From 40febfdf9b1347f674d1b9791f880d74d6c85627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Thu, 17 Jun 2010 00:40:25 +0100 Subject: [PATCH] clib package --- packages/clib/ChangeLog | 486 ++ packages/clib/Makefile | 221 + packages/clib/Makefile.in | 273 + packages/clib/Makefile.mak | 160 + packages/clib/README | 30 + packages/clib/VERSION | 1 + packages/clib/bsd-crypt.c | 1018 +++ packages/clib/cgi.c | 185 + packages/clib/cgi.pl | 37 + packages/clib/clib.doc | 1128 ++++ packages/clib/clib.h | 41 + packages/clib/config.h | 156 + packages/clib/config.h.in | 155 + packages/clib/config.log | 830 +++ packages/clib/configure | 5766 +++++++++++++++++ packages/clib/configure.in | 129 + packages/clib/crypt.c | 165 + packages/clib/crypt.pl | 41 + packages/clib/demo/cgidemo.pl | 29 + packages/clib/demo/fork.pl | 33 + packages/clib/demo/pipe.pl | 60 + packages/clib/demo/win.pl | 117 + packages/clib/depcomp | 522 ++ packages/clib/error.c | 209 + packages/clib/error.h | 42 + packages/clib/files.c | 163 + packages/clib/filesex.pl | 40 + packages/clib/form.c | 395 ++ packages/clib/form.h | 57 + packages/clib/install-sh | 238 + packages/clib/maildrop/COPYING | 3 + packages/clib/maildrop/COPYING.GPL | 340 + packages/clib/maildrop/LICENSE.MAIL | 67 + packages/clib/maildrop/README | 16 + packages/clib/maildrop/rfc2045/Makefile | 38 + packages/clib/maildrop/rfc2045/Makefile.in | 48 + packages/clib/maildrop/rfc2045/Makefile.in~ | 48 + packages/clib/maildrop/rfc2045/Makefile.mak | 35 + packages/clib/maildrop/rfc2045/aclocal.m4 | 1044 +++ packages/clib/maildrop/rfc2045/config.h | 106 + packages/clib/maildrop/rfc2045/config.h.in | 105 + packages/clib/maildrop/rfc2045/config.log | 810 +++ packages/clib/maildrop/rfc2045/configure | 5153 +++++++++++++++ packages/clib/maildrop/rfc2045/configure.in | 82 + packages/clib/maildrop/rfc2045/librfc2045.a | Bin 0 -> 78170 bytes packages/clib/maildrop/rfc2045/makemime.c | 1000 +++ packages/clib/maildrop/rfc2045/makemime.html | 362 ++ packages/clib/maildrop/rfc2045/reformime.c | 962 +++ packages/clib/maildrop/rfc2045/reformime.html | 212 + packages/clib/maildrop/rfc2045/rfc2045.c | 1239 ++++ packages/clib/maildrop/rfc2045/rfc2045.h | 188 + packages/clib/maildrop/rfc2045/rfc2045.html | 323 + .../maildrop/rfc2045/rfc2045_base64encode.c | 76 + .../clib/maildrop/rfc2045/rfc2045_fromfd.c | 46 + packages/clib/maildrop/rfc2045/rfc2045acchk.c | 146 + .../clib/maildrop/rfc2045/rfc2045acprep.c | 107 + .../clib/maildrop/rfc2045/rfc2045appendurl.c | 131 + .../clib/maildrop/rfc2045/rfc2045cdecode.c | 201 + .../clib/maildrop/rfc2045/rfc2045charset.h | 10 + .../clib/maildrop/rfc2045/rfc2045charset.h.in | 10 + .../clib/maildrop/rfc2045/rfc2045decode.c | 41 + .../clib/maildrop/rfc2045/rfc2045enomem.c | 9 + packages/clib/maildrop/rfc2045/rfc2045find.c | 50 + .../clib/maildrop/rfc2045/rfc2045mkboundary.c | 82 + .../clib/maildrop/rfc2045/rfc2045rewrite.c | 471 ++ .../maildrop/rfc2045/rfc2045tryboundary.c | 125 + packages/clib/maildrop/rfc2045/rfc2045xdump.c | 48 + packages/clib/maildrop/rfc2045/stamp-h.in | 0 packages/clib/maildrop/rfc2045/stamp-h1 | 1 + packages/clib/maildrop/rfc822/ChangeLog | 33 + packages/clib/maildrop/rfc822/Makefile | 35 + packages/clib/maildrop/rfc822/Makefile.in | 45 + packages/clib/maildrop/rfc822/Makefile.in~ | 40 + packages/clib/maildrop/rfc822/Makefile.mak | 32 + packages/clib/maildrop/rfc822/aclocal.m4 | 1044 +++ packages/clib/maildrop/rfc822/config.h | 109 + packages/clib/maildrop/rfc822/config.h.in | 108 + packages/clib/maildrop/rfc822/config.log | 643 ++ packages/clib/maildrop/rfc822/configure | 5172 +++++++++++++++ packages/clib/maildrop/rfc822/configure.in | 105 + packages/clib/maildrop/rfc822/imaprefs.c | 921 +++ packages/clib/maildrop/rfc822/imaprefs.h | 97 + packages/clib/maildrop/rfc822/imapsubj.c | 254 + packages/clib/maildrop/rfc822/librfc822.a | Bin 0 -> 57790 bytes packages/clib/maildrop/rfc822/reftest.c | 351 + packages/clib/maildrop/rfc822/reftest.txt | 106 + packages/clib/maildrop/rfc822/rfc2047.c | 541 ++ packages/clib/maildrop/rfc822/rfc2047.h | 83 + packages/clib/maildrop/rfc822/rfc2047u.c | 109 + packages/clib/maildrop/rfc822/rfc822.c | 721 +++ packages/clib/maildrop/rfc822/rfc822.h | 170 + packages/clib/maildrop/rfc822/rfc822.html | 391 ++ .../clib/maildrop/rfc822/rfc822_getaddr.c | 101 + .../clib/maildrop/rfc822/rfc822_getaddrs.c | 94 + packages/clib/maildrop/rfc822/rfc822_mkdate.c | 113 + .../clib/maildrop/rfc822/rfc822_parsedt.c | 243 + packages/clib/maildrop/rfc822/stamp-h.in | 1 + packages/clib/maildrop/rfc822/stamp-h1 | 1 + packages/clib/maildrop/rfc822/testsuite.c | 86 + packages/clib/maildrop/rfc822/testsuite.txt | 91 + packages/clib/md5.c | 381 ++ packages/clib/md5.h | 91 + packages/clib/md5passwd.c | 169 + packages/clib/memfile.c | 515 ++ packages/clib/memfile.c~ | 512 ++ packages/clib/memfile.pl | 45 + packages/clib/mime.c | 391 ++ packages/clib/mime.pl | 67 + packages/clib/missing | 360 + packages/clib/nonblockio.c | 2396 +++++++ packages/clib/nonblockio.h | 196 + packages/clib/pltotex.pl | 60 + packages/clib/process.c | 1627 +++++ packages/clib/process.pl | 333 + packages/clib/prolog_server.pl | 123 + packages/clib/random.c | 155 + packages/clib/random.pl | 163 + packages/clib/readutil.c | 170 + packages/clib/rlimit.c | 128 + packages/clib/rlimit.pl | 51 + packages/clib/sha.pl | 75 + packages/clib/sha1/README | 1 + packages/clib/sha1/brg_endian.h | 142 + packages/clib/sha1/brg_types.h | 188 + packages/clib/sha1/hmac.c | 145 + packages/clib/sha1/hmac.h | 116 + packages/clib/sha1/pwd2key.c | 193 + packages/clib/sha1/pwd2key.h | 57 + packages/clib/sha1/sha1.c | 258 + packages/clib/sha1/sha1.h | 73 + packages/clib/sha1/sha1b.c | 287 + packages/clib/sha1/sha2.c | 773 +++ packages/clib/sha1/sha2.h | 151 + packages/clib/sha1/sha2b.c | 833 +++ packages/clib/sha1/shasum.c | 62 + packages/clib/sha4pl.c | 271 + packages/clib/sha4pl.c~ | 271 + packages/clib/sockcommon.c | 180 + packages/clib/socket.c | 648 ++ packages/clib/socket.pl | 117 + packages/clib/streaminfo.c | 109 + packages/clib/streaminfo.pl | 85 + packages/clib/streampool.pl | 120 + packages/clib/streampool.pl~ | 120 + packages/clib/stresssocket.pl | 419 ++ packages/clib/test.pl | 186 + packages/clib/test_cgi.pl | 79 + packages/clib/test_memfile.pl | 208 + packages/clib/test_process.pl | 113 + packages/clib/test_readutil.pl | 52 + packages/clib/test_socket.pl | 300 + packages/clib/test_socket.pl~ | 297 + packages/clib/test_time.pl | 121 + packages/clib/test_uri.pl | 129 + packages/clib/testrlimit.pl | 8 + packages/clib/time.c | 1007 +++ packages/clib/time.pl | 136 + packages/clib/unix.c | 384 ++ packages/clib/unix.pl | 51 + packages/clib/uri.c | 1599 +++++ packages/clib/uri.pl | 282 + packages/clib/util.h | 75 + packages/clib/winpipe.c | 290 + 163 files changed, 57246 insertions(+) create mode 100644 packages/clib/ChangeLog create mode 100644 packages/clib/Makefile create mode 100644 packages/clib/Makefile.in create mode 100644 packages/clib/Makefile.mak create mode 100644 packages/clib/README create mode 100644 packages/clib/VERSION create mode 100644 packages/clib/bsd-crypt.c create mode 100644 packages/clib/cgi.c create mode 100644 packages/clib/cgi.pl create mode 100644 packages/clib/clib.doc create mode 100644 packages/clib/clib.h create mode 100644 packages/clib/config.h create mode 100644 packages/clib/config.h.in create mode 100644 packages/clib/config.log create mode 100755 packages/clib/configure create mode 100644 packages/clib/configure.in create mode 100644 packages/clib/crypt.c create mode 100644 packages/clib/crypt.pl create mode 100644 packages/clib/demo/cgidemo.pl create mode 100644 packages/clib/demo/fork.pl create mode 100644 packages/clib/demo/pipe.pl create mode 100644 packages/clib/demo/win.pl create mode 100755 packages/clib/depcomp create mode 100644 packages/clib/error.c create mode 100644 packages/clib/error.h create mode 100644 packages/clib/files.c create mode 100644 packages/clib/filesex.pl create mode 100644 packages/clib/form.c create mode 100644 packages/clib/form.h create mode 100755 packages/clib/install-sh create mode 100644 packages/clib/maildrop/COPYING create mode 100644 packages/clib/maildrop/COPYING.GPL create mode 100644 packages/clib/maildrop/LICENSE.MAIL create mode 100644 packages/clib/maildrop/README create mode 100644 packages/clib/maildrop/rfc2045/Makefile create mode 100644 packages/clib/maildrop/rfc2045/Makefile.in create mode 100644 packages/clib/maildrop/rfc2045/Makefile.in~ create mode 100644 packages/clib/maildrop/rfc2045/Makefile.mak create mode 100644 packages/clib/maildrop/rfc2045/aclocal.m4 create mode 100644 packages/clib/maildrop/rfc2045/config.h create mode 100644 packages/clib/maildrop/rfc2045/config.h.in create mode 100644 packages/clib/maildrop/rfc2045/config.log create mode 100755 packages/clib/maildrop/rfc2045/configure create mode 100644 packages/clib/maildrop/rfc2045/configure.in create mode 100644 packages/clib/maildrop/rfc2045/librfc2045.a create mode 100644 packages/clib/maildrop/rfc2045/makemime.c create mode 100644 packages/clib/maildrop/rfc2045/makemime.html create mode 100644 packages/clib/maildrop/rfc2045/reformime.c create mode 100644 packages/clib/maildrop/rfc2045/reformime.html create mode 100644 packages/clib/maildrop/rfc2045/rfc2045.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045.h create mode 100644 packages/clib/maildrop/rfc2045/rfc2045.html create mode 100644 packages/clib/maildrop/rfc2045/rfc2045_base64encode.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045_fromfd.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045acchk.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045acprep.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045appendurl.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045cdecode.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045charset.h create mode 100644 packages/clib/maildrop/rfc2045/rfc2045charset.h.in create mode 100644 packages/clib/maildrop/rfc2045/rfc2045decode.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045enomem.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045find.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045mkboundary.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045rewrite.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045tryboundary.c create mode 100644 packages/clib/maildrop/rfc2045/rfc2045xdump.c create mode 100644 packages/clib/maildrop/rfc2045/stamp-h.in create mode 100644 packages/clib/maildrop/rfc2045/stamp-h1 create mode 100644 packages/clib/maildrop/rfc822/ChangeLog create mode 100644 packages/clib/maildrop/rfc822/Makefile create mode 100644 packages/clib/maildrop/rfc822/Makefile.in create mode 100644 packages/clib/maildrop/rfc822/Makefile.in~ create mode 100644 packages/clib/maildrop/rfc822/Makefile.mak create mode 100644 packages/clib/maildrop/rfc822/aclocal.m4 create mode 100644 packages/clib/maildrop/rfc822/config.h create mode 100644 packages/clib/maildrop/rfc822/config.h.in create mode 100644 packages/clib/maildrop/rfc822/config.log create mode 100755 packages/clib/maildrop/rfc822/configure create mode 100644 packages/clib/maildrop/rfc822/configure.in create mode 100644 packages/clib/maildrop/rfc822/imaprefs.c create mode 100644 packages/clib/maildrop/rfc822/imaprefs.h create mode 100644 packages/clib/maildrop/rfc822/imapsubj.c create mode 100644 packages/clib/maildrop/rfc822/librfc822.a create mode 100644 packages/clib/maildrop/rfc822/reftest.c create mode 100644 packages/clib/maildrop/rfc822/reftest.txt create mode 100644 packages/clib/maildrop/rfc822/rfc2047.c create mode 100644 packages/clib/maildrop/rfc822/rfc2047.h create mode 100644 packages/clib/maildrop/rfc822/rfc2047u.c create mode 100644 packages/clib/maildrop/rfc822/rfc822.c create mode 100644 packages/clib/maildrop/rfc822/rfc822.h create mode 100644 packages/clib/maildrop/rfc822/rfc822.html create mode 100644 packages/clib/maildrop/rfc822/rfc822_getaddr.c create mode 100644 packages/clib/maildrop/rfc822/rfc822_getaddrs.c create mode 100644 packages/clib/maildrop/rfc822/rfc822_mkdate.c create mode 100644 packages/clib/maildrop/rfc822/rfc822_parsedt.c create mode 100644 packages/clib/maildrop/rfc822/stamp-h.in create mode 100644 packages/clib/maildrop/rfc822/stamp-h1 create mode 100644 packages/clib/maildrop/rfc822/testsuite.c create mode 100644 packages/clib/maildrop/rfc822/testsuite.txt create mode 100644 packages/clib/md5.c create mode 100644 packages/clib/md5.h create mode 100644 packages/clib/md5passwd.c create mode 100644 packages/clib/memfile.c create mode 100644 packages/clib/memfile.c~ create mode 100644 packages/clib/memfile.pl create mode 100644 packages/clib/mime.c create mode 100644 packages/clib/mime.pl create mode 100755 packages/clib/missing create mode 100644 packages/clib/nonblockio.c create mode 100644 packages/clib/nonblockio.h create mode 100644 packages/clib/pltotex.pl create mode 100644 packages/clib/process.c create mode 100644 packages/clib/process.pl create mode 100644 packages/clib/prolog_server.pl create mode 100644 packages/clib/random.c create mode 100644 packages/clib/random.pl create mode 100644 packages/clib/readutil.c create mode 100644 packages/clib/rlimit.c create mode 100644 packages/clib/rlimit.pl create mode 100644 packages/clib/sha.pl create mode 100644 packages/clib/sha1/README create mode 100644 packages/clib/sha1/brg_endian.h create mode 100644 packages/clib/sha1/brg_types.h create mode 100644 packages/clib/sha1/hmac.c create mode 100644 packages/clib/sha1/hmac.h create mode 100644 packages/clib/sha1/pwd2key.c create mode 100644 packages/clib/sha1/pwd2key.h create mode 100644 packages/clib/sha1/sha1.c create mode 100644 packages/clib/sha1/sha1.h create mode 100644 packages/clib/sha1/sha1b.c create mode 100644 packages/clib/sha1/sha2.c create mode 100644 packages/clib/sha1/sha2.h create mode 100644 packages/clib/sha1/sha2b.c create mode 100644 packages/clib/sha1/shasum.c create mode 100644 packages/clib/sha4pl.c create mode 100644 packages/clib/sha4pl.c~ create mode 100644 packages/clib/sockcommon.c create mode 100644 packages/clib/socket.c create mode 100644 packages/clib/socket.pl create mode 100644 packages/clib/streaminfo.c create mode 100644 packages/clib/streaminfo.pl create mode 100644 packages/clib/streampool.pl create mode 100644 packages/clib/streampool.pl~ create mode 100644 packages/clib/stresssocket.pl create mode 100644 packages/clib/test.pl create mode 100644 packages/clib/test_cgi.pl create mode 100644 packages/clib/test_memfile.pl create mode 100644 packages/clib/test_process.pl create mode 100644 packages/clib/test_readutil.pl create mode 100644 packages/clib/test_socket.pl create mode 100644 packages/clib/test_socket.pl~ create mode 100644 packages/clib/test_time.pl create mode 100644 packages/clib/test_uri.pl create mode 100644 packages/clib/testrlimit.pl create mode 100644 packages/clib/time.c create mode 100644 packages/clib/time.pl create mode 100644 packages/clib/unix.c create mode 100644 packages/clib/unix.pl create mode 100644 packages/clib/uri.c create mode 100644 packages/clib/uri.pl create mode 100644 packages/clib/util.h create mode 100644 packages/clib/winpipe.c diff --git a/packages/clib/ChangeLog b/packages/clib/ChangeLog new file mode 100644 index 000000000..dc3e8d8ff --- /dev/null +++ b/packages/clib/ChangeLog @@ -0,0 +1,486 @@ +[Sep 9 2009] + + * ADDED: uri_file_name/2 + + * ADDED: library(uri), providing a much faster and modern API to handling + URIs and IRIs. + +[Aug 18 2009] + + * CLEANUP: Bug#413: Complete 'make distclean'. Feliks Kluzniak +[Aug 7 2009] + + * MODIFIED: WinSock interface now signals WSAECONNABORTED as EOF when reading. This is somewhat debatable, but compatible with the Unix version of the socket interface. Matt Lilley. + +[Aug 3 2009] + + * PORT: Avoid name-clash on SOCK_* constants. +[Jul 27 2009] + + * FIXED: Another timer issue that could crash the alarm-scheduler. + + * FIXED: The library(time) now uses SIGUSR2 rather then SIGALRM if available to avoid interference from libreadline's signal handling of SIGALRM. + + * FIXED: Crash in alarm-timers (Multi-threaded unix version) + +[Jul 21 2009] + + * MODIFIED: Make initialization/1 ISO compliant + This patch is a modest cleanup to the implementation of '$load_file'/3 + from init.pl and provides an ISO compatible implementation of + initialization/1. This executes the argument goal *after* loading the + file rather than when encountering the directive. Often this makes no + difference, but notably load_foreign_library/1 is an exception. + Therefore we added use_foreign_library/1,2 that act as a directive and + provides proper integration with saved-states automatically. Loading + code using initialization(load_foreign_library(...)) will load the + library immediately and issue a warning. + + See initialization/1,2 for details and further hints for dealing with + possible compatibility problems. + +[Jul 8 2009] + + * ADDED: alarm_at/4. Addition provided by Samar Abdallah. + +[Jul 6 2009] + + * FIXED: library(time) (Unix version): properly handle multiple alarms at the same time. Reported by Samer Abdallah. +[Jun 15 2009] + + * BUILD: Skip RFC2202 tests if Prolog is not compiled with unbounded arithmetic. Keri Harris. + +[Jun 2 2009] + + * ADDED: uninstall_alarm/1 + +[Mar 30 2009] + + * FIXED: alarm handling on Win64 (Kerri Haris) + +[Mar 19 2009] + + * CLEANUP: Removed all trailing whitespace from all source-files. This avoids many GIT (merge) warnings. +[Mar 12 2009] + + * MODIFIED: Renamed concat_atom/2,3 into atomic_list_concat/2,3 for compatibility. Moved the old predicates into library(backcomp). It is adviced to update your code, but 99% of the code will remain working because the old definitions are autoloaded. + +[Feb 4 2009] + + * FIXED: Uninitialised variable in environment parsing of process.c. Keri Harris. + +[Jan 29 2009] + + * CLEANUP: generalisations in the socket library design to allow TIPC to + reuse parts of it. Contributed by Jeff Rosenwald. + + * PORT: Port new environment initialisation of process_create/3 to Windows. + The new environment processing code is free of limits (of course, except + limits of the operating system). + +[Jan 28 2009] + + * ADDED: env option to process_create/3 to specify the environment for + the child process. + +[Jan 26 2009] + + * FIXED: make install_alarm/1 produce an error when installing twice. + + * MODIFIED: Renamed setup_and_call_cleanup/3,4 to setup_call_cleanup/3 and setup_call_catcher_cleanup/4; added to library(backcomp). + + * ADDED: library(streaminfo) for debugging (network) stream issues +[Jan 23 2009] + + * CHECK: Fixed makefile for modified test entry-point + +[Jan 22 2009] + + * ADDED: free_on_close option to open_memory_file/4 + + * CLEANUP: library(time) to use meta_predicate declaration and make debugging a + bit simpler. +[Oct 9 2008] + + * ADDED: library(unix): support symbolic signal names. + + * FIXED: Many errors in exceptions raised after failing system calls + by the libraries from the clib package. + +[Oct 2 2008] + + * ENHANCED: Cache value of gethostname/1. +[Sep 11 2008] + + * PORT: Add AC_PREREQ to configure.h for systems that auto-select autoconf + versions. After tip by Ulrich Neumerkel. + +[Sep 9 2008] + + * ADDED: TCP sockets: support TCP_NODELAY using tcp_setopt(Socket, nodelay(true)). + After patch submitted by Matt Lilley. + +[Aug 14 2008] + + * FIXED: Possible crash if closing a socket in Windows fails. Matt Lilley. + +[Aug 13 2008] + + * FIXED: Windows: closing the read-handle of a socket reported an error. Matt Lilley. + +[Aug 11 2008] + + * INSTALL: Remove all configure files from the git repository +[Jul 4 2008] + + * FIXED: library(process) stream administration (could lead to errors in close) + +[Jul 3 2008] + + * FIXED: Avoid possible deadlock in PL_cleanup_fork(). Michiel William Kauw-A-Tjoe + +[Jun 25 2008] + + * ADDED: memory_file_to_atom/3 and memory_file_to_codes/3 to convert encodings. + +[Jun 27 2008] + + * FIXED: read_line_to_codes/3: foreign implementation did not unlock stream. +[Jun 13 2008] + + * FIXED: Include initialization to load process.so. Matt Lilley. + +[May 21 2008] + + * FIXED: Error message when using a service name in tcp_bind/connect. + Jean-Marc Vanel. + +[May 20 2008] + + * PORT: Port UDP socket support to Windows + + * MODIFIED: Streams in socket.pl and ssl.pl appeared unbuffered. They + are now fully buffered. + +[May 19 2008] + + * ADDED: support for 'as(Type) option to udp_receive/4 + +[May 16 2008] + + * FIXED: Process streams are by default in text-mode using full buffering. + +[May 12 2008] + + * PORT: Ported library(process) to Windows + +[May 11 2008] + + * ADDED: library(process), providing SICStus 4 compatible process interaction + to the clib packages. Currently runs on Unix systems only (tested Linux and + MacOS X 10.4). + + This patch also extends the foreign interface with the PL_get_signum_ex() + and PL_cleanup_fork(). + +[Mar 10 2008] + + * FIXED: Pass error while waiting for accept() in Windows + +[Feb 26 2008] + + * PORT: Fix compilation of SHA1 routines for SUN/SPARC. Robert Andersson. + +[Feb 15 2008] + + * FIXED: cgi_get_form/1 now assumes input data is in UTF-8. + +[Jan 23 2008] + + * PORT: Bug#346: Allow overriding COFLAGS and CWFLAGS in package + configuration. Keri Harris. +[Jan 15 2008] + + * PORT: Fix cpp handling in clib package configure. This is assumed to + fix the Darwinports on MacOS Leopard. Nico, Ryoko et Anna. +Oct 6, 2007 + + * FIXED: call_with_time_limit non-determinism. Norbert Fuchs. + +Sep 25, 2007 + + * Make SHA routines compile on Solaris + +Sep 3, 2007 + + * Possible not working timer alarm. Ulrich Neumerkel. + +Jul 30, 2007 + + * FIXED: Bug#302: memory leak in atom_to_memory_file/2 with filled + output argument. Keri Harris. + +Jul 12, 2007 + + * FIXED: call_with_time_limit/2 if the alarm fires before call_cleanup + is entered, a theoretical problem using short timeouts on a loaded + machine. + + * ADDED: install_alarm/1. + + * FIXED: Avoid exit of Prolog on uncaught exception from + call_with_time_limit/2. Ulrich Neumerkel. + +May 3, 2007 + + * ADDED: open_memory_file/4, providing encoding facilities. Matt Lilley. + +Apr 23, 2007 + + * FIXED: tcp_accept to deal with stream handles (broken in nbio redesign). + +Mar 7, 2007 + + * FIXED: Put debug message "shutdown(6=-1, SD_RECEIVE) failed" under + tcp_debug/1. Mike Elston + +Mar 6, 2007 + + * FIXED: Waiting for a socket with XPCE enabled. + * ADDED: SHA-1 and SHA-2 support in new library(sha). + +Feb 28, 2007 + + * Re-renerated HTML docs (outdated) + +Feb 26, 2007 + + * FIXED: complete redesign of nonblock.c socket layer to deal with + validness of socket handles. + +Feb 9, 2007 + + * ADDED: MD5 hashes to crypt. Added library(crypt) to Windows version + (only supporting MD5). + +Feb 2, 2007 + + * Fixed alloca issues in socket.c. Richard O'Keefe. + +Jan 31, 2007 + + * Documentation update to document issues in the Windows timer + implementation. + +Jan 23, 2007 + + * size_t cleanup. + +Dec 12, 2006 + + * FIXED: Error handling in read_line_to_codes/[2,3] and + read_stream_to_codes/[2,3]. + +Nov 8, 2006 + + * CLEANUP: GCC warnings + +Oct 27, 2006 + + * FIXED: random/3 never to generate upper bound. Nicos. + +Oct 16, 2006 + + * ADDED: YAP/SICStus compatible library(random). + +Sep 7, 2006 + + * FIXED: Bug#205 make --> $(MAKE). Marc Espie + +Feb 1, 2006 + + * FIXED: Remove DOS ^M from files in maildrop package. Richard O'Keefe. + +Jan 19, 2006 + + * Fixed: Bug#137: make time.c compile for single-threaded operation + Keri Harris. + +Jan 12, 2006 + + * Fixed: rewrote most of time.c, providing alarm/4 using portable + pthread code. + +Jan 10, 2006 + + * UDP ssize_t portability issues + +Dec 23, 2005 + + * Start work on UDP support in socket.pl. + +Oct 14, 2005 + + * Fixed signedness error in library memfile, returning incorrect values + for size_memory_file/2 + +Oct 11, 2005 + + * PORT: Use plld to compile maildrop as position independent code + +May 22, 2005 + + * PORT: Added maildrop RFC libraries to distribution + +Apr 23, 2005 + + * FIXED: mime_parse/3: read stream with Sgetcode rather than Sgetc to + deal with encoding issues. + +Feb 17, 2005 + + * ADDED: Provide wide-character support for library(memfile). + +Dec 16, 2004 + + * FIXED: Socket and ssl interaction problems (Windows). Matt Lilley. + +October 04, 2004 + + * FIXED: library(socket) and library(ssl): potential crash and starvation + issue. Appears to happen only on Windows NT, but the problem can -at + least in theory- also appear in other Windows versions. With thanks + to Mike Elston for providing the test program. + +Sep 21, 2004 + + * FIXED: cgi_get_form/1 for www-form-encoded strings with lowercase + %xx. John Paolillo. + +Jul 18, 2004 + + * CLEANUP: ensure mimimal library dependency. After discussion on + mailinglist. + +Jul 5, 2004 + + * CLEANUP: split socket library in two to be able to reuse the + non-blocking socket stuff in the SSL library. + +May 5, 2004 + + * FIXED: memory leak in open_memory_file/3. Fabien Todescato. + +Oct 2, 2003 + + * PORT: Configure socket library for IRIX 6.5 (Rob Myers). + +Aug 28, 2003 + + * FIXED: Complete rewrite of library(socket) for MS-Windows. + +Jun 2, 2003 + + * FIXED: time:remove_alarm/1 for MS-WIndows. Mike Elston. + +Mar 14, 2003 + + * ADDED: Code to make sockets cooperate with signals, so + call_with_time_limit/2 works on blocking socket operations. + + * FIXED: Error handling on sockets (Windows) + + * FIXED: call_with_time_limit/2 module problem + +Feb 2, 2003 + + * FIXED: call_with_time_limit/2 if the argument goal fails. Wouter + Jansweijer. + +Dec 18, 2002 + + * FIXED: make all socket calls resume on EINTR (Unix systems). + +Dec 7, 2002 + + * FIXED: hand open sockets to other threads (blocking problems in Windows). + +Dec 6, 2002 + + * FIXED: blocking write in sockets and make tcp_close_socket close the + associated streams (if any). + +Dec 4, 2002 + + * FIXED: tcp_close_socket/1 to work on the listened socket. Peter Marks. + +Dec 2, 2002 + + * ADDED: tcp_bind(+Socket, -Port) to bind with an arbitrary free port. + +Nov 29, 2002 + + * FIXED: MS-Windows tcp_read() not to wait for messages after we have + seen FD_CLOSE. Holger Kanwischer. + + * ADDED: Make library(socket) suitable for multi-threaded operation in + MS-Windows. Mike Elston. + +Nov 26, 2002 + + * ADDED: Make library(time) suitable for multi-threaded operation. + + * ADDED: library(rlimit) for accessing POSIX process limits + +Jul 24, 2002 + + * ADDED: tcp_setopt(Socket, dispatch(false)) + +Jun 20, 2002 + + * FIXED: Handle WSAEWOULDBLOCK in tcp_acept() to get a blocking accept + call. + +Jun 11, 2002 + + * ADDED: library(files), providing uncommon access to file objects. + +29/04/2002 + + * Add initialization to load_foreign_library for calls lacking this. + Holger Kanwischer. + +28/03/2002 + + * Record position on socket-streams (SIO_RECORDPOS). + + * Many changes to library(socket): fixes for the Windows implementation, + dispatch events during tcp_read() while waiting for input. + +01/02/2002 + + * Modified copyright for compatibility with the now LGPL SWI-Prolog system + +07/12/2001 + + * FIXED: memory_file_to_atom/2 and friends to return size 0, empty atom + when the file contains no data. + +10/06/2001 + + * ADDED: library(mime) for MIME message parsing. + +07/10/2000 + + * ADDED: Allow for descriptor to arguments of dup/2. + +30/06/1999 + + * ADDED: cgi.pl, cgi.c and form.[ch] providing cgi_get_form/1 to get the + Form-data if SWI-Prolog is installed as a CGI script. + +06/04/1999 + + * Renamed the predicates from the socket package to tcp_. + These predicates are meant as low-level primitives and their normal name + is too general. diff --git a/packages/clib/Makefile b/packages/clib/Makefile new file mode 100644 index 000000000..0930508e4 --- /dev/null +++ b/packages/clib/Makefile @@ -0,0 +1,221 @@ +################################################################ +# Makefile template for SWI-Prolog CLIB package +# +# This template is used by configure to create Makefile. See +# the file INSTALL for further installation instructions. +# +# License: LGPL +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +.SUFFIXES: .tex .dvi .doc .pl + +PL=../swipl.sh +PLBASE=/home/vsc/Yap/Prologs/pl-devel/lib/swipl-5.9.11 +PLARCH=x86_64-linux +PLINCL=/home/vsc/Yap/Prologs/pl-devel/include +PKGDOC=$(PLBASE)/doc/packages +PCEHOME=../xpce + +CC=../swipl-ld.sh +COFLAGS=-O2 -fno-strict-aliasing +CWFLAGS=-Wall +CMFLAGS=-fPIC +CIFLAGS=-I. -Imaildrop/rfc2045 -Imaildrop/rfc822 +CFLAGS=$(COFLAGS) $(CWFLAGS) $(CMFLAGS) $(CIFLAGS) -DHAVE_CONFIG_H +LIBS= +NETLIBS= +CRYPTLIBS=-lcrypt +MIMELIBS=maildrop/rfc2045/librfc2045.a maildrop/rfc822/librfc822.a + +PUBLICPL=swipl +DOCTOTEX=$(PCEHOME)/bin/doc2tex +PLTOTEX=$(PUBLICPL) -q -s pltotex.pl -g pltotex -- +DOC=clib +TEX=$(DOC).tex process.tex uri.tex +DVI=$(DOC).dvi +PDF=$(DOC).pdf +RUNTEX=../../man/runtex + +LD=../swipl-ld.sh +LDFLAGS=-shared + +INSTALL=/usr/bin/install -c +INSTALL_PROGRAM=${INSTALL} +INSTALL_DATA=/usr/bin/install -c -m 644 + +LIBPL= random.pl unix.pl socket.pl cgi.pl memfile.pl filesex.pl mime.pl crypt.pl time.pl rlimit.pl streampool.pl streaminfo.pl process.pl prolog_server.pl sha.pl \ + uri.pl +TARGETS= random.so unix.so socket.so cgi.so memfile.so files.so mime.so crypt.so time.so rlimit.so readutil.so streaminfo.so process.so \ + sha4pl.so uri.so + +UNXOBJ= error.o unix.o +SOCKOBJ= error.o socket.o nonblockio.o +CGIOBJ= error.o form.o cgi.o +CRYPTOBJ= error.o crypt.o md5.o md5passwd.o +MEMOBJ= error.o memfile.o +MIMEOBJ= error.o mime.o +TIMEOBJ= error.o time.o +FILESOBJ= error.o files.o +RLIMITOBJ= error.o rlimit.o +URIOBJ= uri.o +RANDOMOBJ= random.o +READUTILOBJ= readutil.o +PROCESSOBJ= error.o process.o +STREAMINFOOBJ= error.o streaminfo.o +SHAOBJ= error.o sha4pl.o sha1/sha1.o sha1/sha2.o \ + sha1/hmac_sha1.o sha1/hmac_sha256.o + +all: $(TARGETS) + +random.so: $(RANDOMOBJ) + $(LD) $(LDFLAGS) -o $@ $(RANDOMOBJ) +unix.so: $(UNXOBJ) + $(LD) $(LDFLAGS) -o $@ $(UNXOBJ) +socket.so: $(SOCKOBJ) + $(LD) $(LDFLAGS) -o $@ $(SOCKOBJ) $(NETLIBS) +cgi.so: $(CGIOBJ) + $(LD) $(LDFLAGS) -o $@ $(CGIOBJ) +crypt.so: $(CRYPTOBJ) + $(LD) $(LDFLAGS) -o $@ $(CRYPTOBJ) $(CRYPTLIBS) +memfile.so: $(MEMOBJ) + $(LD) $(LDFLAGS) -o $@ $(MEMOBJ) $(LIBS) +mime.so: $(MIMEOBJ) $(MIMELIBS) + $(LD) $(LDFLAGS) -o $@ $(MIMEOBJ) $(MIMELIBS) +time.so: $(TIMEOBJ) + $(LD) $(LDFLAGS) -o $@ $(TIMEOBJ) $(LIBS) +files.so: $(FILESOBJ) + $(LD) $(LDFLAGS) -o $@ $(FILESOBJ) $(LIBS) +rlimit.so: $(RLIMITOBJ) + $(LD) $(LDFLAGS) -o $@ $(RLIMITOBJ) $(LIBS) +readutil.so: $(READUTILOBJ) + $(LD) $(LDFLAGS) -o $@ $(READUTILOBJ) +process.so: $(PROCESSOBJ) + $(LD) $(LDFLAGS) -o $@ $(PROCESSOBJ) +streaminfo.so: $(STREAMINFOOBJ) + $(LD) $(LDFLAGS) -o $@ $(STREAMINFOOBJ) +sha4pl.so: $(SHAOBJ) + $(LD) $(LDFLAGS) -o $@ $(SHAOBJ) +uri.so: $(URIOBJ) + $(LD) $(LDFLAGS) -o $@ $(URIOBJ) + +socket.o: socket.c sockcommon.c + +sha1/hmac_sha1.o: + $(CC) -c $(CFLAGS) -DUSE_SHA1 -o $@ sha1/hmac.c +sha1/hmac_sha256.o: + $(CC) -c $(CFLAGS) -DUSE_SHA256 -o $@ sha1/hmac.c + +maildrop/rfc822/librfc822.a: + (cd maildrop/rfc822 && $(MAKE)) +maildrop/rfc2045/librfc2045.a: + (cd maildrop/rfc2045 && $(MAKE)) + + +install: $(TARGETS) $(LIBPL) + mkdir -p $(DESTDIR)$(PLBASE)/lib/$(PLARCH) + for f in $(TARGETS); do \ + $(INSTALL_PROGRAM) $$f $(DESTDIR)$(PLBASE)/lib/$(PLARCH); \ + done + mkdir -p $(DESTDIR)$(PLBASE)/library + for f in $(LIBPL); do \ + $(INSTALL_DATA) $$f $(DESTDIR)$(PLBASE)/library; \ + done + $(PL) -f none -g make -t halt + +ln-install:: + @$(MAKE) INSTALL_DATA='../ln-install' INSTALL_PROGRAM='../ln-install' install + +rpm-install: install + +html-install:: + mkdir -p $(DESTDIR)$(PKGDOC) + $(INSTALL) -m 644 clib.html $(DESTDIR)$(PKGDOC) + +pdf-install:: + mkdir -p $(DESTDIR)$(PKGDOC) + $(INSTALL) -m 644 clib.pdf $(DESTDIR)$(PKGDOC) + +uninstall:: + (cd $(PLBASE)/lib/$(PLARCH) && rm -f $(TARGETS)) + (cd $(PLBASE)/library && rm -f $(LIBPL)) + $(PL) -f none -g make -t halt + +################################################################ +# Testing +################################################################ + +check: check-socket check-memfile check-unit check-process \ + check-read check-uri check-cgi + +torture: torture-socket + +check-socket:: + $(PL) -q -f test_socket.pl -F none -g test_socket,halt -t 'halt(1)' + +torture-socket:: + $(PL) -q -f stresssocket.pl -F none -g test,halt -t 'halt(1)' + +check-memfile:: + $(PL) -q -f test_memfile.pl -F none -g test_memfile,halt -t 'halt(1)' + +check-unit:: + $(PL) -q -f test.pl -g run_tests,halt -t 'halt(1)' + +check-uri:: + $(PL) -q -f test_uri.pl -g true -t test_uri + +check-cgi:: + $(PL) -q -f test_cgi.pl -g true -t test_cgi + +check-process:: + $(PL) -q -f test_process.pl -g true -t test_process + +check-read:: + $(PL) -q -f test_readutil.pl -g true -t test_readutil + +################################################################ +# Documentation +################################################################ + +pdf: $(PDF) + +$(DVI): $(TEX) + $(RUNTEX) $(DOC) + +$(PDF): $(TEX) + $(RUNTEX) --pdf $(DOC) + +html: $(TEX) + latex2html $(DOC) + mv html/index.html clib.html + rm -r html + +$(TEX): $(DOCTOTEX) + +uri.tex: uri.pl + $(PLTOTEX) 'library(uri)' +process.tex: process.pl + $(PLTOTEX) 'library(process)' + +.doc.tex: + $(DOCTOTEX) $*.doc > $*.tex + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log sha1/*.o + rm -f $(TEX) + -(cd maildrop/rfc822 && $(MAKE) clean) + -(cd maildrop/rfc2045 && $(MAKE) clean) + +distclean: clean + rm -f $(TARGETS) config.cache config.h config.status Makefile + rm -f clib.aux clib.log clib.out clib.toc + rm -rf html + -(cd maildrop/rfc822 && $(MAKE) distclean) + -(cd maildrop/rfc2045 && $(MAKE) distclean) diff --git a/packages/clib/Makefile.in b/packages/clib/Makefile.in new file mode 100644 index 000000000..c729e1a94 --- /dev/null +++ b/packages/clib/Makefile.in @@ -0,0 +1,273 @@ +################################################################ +# Makefile template for SWI-Prolog CLIB package +# +# This template is used by configure to create Makefile. See +# the file INSTALL for further installation instructions. +# +# License: LGPL +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +.SUFFIXES: .tex .dvi .doc .pl + +ifeq (@PROLOG_SYSTEM@,yap) +prefix = @prefix@ +exec_prefix = @exec_prefix@ +ROOTDIR = $(prefix) +EROOTDIR = @exec_prefix@ +abs_top_builddir = @abs_top_builddir@ + +srcdir=@srcdir@ + +BINDIR = $(EROOTDIR)/bin +LIBDIR=@libdir@ +YAPLIBDIR=@libdir@/Yap +SHAREDIR=$(ROOTDIR)/share/Yap + +SHELL=@SHELL@ +PL=@INSTALL_ENV@ $(DESTDIR)$(BINDIR)/yap $(DESTDIR)$(YAPLIBDIR)/startup.yss +LN_S=@LN_S@ +# +# +CC=@CC@ +CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) -D_YAP_NOT_INSTALLED_=1 -DHAVE_CONFIG_H=1 -I$(srcdir) -I../.. -I$(srcdir)/../../include -I. -I$(srcdir)/maildrop/rfc2045 -I$(srcdir)/maildrop/rfc822 @SHLIB_CFLAGS@ +MKINDEX=true + +LD=@DO_SECOND_LD@ @SHLIB_CXX_LD@ +LDFLAGS=@EXTRA_LIBS_FOR_SWIDLLS@ + +BINTARGET=$(DESTDIR)$(YAPLIBDIR) +PLTARGET=$(DESTDIR)$(SHAREDIR) + +FINAL_BINTARGET=$(YAPLIBDIR) +FINAL_PLTARGET=$(SHAREDIR) + +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) $< -o $@ + +sha1/%.o: $(srcdir)/sha1/%.c + $(CC) -c $(CFLAGS) $< -o $@ + +else # SWI + +PL=@PL@ +PLBASE=@PLBASE@ +PLARCH=@PLARCH@ +PLINCL=@PLINCL@ +PKGDOC=$(PLBASE)/doc/packages +PCEHOME=../xpce + +CC=@CC@ +COFLAGS=@COFLAGS@ +CWFLAGS=@CWFLAGS@ +CMFLAGS=@CMFLAGS@ +CIFLAGS=-I. -Imaildrop/rfc2045 -Imaildrop/rfc822 +CFLAGS=$(COFLAGS) $(CWFLAGS) $(CMFLAGS) $(CIFLAGS) @DEFS@ +LIBS=@LIBS@ +NETLIBS=@NETLIBS@ +CRYPTLIBS=@CRYPTLIBS@ + +PUBLICPL=swipl +DOCTOTEX=$(PCEHOME)/bin/doc2tex +PLTOTEX=$(PUBLICPL) -q -s pltotex.pl -g pltotex -- +DOC=clib +TEX=$(DOC).tex process.tex uri.tex +DVI=$(DOC).dvi +PDF=$(DOC).pdf +RUNTEX=../../man/runtex + +LD=@LD@ +LDFLAGS=@LDSOFLAGS@ + +BINTARGET=$(DESTDIR)$(PLBASE)/lib/$(PLARCH) +PLTARGET=$(DESTDIR)$(PLBASE)/library + +FINAL_BINTARGET=$(PLBASE)/lib/$(PLARCH) +FINAL_PLTARGET=$(PLBASE)/library + +endif #YAP/SWI + +MIMELIBS=maildrop/rfc2045/librfc2045.a maildrop/rfc822/librfc822.a + +INSTALL=@INSTALL@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +INSTALL_DATA=@INSTALL_DATA@ + +LIBPL= @PLTARGETS@ $(srcdir)/streaminfo.pl $(srcdir)/process.pl \ + $(srcdir)/prolog_server.pl $(srcdir)/sha.pl \ + $(srcdir)/socket.pl \ + $(srcdir)/uri.pl +TARGETS= @TARGETS@ readutil.@SO@ streaminfo.@SO@ process.@SO@ \ + sha4pl.@SO@ uri.@SO@ memfile.@SO@ mime.@SO@ time.@SO@ \ + files.@SO@ rlimit.@SO@ random.@SO@ cgi.@SO@ socket.@SO@ + +UNXOBJ= error.o unix.o +SOCKOBJ= error.o socket.o nonblockio.o +CGIOBJ= error.o form.o cgi.o +CRYPTOBJ= error.o crypt.o md5.o md5passwd.o +MEMOBJ= error.o memfile.o +MIMEOBJ= error.o mime.o +TIMEOBJ= error.o time.o +FILESOBJ= error.o files.o +RLIMITOBJ= error.o rlimit.o +URIOBJ= uri.o +RANDOMOBJ= random.o +READUTILOBJ= readutil.o +PROCESSOBJ= error.o process.o +STREAMINFOOBJ= error.o streaminfo.o +SHAOBJ= error.o sha4pl.o sha1/sha1.o sha1/sha2.o \ + sha1/hmac_sha1.o sha1/hmac_sha256.o + +all: $(TARGETS) + +random.@SO@: $(RANDOMOBJ) + $(LD) $(LDFLAGS) -o $@ $(RANDOMOBJ) +unix.@SO@: $(UNXOBJ) + $(LD) $(LDFLAGS) -o $@ $(UNXOBJ) +socket.@SO@: $(SOCKOBJ) + $(LD) $(LDFLAGS) -o $@ $(SOCKOBJ) $(NETLIBS) +cgi.@SO@: $(CGIOBJ) + $(LD) $(LDFLAGS) -o $@ $(CGIOBJ) +crypt.@SO@: $(CRYPTOBJ) + $(LD) $(LDFLAGS) -o $@ $(CRYPTOBJ) $(CRYPTLIBS) +memfile.@SO@: $(MEMOBJ) + $(LD) $(LDFLAGS) -o $@ $(MEMOBJ) $(LIBS) +mime.@SO@: $(MIMEOBJ) $(MIMELIBS) + $(LD) $(LDFLAGS) -o $@ $(MIMEOBJ) $(MIMELIBS) +time.@SO@: $(TIMEOBJ) + $(LD) $(LDFLAGS) -o $@ $(TIMEOBJ) $(LIBS) +files.@SO@: $(FILESOBJ) + $(LD) $(LDFLAGS) -o $@ $(FILESOBJ) $(LIBS) +rlimit.@SO@: $(RLIMITOBJ) + $(LD) $(LDFLAGS) -o $@ $(RLIMITOBJ) $(LIBS) +readutil.@SO@: $(READUTILOBJ) + $(LD) $(LDFLAGS) -o $@ $(READUTILOBJ) +process.@SO@: $(PROCESSOBJ) + $(LD) $(LDFLAGS) -o $@ $(PROCESSOBJ) +streaminfo.@SO@: $(STREAMINFOOBJ) + $(LD) $(LDFLAGS) -o $@ $(STREAMINFOOBJ) +sha4pl.@SO@: $(SHAOBJ) + $(LD) $(LDFLAGS) -o $@ $(SHAOBJ) +uri.@SO@: $(URIOBJ) + $(LD) $(LDFLAGS) -o $@ $(URIOBJ) + +socket.o: $(srcdir)/socket.c $(srcdir)/sockcommon.c + +sha1/hmac_sha1.o: + $(CC) -c $(CFLAGS) -DUSE_SHA1 -o $@ $(srcdir)/sha1/hmac.c +sha1/hmac_sha256.o: + $(CC) -c $(CFLAGS) -DUSE_SHA256 -o $@ $(srcdir)/sha1/hmac.c + +maildrop/rfc822/librfc822.a: + (cd maildrop/rfc822 && $(MAKE)) +maildrop/rfc2045/librfc2045.a: + (cd maildrop/rfc2045 && $(MAKE)) + + +install: $(TARGETS) $(LIBPL) + mkdir -p $(BINTARGET) + for f in $(TARGETS); do \ + $(INSTALL_PROGRAM) $$f $(BINTARGET); \ + done + mkdir -p $(PLTARGET) + for f in $(LIBPL); do \ + $(INSTALL_DATA) $$f $(PLTARGET); \ + done + $(PL) -f none -g make -t halt + +ln-install:: + @$(MAKE) INSTALL_DATA='../ln-install' INSTALL_PROGRAM='../ln-install' install + +rpm-install: install + +html-install:: + mkdir -p $(DESTDIR)$(PKGDOC) + $(INSTALL) -m 644 clib.html $(DESTDIR)$(PKGDOC) + +pdf-install:: + mkdir -p $(DESTDIR)$(PKGDOC) + $(INSTALL) -m 644 clib.pdf $(DESTDIR)$(PKGDOC) + +uninstall:: + (cd $(FINAL_BINTARGET) && rm -f $(TARGETS)) + (cd $(FINAL_PLTARGET) && rm -f $(LIBPL)) + $(PL) -f none -g make -t halt + +################################################################ +# Testing +################################################################ + +check: check-socket check-memfile check-unit check-process \ + check-read check-uri check-cgi + +torture: torture-socket + +check-socket:: + $(PL) -q -f $(srcdir)/test_socket.pl -F none -g test_socket,halt -t 'halt(1)' + +torture-socket:: + $(PL) -q -f $(srcdir)/stresssocket.pl -F none -g test,halt -t 'halt(1)' + +check-memfile:: + $(PL) -q -f $(srcdir)/test_memfile.pl -F none -g test_memfile,halt -t 'halt(1)' + +check-unit:: + $(PL) -q -f $(srcdir)/test.pl -g run_tests,halt -t 'halt(1)' + +check-uri:: + $(PL) -q -f $(srcdir)/test_uri.pl -g true -t test_uri + +check-cgi:: + $(PL) -q -f $(srcdir)/test_cgi.pl -g true -t test_cgi + +check-process:: + $(PL) -q -f $(srcdir)/test_process.pl -g true -t test_process + +check-read:: + $(PL) -q -f $(srcdir)/test_readutil.pl -g true -t test_readutil + +################################################################ +# Documentation +################################################################ + +pdf: $(PDF) + +$(DVI): $(TEX) + $(RUNTEX) $(DOC) + +$(PDF): $(TEX) + $(RUNTEX) --pdf $(DOC) + +html: $(TEX) + latex2html $(DOC) + mv html/index.html clib.html + rm -r html + +$(TEX): $(DOCTOTEX) + +uri.tex: uri.pl + $(PLTOTEX) 'library(uri)' +process.tex: process.pl + $(PLTOTEX) 'library(process)' + +.doc.tex: + $(DOCTOTEX) $*.doc > $*.tex + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log sha1/*.o + rm -f $(TEX) + -(cd maildrop/rfc822 && $(MAKE) clean) + -(cd maildrop/rfc2045 && $(MAKE) clean) + +distclean: clean + rm -f $(TARGETS) config.cache config.h config.status Makefile + rm -f clib.aux clib.log clib.out clib.toc + rm -rf html + -(cd maildrop/rfc822 && $(MAKE) distclean) + -(cd maildrop/rfc2045 && $(MAKE) distclean) diff --git a/packages/clib/Makefile.mak b/packages/clib/Makefile.mak new file mode 100644 index 000000000..19c7adca9 --- /dev/null +++ b/packages/clib/Makefile.mak @@ -0,0 +1,160 @@ +################################################################ +# Build the SWI-Prolog tabling package for MS-Windows +# +# Author: Jan Wielemaker +# +# Use: +# nmake /f Makefile.mak +# nmake /f Makefile.mak install +################################################################ + +PLHOME=..\.. +!include $(PLHOME)\src\rules.mk +PKGDLL=socket + +SOCKOBJ= socket.obj nonblockio.obj error.obj +CGIOBJ= error.obj form.obj cgi.obj +CRYPTOBJ= error.obj crypt.obj md5.obj md5passwd.obj bsd-crypt.obj +MEMOBJ= error.obj memfile.obj +MIMEOBJ= error.obj mime.obj +MIMELIBS= rfc2045.lib rfc822.lib +TIMEOBJ= error.obj time.obj +READOBJ= readutil.obj +PROCESSOBJ= error.obj process.obj +RANDOMOBJ= random.obj +SHAOBJ= error.obj sha4pl.obj sha1/sha1.obj sha1/sha2.obj \ + sha1/hmac_sha1.obj sha1/hmac_sha256.obj +URIOBJ= uri.obj +TIMELIBS= winmm.lib + +all: socket.dll cgi.dll memfile.dll mime.dll time.dll readutil.dll \ + random.dll crypt.dll sha4pl.dll process.dll uri.dll + +readutil.dll: $(READOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(READOBJ) $(PLLIB) $(LIBS) +process.dll: $(PROCESSOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(PROCESSOBJ) $(PLLIB) $(LIBS) +socket.dll: $(SOCKOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(SOCKOBJ) $(PLLIB) $(LIBS) +cgi.dll: $(CGIOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(CGIOBJ) $(PLLIB) $(LIBS) +crypt.dll: $(CRYPTOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(CRYPTOBJ) $(PLLIB) $(LIBS) +memfile.dll: $(MEMOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(MEMOBJ) $(PLLIB) $(LIBS) +mime.dll: $(MIMEOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(MIMEOBJ) $(PLLIB) $(LIBS) $(MIMELIBS) +time.dll: $(TIMEOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(TIMEOBJ) $(PLLIB) $(LIBS) $(TIMELIBS) +random.dll: $(RANDOMOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(RANDOMOBJ) $(PLLIB) $(LIBS) +sha4pl.dll: $(SHAOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(SHAOBJ) $(PLLIB) $(LIBS) +uri.dll: $(URIOBJ) + $(LD) /dll /out:$@ $(LDFLAGS) $(URIOBJ) $(PLLIB) $(LIBS) + +sha1/hmac_sha1.obj: sha1/hmac.c + $(CC) -I $(PLHOME)\include $(CFLAGS) /DUSE_SHA1 /Fo$@ sha1/hmac.c +sha1/hmac_sha256.obj: sha1/hmac.c + $(CC) -I $(PLHOME)\include $(CFLAGS) /DUSE_SHA256 /Fo$@ sha1/hmac.c + +!IF "$(CFG)" == "rt" +install: idll +!ELSE +install: idll ilib +!ENDIF + +################################################################ +# Testing +################################################################ + +check: check-socket + +torture: torture-socket + +check-socket:: + "$(PLCON)" -q -f testsocket.pl -F none -g tcp_test,halt -t 'halt(1)' + +torture-socket:: + "$(PLCON)" -q -f stresssocket.pl -F none -g test,halt -t 'halt(1)' + +################################################################ +# Installation +################################################################ + +idll:: + copy socket.dll "$(BINDIR)" + copy cgi.dll "$(BINDIR)" + copy crypt.dll "$(BINDIR)" + copy memfile.dll "$(BINDIR)" + copy mime.dll "$(BINDIR)" + copy time.dll "$(BINDIR)" + copy random.dll "$(BINDIR)" + copy readutil.dll "$(BINDIR)" + copy process.dll "$(BINDIR)" + copy sha4pl.dll "$(BINDIR)" + copy uri.dll "$(BINDIR)" +!IF "$(PDB)" == "true" + copy socket.pdb "$(BINDIR)" + copy cgi.pdb "$(BINDIR)" + copy memfile.pdb "$(BINDIR)" + copy mime.pdb "$(BINDIR)" + copy time.pdb "$(BINDIR)" + copy readutil.pdb "$(BINDIR)" + copy process.pdb "$(BINDIR)" + copy sha4pl.pdb "$(BINDIR)" + copy uri.pdb "$(BINDIR)" +!ENDIF + +ilib:: + copy socket.pl "$(PLBASE)\library" + copy prolog_server.pl "$(PLBASE)\library" + copy streampool.pl "$(PLBASE)\library" + copy cgi.pl "$(PLBASE)\library" + copy crypt.pl "$(PLBASE)\library" + copy memfile.pl "$(PLBASE)\library" + copy mime.pl "$(PLBASE)\library" + copy random.pl "$(PLBASE)\library" + copy time.pl "$(PLBASE)\library" + copy sha.pl "$(PLBASE)\library" + copy uri.pl "$(PLBASE)\library" + copy process.pl "$(PLBASE)\library" + $(MAKEINDEX) + +uninstall:: + del "$(BINDIR)\socket.dll" + del "$(BINDIR)\streampool.dll" + del "$(BINDIR)\cgi.dll" + del "$(BINDIR)\crypt.dll" + del "$(BINDIR)\memfile.dll" + del "$(BINDIR)\mime.dll" + del "$(BINDIR)\random.dll" + del "$(BINDIR)\time.dll" + del "$(BINDIR)\readutil.dll" + del "$(BINDIR)\sha4pl.dll" + del "$(PLBASE)\library\socket.pl" + del "$(PLBASE)\library\cgi.pl" + del "$(PLBASE)\library\crypt.pl" + del "$(PLBASE)\library\memfile.pl" + del "$(PLBASE)\library\mime.pl" + del "$(PLBASE)\library\random.pl" + del "$(PLBASE)\library\time.pl" + del "$(PLBASE)\library\sha.pl" + del "$(PLBASE)\library\uri.pl" + del "$(PLBASE)\library\process.pl" + $(MAKEINDEX) + +html-install:: + copy clib.html "$(PKGDOC)" + +xpce-install:: + +clean:: + if exist *.obj del *.obj + if exist sha1\*.obj del sha1\*.obj + if exist *~ del *~ + +distclean: clean + -DEL *.dll *.lib *.exp *.ilk *.pdb 2>nul + + diff --git a/packages/clib/README b/packages/clib/README new file mode 100644 index 000000000..9bdaa4526 --- /dev/null +++ b/packages/clib/README @@ -0,0 +1,30 @@ +---+ SWI-Prolog Library CLIB + +Author: Jan Wielemaker +Copyright: SWI-Prolog conditions + LGPL for C-code, GPL+exception for Prolog-code + +This library contains SWI-Prolog foreign-libraries to deal with various +OS-dependent or obscure stuff from SWI-Prolog. + +Currently provided: + + * library(unix) + Unix process management and other Unix-specific extensions: + fork/1, exec/1, pipe/2, etc. + + * library(process) + Create and manage processes, compatible to SICStus 4. + + * library(socket) + General purpose inet tcp socket library. Loosely based on a TCP + library from Gordon Streeter. + + * library(cgi) + Get form-arguments from input and/or environment for CGI scripts + + * library(crypt) + Unix password generation and validation. + + * library(memfile) + Read-write to memory-buffers, an alternative to temporary files. diff --git a/packages/clib/VERSION b/packages/clib/VERSION new file mode 100644 index 000000000..6085e9465 --- /dev/null +++ b/packages/clib/VERSION @@ -0,0 +1 @@ +1.2.1 diff --git a/packages/clib/bsd-crypt.c b/packages/clib/bsd-crypt.c new file mode 100644 index 000000000..5dbcc69b7 --- /dev/null +++ b/packages/clib/bsd-crypt.c @@ -0,0 +1,1018 @@ +/* $NetBSD: crypt.c,v 1.26.20.1 2009/05/13 19:18:28 jym Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* JW: Added to make this file compile as-is for SWI-Prolog */ +#define __RCSID(s) static char sccsid[] = s +#define DES_ONLY +#define CRYPT_ONLY +static int des_setkey(const char *key); +static int des_cipher(const char *in, char *out, long salt, int num_iter); + +#ifdef __WINDOWS__ +typedef __int32 int32_t; +#else +#include +#endif + +#if !defined(lint) +#if 0 +static char sccsid[] = "@(#)crypt.c 8.1.1.1 (Berkeley) 8/18/93"; +#else +__RCSID("$NetBSD: crypt.c,v 1.26.20.1 2009/05/13 19:18:28 jym Exp $"); +#endif +#endif /* not lint */ + +#include +#ifndef __WINDOWS__ +#include +#include +#endif +#include +#if defined(DEBUG) || defined(MAIN) || defined(UNIT_TEST) +#include +#endif + +#ifndef __WINDOWS__ +#include "crypt.h" +#endif + +/* + * UNIX password, and DES, encryption. + * By Tom Truscott, trt@rti.rti.org, + * from algorithms by Robert W. Baldwin and James Gillogly. + * + * References: + * "Mathematical Cryptology for Computer Scientists and Mathematicians," + * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. + * + * "Password Security: A Case History," R. Morris and Ken Thompson, + * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. + * + * "DES will be Totally Insecure within Ten Years," M.E. Hellman, + * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. + */ + +/* ===== Configuration ==================== */ + +/* + * define "MUST_ALIGN" if your compiler cannot load/store + * long integers at arbitrary (e.g. odd) memory locations. + * (Either that or never pass unaligned addresses to des_cipher!) + */ +#if !defined(__vax__) && !defined(__i386__) +#define MUST_ALIGN +#endif + +#ifdef CHAR_BITS +#if CHAR_BITS != 8 + #error C_block structure assumes 8 bit characters +#endif +#endif + +/* + * define "B64" to be the declaration for a 64 bit integer. + * XXX this feature is currently unused, see "endian" comment below. + */ +#if defined(cray) +#define B64 long +#endif +#if defined(convex) +#define B64 long long +#endif + +/* + * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes + * of lookup tables. This speeds up des_setkey() and des_cipher(), but has + * little effect on crypt(). + */ +#if defined(notdef) +#define LARGEDATA +#endif + +/* compile with "-DSTATIC=void" when profiling */ +#ifndef STATIC +#define STATIC static void +#endif + +/* ==================================== */ + +/* + * Cipher-block representation (Bob Baldwin): + * + * DES operates on groups of 64 bits, numbered 1..64 (sigh). One + * representation is to store one bit per byte in an array of bytes. Bit N of + * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. + * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the + * first byte, 9..16 in the second, and so on. The DES spec apparently has + * bit 1 in the MSB of the first byte, but that is particularly noxious so we + * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is + * the MSB of the first byte. Specifically, the 64-bit input data and key are + * converted to LSB format, and the output 64-bit block is converted back into + * MSB format. + * + * DES operates internally on groups of 32 bits which are expanded to 48 bits + * by permutation E and shrunk back to 32 bits by the S boxes. To speed up + * the computation, the expansion is applied only once, the expanded + * representation is maintained during the encryption, and a compression + * permutation is applied only at the end. To speed up the S-box lookups, + * the 48 bits are maintained as eight 6 bit groups, one per byte, which + * directly feed the eight S-boxes. Within each byte, the 6 bits are the + * most significant ones. The low two bits of each byte are zero. (Thus, + * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the + * first byte in the eight byte representation, bit 2 of the 48 bit value is + * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is + * used, in which the output is the 64 bit result of an S-box lookup which + * has been permuted by P and expanded by E, and is ready for use in the next + * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this + * lookup. Since each byte in the 48 bit path is a multiple of four, indexed + * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and + * "salt" are also converted to this 8*(6+2) format. The SPE table size is + * 8*64*8 = 4K bytes. + * + * To speed up bit-parallel operations (such as XOR), the 8 byte + * representation is "union"ed with 32 bit values "i0" and "i1", and, on + * machines which support it, a 64 bit value "b64". This data structure, + * "C_block", has two problems. First, alignment restrictions must be + * honored. Second, the byte-order (e.g. little-endian or big-endian) of + * the architecture becomes visible. + * + * The byte-order problem is unfortunate, since on the one hand it is good + * to have a machine-independent C_block representation (bits 1..8 in the + * first byte, etc.), and on the other hand it is good for the LSB of the + * first byte to be the LSB of i0. We cannot have both these things, so we + * currently use the "little-endian" representation and avoid any multi-byte + * operations that depend on byte order. This largely precludes use of the + * 64-bit datatype since the relative order of i0 and i1 are unknown. It + * also inhibits grouping the SPE table to look up 12 bits at a time. (The + * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 + * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the + * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup + * requires a 128 kilobyte table, so perhaps this is not a big loss. + * + * Permutation representation (Jim Gillogly): + * + * A transformation is defined by its effect on each of the 8 bytes of the + * 64-bit input. For each byte we give a 64-bit output that has the bits in + * the input distributed appropriately. The transformation is then the OR + * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for + * each transformation. Unless LARGEDATA is defined, however, a more compact + * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. + * The smaller table uses 16*16*8 = 2K bytes for each transformation. This + * is slower but tolerable, particularly for password encryption in which + * the SPE transformation is iterated many times. The small tables total 9K + * bytes, the large tables total 72K bytes. + * + * The transformations used are: + * IE3264: MSB->LSB conversion, initial permutation, and expansion. + * This is done by collecting the 32 even-numbered bits and applying + * a 32->64 bit transformation, and then collecting the 32 odd-numbered + * bits and applying the same transformation. Since there are only + * 32 input bits, the IE3264 transformation table is half the size of + * the usual table. + * CF6464: Compression, final permutation, and LSB->MSB conversion. + * This is done by two trivial 48->32 bit compressions to obtain + * a 64-bit block (the bit numbering is given in the "CIFP" table) + * followed by a 64->64 bit "cleanup" transformation. (It would + * be possible to group the bits in the 64-bit block so that 2 + * identical 32->32 bit transformations could be used instead, + * saving a factor of 4 in space and possibly 2 in time, but + * byte-ordering and other complications rear their ugly head. + * Similar opportunities/problems arise in the key schedule + * transforms.) + * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. + * This admittedly baroque 64->64 bit transformation is used to + * produce the first code (in 8*(6+2) format) of the key schedule. + * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. + * It would be possible to define 15 more transformations, each + * with a different rotation, to generate the entire key schedule. + * To save space, however, we instead permute each code into the + * next by using a transformation that "undoes" the PC2 permutation, + * rotates the code, and then applies PC2. Unfortunately, PC2 + * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not + * invertible. We get around that problem by using a modified PC2 + * which retains the 8 otherwise-lost bits in the unused low-order + * bits of each byte. The low-order bits are cleared when the + * codes are stored into the key schedule. + * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. + * This is faster than applying PC2ROT[0] twice, + * + * The Bell Labs "salt" (Bob Baldwin): + * + * The salting is a simple permutation applied to the 48-bit result of E. + * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and + * i+24 of the result are swapped. The salt is thus a 24 bit number, with + * 16777216 possible values. (The original salt was 12 bits and could not + * swap bits 13..24 with 36..48.) + * + * It is possible, but ugly, to warp the SPE table to account for the salt + * permutation. Fortunately, the conditional bit swapping requires only + * about four machine instructions and can be done on-the-fly with about an + * 8% performance penalty. + */ + +typedef union { + unsigned char b[8]; + struct { + int32_t i0; + int32_t i1; + } b32; +#if defined(B64) + B64 b64; +#endif +} C_block; + +/* + * Convert twenty-four-bit long in host-order + * to six bits (and 2 low-order zeroes) per char little-endian format. + */ +#define TO_SIX_BIT(rslt, src) { \ + C_block cvt; \ + cvt.b[0] = src; src >>= 6; \ + cvt.b[1] = src; src >>= 6; \ + cvt.b[2] = src; src >>= 6; \ + cvt.b[3] = src; \ + rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ + } + +/* + * These macros may someday permit efficient use of 64-bit integers. + */ +#define ZERO(d,d0,d1) d0 = 0, d1 = 0 +#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 +#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 +#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 +#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 +#define DCL_BLOCK(d,d0,d1) int32_t d0, d1 + +#if defined(LARGEDATA) + /* Waste memory like crazy. Also, do permutations in line */ +#define LGCHUNKBITS 3 +#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); + STORE(D,D0,D1,*out); +} +#endif /* LARGEDATA */ + + +/* ===== (mostly) Standard DES Tables ==================== */ + +static const unsigned char IP[] = { /* initial permutation */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* The final permutation is the inverse of IP - no table is necessary */ + +static const unsigned char ExpandTr[] = { /* expansion operation */ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +static const unsigned char PC1[] = { /* permuted choice table 1 */ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +static const unsigned char Rotates[] = {/* PC1 rotation schedule */ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* note: each "row" of PC2 is left-padded with bits that make it invertible */ +static const unsigned char PC2[] = { /* permuted choice table 2 */ + 9, 18, 14, 17, 11, 24, 1, 5, + 22, 25, 3, 28, 15, 6, 21, 10, + 35, 38, 23, 19, 12, 4, 26, 8, + 43, 54, 16, 7, 27, 20, 13, 2, + + 0, 0, 41, 52, 31, 37, 47, 55, + 0, 0, 30, 40, 51, 45, 33, 48, + 0, 0, 44, 49, 39, 56, 34, 53, + 0, 0, 46, 42, 50, 36, 29, 32, +}; + +static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */ + /* S[1] */ + { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, + /* S[2] */ + { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, + /* S[3] */ + { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, + /* S[4] */ + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, + /* S[5] */ + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, + /* S[6] */ + { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, + /* S[7] */ + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, + /* S[8] */ + { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } +}; + +static const unsigned char P32Tr[] = { /* 32-bit permutation function */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +static const unsigned char CIFP[] = { /* compressed/interleaved permutation */ + 1, 2, 3, 4, 17, 18, 19, 20, + 5, 6, 7, 8, 21, 22, 23, 24, + 9, 10, 11, 12, 25, 26, 27, 28, + 13, 14, 15, 16, 29, 30, 31, 32, + + 33, 34, 35, 36, 49, 50, 51, 52, + 37, 38, 39, 40, 53, 54, 55, 56, + 41, 42, 43, 44, 57, 58, 59, 60, + 45, 46, 47, 48, 61, 62, 63, 64, +}; + +static const unsigned char itoa64[] = /* 0..63 => ascii-64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + +/* ===== Tables that are initialized at run time ==================== */ + + +static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ + +/* Initial key schedule permutation */ +static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ +static C_block CF6464[64/CHUNKBITS][1<= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + num_iter = (num_iter<<6) | a64toi[t]; + } + setting += 4; + encp += 4; + salt_size = 4; + break; +#endif + default: + num_iter = 25; + salt_size = 2; + } + + salt = 0; + for (i = salt_size; --i >= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + salt = (salt<<6) | a64toi[t]; + } + encp += salt_size; + if (des_cipher((char *)(void *)&constdatablock, + (char *)(void *)&rsltblock, salt, num_iter)) + return (NULL); + + /* + * Encode the 64 cipher bits as 11 ascii characters. + */ + i = ((int32_t)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | + rsltblock.b[2]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((int32_t)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | + rsltblock.b[5]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((int32_t)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; + + encp[3] = 0; + + return (cryptresult); +} + + +/* + * The Key Schedule, filled in by des_setkey() or setkey(). + */ +#define KS_SIZE 16 +static C_block KS[KS_SIZE]; + +/* + * Set up the key schedule from the key. + */ +static int +des_setkey(const char *key) +{ + DCL_BLOCK(K, K0, K1); + C_block *help, *ptabp; + int i; + static int des_ready = 0; + + if (!des_ready) { + init_des(); + des_ready = 1; + } + + PERM6464(K,K0,K1,(const unsigned char *)key,(C_block *)PC1ROT); + help = &KS[0]; + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help); + for (i = 1; i < 16; i++) { + help++; + STORE(K,K0,K1,*help); + ptabp = (C_block *)PC2ROT[Rotates[i]-1]; + PERM6464(K,K0,K1,(const unsigned char *)help,ptabp); + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help); + } + return (0); +} + +/* + * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) + * iterations of DES, using the given 24-bit salt and the pre-computed key + * schedule, and store the resulting 8 chars at "out" (in == out is permitted). + * + * NOTE: the performance of this routine is critically dependent on your + * compiler and machine architecture. + */ +static int +des_cipher(const char *in, char *out, long salt, int num_iter) +{ + /* variables that we want in registers, most important first */ +#if defined(pdp11) + int j; +#endif + int32_t L0, L1, R0, R1, k; + C_block *kp; + int ks_inc, loop_count; + C_block B; + + L0 = salt; + TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ + +#if defined(__vax__) || defined(pdp11) + salt = ~salt; /* "x &~ y" is faster than "x & y". */ +#define SALT (~salt) +#else +#define SALT salt +#endif + +#if defined(MUST_ALIGN) + B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; + B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; + LOAD(L,L0,L1,B); +#else + LOAD(L,L0,L1,*(const C_block *)in); +#endif + LOADREG(R,R0,R1,L,L0,L1); + L0 &= 0x55555555L; + L1 &= 0x55555555L; + L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ + R0 &= 0xaaaaaaaaL; + R1 = (R1 >> 1) & 0x55555555L; + L1 = R0 | R1; /* L1 is the odd-numbered input bits */ + STORE(L,L0,L1,B); + PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ + PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ + + if (num_iter >= 0) + { /* encryption */ + kp = &KS[0]; + ks_inc = sizeof(*kp); + } + else + { /* decryption */ + num_iter = -num_iter; + kp = &KS[KS_SIZE-1]; + ks_inc = -(long)sizeof(*kp); + } + + while (--num_iter >= 0) { + loop_count = 8; + do { + +#define SPTAB(t, i) \ + (*(int32_t *)((unsigned char *)t + i*(sizeof(int32_t)/4))) +#if defined(gould) + /* use this if B.b[i] is evaluated just once ... */ +#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); +#else +#if defined(pdp11) + /* use this if your "long" int indexing is slow */ +#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); +#else + /* use this if "k" is allocated to a register ... */ +#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); +#endif +#endif + +#define CRUNCH(p0, p1, q0, q1) \ + k = (q0 ^ q1) & SALT; \ + B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ + B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ + kp = (C_block *)((char *)kp+ks_inc); \ + \ + DOXOR(p0, p1, 0); \ + DOXOR(p0, p1, 1); \ + DOXOR(p0, p1, 2); \ + DOXOR(p0, p1, 3); \ + DOXOR(p0, p1, 4); \ + DOXOR(p0, p1, 5); \ + DOXOR(p0, p1, 6); \ + DOXOR(p0, p1, 7); + + CRUNCH(L0, L1, R0, R1); + CRUNCH(R0, R1, L0, L1); + } while (--loop_count != 0); + kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); + + + /* swap L and R */ + L0 ^= R0; L1 ^= R1; + R0 ^= L0; R1 ^= L1; + L0 ^= R0; L1 ^= R1; + } + + /* store the encrypted (or decrypted) result */ + L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); + L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); + STORE(L,L0,L1,B); + PERM6464(L,L0,L1,B.b, (C_block *)CF6464); +#if defined(MUST_ALIGN) + STORE(L,L0,L1,B); + out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; + out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; +#else + STORE(L,L0,L1,*(C_block *)out); +#endif + return (0); +} + + +/* + * Initialize various tables. This need only be done once. It could even be + * done at compile time, if the compiler were capable of that sort of thing. + */ +STATIC +init_des(void) +{ + int i, j; + int32_t k; + int tableno; + static unsigned char perm[64], tmp32[32]; /* "static" for speed */ + + /* + * table that converts chars "./0-9A-Za-z"to integers 0-63. + */ + for (i = 0; i < 64; i++) + a64toi[itoa64[i]] = i; + + /* + * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. + */ + for (i = 0; i < 64; i++) + perm[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += Rotates[0]-1; + if ((k%28) < Rotates[0]) k -= 28; + k = PC1[k]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i] = k; + } +#ifdef DEBUG + prtab("pc1tab", perm, 8); +#endif + init_perm(PC1ROT, perm, 8, 8); + + /* + * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. + */ + for (j = 0; j < 2; j++) { + unsigned char pc2inv[64]; + for (i = 0; i < 64; i++) + perm[i] = pc2inv[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + pc2inv[k-1] = i+1; + } + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += j; + if ((k%28) <= j) k -= 28; + perm[i] = pc2inv[k]; + } +#ifdef DEBUG + prtab("pc2tab", perm, 8); +#endif + init_perm(PC2ROT[j], perm, 8, 8); + } + + /* + * Bit reverse, then initial permutation, then expansion. + */ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; + if (k > 32) + k -= 32; + else if (k > 0) + k--; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i*8+j] = k; + } + } +#ifdef DEBUG + prtab("ietab", perm, 8); +#endif + init_perm(IE3264, perm, 4, 8); + + /* + * Compression, then final permutation, then bit reverse. + */ + for (i = 0; i < 64; i++) { + k = IP[CIFP[i]-1]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[k-1] = i+1; + } +#ifdef DEBUG + prtab("cftab", perm, 8); +#endif + init_perm(CF6464, perm, 8, 8); + + /* + * SPE table + */ + for (i = 0; i < 48; i++) + perm[i] = P32Tr[ExpandTr[i]-1]; + for (tableno = 0; tableno < 8; tableno++) { + for (j = 0; j < 64; j++) { + k = (((j >> 0) &01) << 5)| + (((j >> 1) &01) << 3)| + (((j >> 2) &01) << 2)| + (((j >> 3) &01) << 1)| + (((j >> 4) &01) << 0)| + (((j >> 5) &01) << 4); + k = S[tableno][k]; + k = (((k >> 3)&01) << 0)| + (((k >> 2)&01) << 1)| + (((k >> 1)&01) << 2)| + (((k >> 0)&01) << 3); + for (i = 0; i < 32; i++) + tmp32[i] = 0; + for (i = 0; i < 4; i++) + tmp32[4 * tableno + i] = (k >> i) & 01; + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i]-1]; + TO_SIX_BIT(SPE[0][tableno][j], k); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i+24]-1]; + TO_SIX_BIT(SPE[1][tableno][j], k); + } + } +} + +/* + * Initialize "perm" to represent transformation "p", which rearranges + * (perhaps with expansion and/or contraction) one packed array of bits + * (of size "chars_in" characters) into another array (of size "chars_out" + * characters). + * + * "perm" must be all-zeroes on entry to this routine. + */ +STATIC +init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ + l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ + for (j = 0; j < (1<>3] |= 1<<(k&07); + } + } +} + +#ifndef CRYPT_ONLY + +/* + * "setkey" routine (for backwards compatibility) + */ +int +setkey(const char *key) +{ + int i, j, k; + C_block keyblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*key++; + } + keyblock.b[i] = k; + } + return (des_setkey((char *)keyblock.b)); +} + +/* + * "encrypt" routine (for backwards compatibility) + */ +int +encrypt(char *block, int flag) +{ + int i, j, k; + C_block cblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*block++; + } + cblock.b[i] = k; + } + if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) + return (1); + for (i = 7; i >= 0; i--) { + k = cblock.b[i]; + for (j = 7; j >= 0; j--) { + *--block = k&01; + k >>= 1; + } + } + return (0); +} + +#endif /*CRYPT_ONLY*/ + +#ifdef DEBUG +STATIC +prtab(const char *s, unsigned char *t, int num_rows) +{ + int i, j; + + (void)printf("%s:\n", s); + for (i = 0; i < num_rows; i++) { + for (j = 0; j < 8; j++) { + (void)printf("%3d", t[i*8+j]); + } + (void)printf("\n"); + } + (void)printf("\n"); +} +#endif + +#if defined(MAIN) || defined(UNIT_TEST) +#ifdef __WINDOWS__ +static void +errx(int status, const char *fmt, const char *s) +{ fprintf(stderr, fmt, s); + exit(status); +} +#else +#include +#endif + +int +main(int argc, char *argv[]) +{ + if (argc < 2) + errx(1, "Usage: %s password [salt]\n", argv[0]); + + printf("%s\n", crypt(argv[1], (argc > 2) ? argv[2] : argv[1])); + exit(0); +} +#endif diff --git a/packages/clib/cgi.c b/packages/clib/cgi.c new file mode 100644 index 000000000..4f90c0f7c --- /dev/null +++ b/packages/clib/cgi.c @@ -0,0 +1,185 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include "clib.h" +#include "form.h" + +static int +isinteger(const char *s, long *val, size_t len) +{ char *e; + + if ( len == (size_t)-1 ) + len = strlen(s); + if ( len == 0 ) + return FALSE; + + *val = strtol(s, &e, 10); + if ( e == s+len ) + return TRUE; + + return FALSE; +} + + +static int +isfloat(const char *s, double *val, size_t len) +{ char *e; + + if ( len == (size_t)-1 ) + len = strlen(s); + if ( len == 0 ) + return FALSE; + + *val = strtod(s, &e); + if ( e == s+len ) + return TRUE; + + return FALSE; +} + + +static int +add_to_form(const char *name, size_t nlen, + const char *value, size_t len, + void *closure) +{ term_t head = PL_new_term_ref(); + term_t tail = (term_t) closure; + term_t val = PL_new_term_ref(); + long vl; + double vf; + int rc; + atom_t aname = 0; + + if ( isinteger(value, &vl, len) ) + rc = PL_put_integer(val, vl); + else if ( isfloat(value, &vf, len) ) + rc = PL_put_float(val, vf); + else + rc = PL_unify_chars(val, PL_ATOM|REP_UTF8, len, value); + + rc = ( rc && + PL_unify_list(tail, head, tail) && + (aname = PL_new_atom_nchars(nlen, name)) && + PL_unify_term(head, + PL_FUNCTOR, PL_new_functor(aname, 1), + PL_TERM, val) ); + + if ( aname ) + PL_unregister_atom(aname); + + return rc; +} + + +static int +mp_add_to_form(const char *name, size_t nlen, + const char *value, size_t len, + const char *file, void *closure) +{ term_t head = PL_new_term_ref(); + term_t tail = (term_t) closure; + term_t val = PL_new_term_ref(); + long vl; + double vf; + int rc; + atom_t aname = 0; + + if ( isinteger(value, &vl, len) ) + rc = PL_put_integer(val, vl); + else if ( isfloat(value, &vf, len) ) + rc = PL_put_float(val, vf); + else + rc = PL_unify_chars(val, PL_ATOM|REP_UTF8, len, value); + + rc = ( rc && + PL_unify_list(tail, head, tail) && + (aname = PL_new_atom_nchars(nlen, name)) && + PL_unify_term(head, + PL_FUNCTOR, PL_new_functor(aname, 1), + PL_TERM, val) ); + + if ( aname ) + PL_unregister_atom(aname); + + return rc; +} + + +static foreign_t +pl_cgi_get_form(term_t form) +{ size_t len = 0; + char *data; + int must_free = FALSE; + term_t list = PL_copy_term_ref(form); + char *ct, *boundary; + + if ( !get_raw_form_data(&data, &len, &must_free) ) + return FALSE; + + if ( (ct = getenv("CONTENT_TYPE")) && + (boundary = strstr(ct, "boundary=")) ) + { boundary = strchr(boundary, '=')+1; + + switch( break_multipart(data, len, boundary, + mp_add_to_form, (void *)list) ) + { case FALSE: + return FALSE; + case TRUE: + break; + default: + assert(0); + return FALSE; + } + } else + { switch( break_form_argument(data, add_to_form, (void *)list) ) + { case FALSE: + return FALSE; + case TRUE: + break; + case ERROR_NOMEM: + return pl_error("cgi_get_form", 1, NULL, + ERR_RESOURCE, "memory"); + case ERROR_SYNTAX_ERROR: + return pl_error("cgi_get_form", 1, NULL, + ERR_SYNTAX, "cgi_value"); + default: + assert(0); + return FALSE; + } + } + + if ( must_free ) + free(data); + + return PL_unify_nil(list); +} + + +install_t +install_cgi() +{ PL_register_foreign("cgi_get_form", 1, pl_cgi_get_form, 0); +} diff --git a/packages/clib/cgi.pl b/packages/clib/cgi.pl new file mode 100644 index 000000000..a3f0ed62c --- /dev/null +++ b/packages/clib/cgi.pl @@ -0,0 +1,37 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(cgi, + [ cgi_get_form/1 % -ListOf Name(Value) + ]). +:- use_module(library(shlib)). + +:- use_foreign_library(foreign(cgi), install_cgi). diff --git a/packages/clib/clib.doc b/packages/clib/clib.doc new file mode 100644 index 000000000..5a8e3ead8 --- /dev/null +++ b/packages/clib/clib.doc @@ -0,0 +1,1128 @@ +\documentclass[11pt]{article} +\usepackage{times} +\usepackage{pl} +\usepackage{plpage} +\usepackage{html} +\sloppy +\makeindex + +\onefile +\htmloutput{html} % Output directory +\htmlmainfile{index} % Main document file +\bodycolor{white} % Page colour + +\renewcommand{\runningtitle}{CLIB -- System interfaces} + +\begin{document} + +\title{SWI-Prolog C-library} +\author{Jan Wielemaker \\ + HCS, \\ + University of Amsterdam \\ + The Netherlands \\ + E-mail: \email{J.Wielemaker@cs.vu.nl}} + +\maketitle + +\begin{abstract} +This document describes commonly used foreign language extensions to +\url[SWI-Prolog]{http://www.swi-prolog.org} +distributed as a package known under the name {\em clib}. The package +defines a number of Prolog libraries with accompagnying foreign +libraries. + +On Windows systems, the \pllib{unix} library can only be used if the +whole SWI-Prolog suite is compiled using +\url[Cywin]{http://www.cygwin.com}. The other libraries have been ported +to native Windows. +\end{abstract} + +\vfill + +\pagebreak +\tableofcontents + +\vfill +\vfill + +\newpage + +\section{Introduction} + +Many useful facilities offered by one or more of the operating systems +supported by SWI-Prolog are not supported by the SWI-Prolog kernel +distribution. Including these would enlarge the {\em footprint} and +complicate portability matters while supporting only a limited part of +the user-community. + +This document describes \pllib{unix} to deal with the Unix process API, +\pllib{socket} to deal with inet-domain TCP and UDP sockets, \pllib{cgi} +to deal with getting CGI form-data if SWI-Prolog is used as a CGI +scripting language, \pllib{crypt} to provide password encryption and +verification, \pllib{sha} providing cryptographic hash functions and +\pllib{memfile} providing in-memorty pseudo files. + + +\section{Unix Process manipulation library} + +The \pllib{unix} library provides the commonly used Unix primitives to +deal with process management. These primitives are useful for many +tasks, including server management, parallel computation, exploiting and +controlling other processes, etc. + +The predicates are modelled closely after their native Unix +counterparts. Higher-level primitives, especially to make this library +portable to non-Unix systems are desirable. Using these primitives and +considering that process manipulation is not a very time-critical +operation we anticipate these libraries to be developed in Prolog. + +\begin{description} + \predicate{fork}{1}{-Pid} +Clone the current process into two branches. In the child, \arg{Pid} is +unified to \const{child}. In the original process, \arg{Pid} is unified +to the process identifier of the created child. Both parent and child +are fully functional Prolog processes running the same program. The +processes share open I/O streams that refer to Unix native streams, such +as files, sockets and pipes. Data is not shared, though on most Unix +systems data is initially shared and duplicated only if one of the +programs attempts to modify the data. + +Unix \funcref{fork}{} is the only way to create new processes and fork/2 +is a simple direct interface to it. + + \predicate{exec}{1}{+Command(...Args...)} +Replace the running program by starting \arg{Command} using the given +commandline arguments. Each command-line argument must be atomic and is +converted to a string before passed to the Unix call \funcref{execvp}{}. + +Unix \funcref{exec}{} is the only way to start an executable file +executing. It is commonly used together with fork/1. For example to +start \program{netscape} on an URL in the background, do: + +\begin{code} +run_netscape(URL) :- + ( fork(child), + exec(netscape(URL)) + ; true + ). +\end{code} + +Using this code, netscape remains part of the process-group of the +invoking Prolog process and Prolog does not wait for netscape to +terminate. The predicate wait/2 allows waiting for a child, while +detach_IO/0 disconnects the child as a deamon process. + + \predicate{wait}{2}{-Pid, -Status} +Wait for a child to change status. Then report the child that changed +status as well as the reason. \arg{Status} is unified with +\term{exited}{ExitCode} if the child with pid \arg{Pid} was terminated +by calling \funcref{exit}{} (Prolog halt/[0,1]). \arg{ExitCode} is the +return=status. \arg{Status} is unified with \term{signaled}{Signal} if +the child died due to a software interrupt (see kill/2). \arg{Signal} +contains the signal number. Finally, if the process suspended execution +due to a signal, \arg{Status} is unified with \term{stopped}{Signal}. + + \predicate{kill}{2}{+Pid, +Signal} +Deliver a software interrupt to the process with identifier \arg{Pid} +using software-interrupt number \arg{Signal}. See also on_signal/2. +Signals can be specified as an integer or signal name, where signal +names are derived from the C constant by dropping the \const{SIG} prefix +and mapping to lowercase. E.g.\ \const{int} is the same as +\const{SIGINT} in C. The meaning of the signal numbers can be found in +the Unix manual.\footnote{kill/2 should support interrupt-names as +well}. + + \predicate{pipe}{2}{-InSream, -OutStream} +Create a communication-pipe. This is normally used to make a child +communicate to its parent. After pipe/2, the process is cloned and, +depending on the desired direction, both processes close the end of the +pipe they do not use. Then they use the remaining stream to communicate. +Here is a simple example: + +\begin{code} +:- use_module(library(unix)). + +fork_demo(Result) :- + pipe(Read, Write), + fork(Pid), + ( Pid == child + -> close(Read), + format(Write, '~q.~n', + [hello(world)]), + flush_output(Write), + halt + ; close(Write), + read(Read, Result), + close(Read) + ). +\end{code} + + \predicate{dup}{2}{+FromStream, +ToStream} +Interface to Unix dup2(), copying the underlying filedescriptor and thus +making both streams point to the same underlying object. This is +normally used together with fork/1 and pipe/2 to talk to an external +program that is designed to communicate using standard I/O. + +Both \arg{FromStream} and \arg{ToStream} either refer to a Prolog stream +or an integer descriptor number to refer directly to OS descriptors. +See also \file{demo/pipe.pl} in the source-distribution of this package. + + \predicate{detach_IO}{0}{} +This predicate is intended to create Unix deamon-processes. It preforms +two actions. First of all, the I/O streams \const{user_input}, +\const{user_output} and \const{user_error} are closed and rebound to +a Prolog stream that returns end-of-file on any attempt to read and +starts writing to a file named \file{/tmp/pl-out.pid} (where is +the process-id of the calling Prolog) on any attempt +to write. This file is opened only if there is data available. This is +intended for debugging purposes.% + \footnote{More subtle handling of I/O, especially for debugging is + required: communicate with the syslog deamon and + optionally start a debugging dialog on a newly created + (X-)terminal should be considered.} +Finally, the process is detached from the current process-group and its +controlling terminal. +\end{description} + + +\input{process.tex} + + +\section{File manipulation library} + +The \pllib{files} library provides additional operations on files from +SWI-Prolog. It is currently very incomplete. + +\begin{description} + \predicate{set_time_file}{3}{+File, -OldTimes, +NewTimes} +Query and set POSIX time attributes of a file. Both \arg{OldTimes} +and \arg{NewTimes} are lists of option-terms. Times are represented +in SWI-Prolog's standard floating point numbers. New times may +be specified as \const{now} to indicate the current time. Defined +options are: + +\begin{description} + \termitem{access}{Time} +Describes the time of last access of the file. This value can be +read and written. + + \termitem{modified}{Time} +Describes the time the contents of the file was last modified. +This value can be read and written. + + \termitem{changed}{Time} +Describes the time the file-structure itself was changed by adding +(link()) or removing (unlink()) names. +\end{description} + +Here are some example queries. The first retrieves the access-time, +while the second sets the last-modified time to the current time. + +\begin{code} +?- set_time_file(foo, [acess(Access)], []). +?- set_time_file(foo, [], [modified(now)]). +\end{code} +\end{description} + +\section{Socket library} + +The \pllib{socket} library provides TCP and UDP inet-domain sockets from +SWI-Prolog, both client and server-side communication. The interface of +this library is very close to the Unix socket interface, also supported +by the MS-Windows {\em winsock} API. SWI-Prolog applications that wish +to communicate with multiple sources have three options: + +\begin{enumerate} + \item Use I/O multiplexing based on wait_for_input/3. On Windows + systems this can only be used for sockets, not for general + (device-) file handles. + \item Use multiple threads, handling either a single blocking socket + or a pool using I/O multiplexing as above. + \item Using XPCE's class \class{socket} which synchronises socket + events in the GUI event-loop. +\end{enumerate} + +\begin{description} + \predicate{tcp_socket}{1}{-SocketId} +Creates an \const{INET}-domain stream-socket and unifies an identifier +to it with \arg{SocketId}. On MS-Windows, if the socket library is not +yet initialised, this will also initialise the library. + + \predicate{tcp_close_socket}{1}{+SocketId} +Closes the indicated socket, making \arg{SocketId} invalid. Normally, +sockets are closed by closing both stream handles returned by +open_socket/3. There are two cases where tcp_close_socket/1 is used +because there are no stream-handles: + +\begin{itemize} + \item After tcp_accept/3, the server does a fork/1 to handle the client + in a sub-process. In this case the accepted socket is not + longer needed from the main server and must be discarded + using tcp_close_socket/1. + \item If, after discovering the connecting client with tcp_accept/3, + the server does not want to accept the connection, it should + discard the accepted socket immediately using tcp_close_socket/1. +\end{itemize} + + \predicate{tcp_open_socket}{3}{+SocketId, -InStream, -OutStream} +Open two SWI-Prolog I/O-streams, one to deal with input from the socket +and one with output to the socket. If tcp_bind/2 has been called on the +socket. \arg{OutSream} is useless and will not be created. After closing +both \arg{InStream} and \arg{OutSream}, the socket itself is discarded. + + \predicate{tcp_bind}{2}{+Socket, ?Port} +Bind the socket to \arg{Port} on the current machine. This operation, +together with tcp_listen/2 and tcp_accept/3 implement the {\em +server}-side of the socket interface. If \arg{Port} is unbound, the +system picks an arbitrary free port and unifies \arg{Port} with the +selected port number. \arg{Port} is either an integer or the name of a +registered service. See also tcp_connect/4. + + \predicate{tcp_listen}{2}{+Socket, +Backlog} +Tells, after tcp_bind/2, the socket to listen for incoming requests for +connections. \arg{Backlog} indicates how many pending connection +requests are allowed. Pending requests are requests that are not yet +acknowledged using tcp_accept/3. If the indicated number is exceeded, the +requesting client will be signalled that the service is currently not +available. A suggested default value is 5. + + \predicate{tcp_accept}{3}{+Socket, -Slave, -Peer} +This predicate waits on a server socket for a connection request by +a client. On success, it creates a new socket for the client and +binds the identifier to \arg{Slave}. \arg{Peer} is bound to the +IP-address of the client. + + \predicate[deprecated]{tcp_connect}{2}{+Socket, +Host:+Port} +Connect \arg{Socket}. After successful completion, tcp_open_socket/3 can +be used to create I/O-Streams to the remote socket. New code should use +tcp_connect/4, which can be hooked to allow for proxy negotiation. + + \predicate{tcp_connect}{4}{+Socket, +Host:+Port, -Read, -Write} +Client-interface to connect a socket to a given \arg{Port} on a given +\arg{Host}. \arg{Port} is either an integer or the name of a registered +service. The fragment below connects to the +\url{http://www.swi-prolog.org} using the service name instead of the +hardcoded number `80'. + +\begin{code} + Adress = 'www.swi-prolog.org':http, + tcp_socket(Socket), + tcp_connect(Socket, Adress, Read, Write), +\end{code} + +This predicate can be hooked by defining the multifile-predicate +socket:tcp_connect_hook/4. This hook is specifically intented for proxy +negotiation. The code below shows the structure of such a hook. The +predicates \nopredref{proxy}{1} and \nopredref{proxy_connect}{3} must +be provided by the user. + +\begin{code} +:- multifile socket:tcp_connect_hook/4. + +socket:tcp_connect_hook(Socket, Address, Read, Write) :- + proxy(ProxyAdress), + tcp_connect(Socket, ProxyAdress), + tcp_open_socket(Socket, Read, Write), + proxy_connect(Address, Read, Write). +\end{code} + + \predicate{tcp_setopt}{2}{+Socket, +Option} +Set options on the socket. Defined options are: + +\begin{description} + \termitem{reuseaddr}{} +Allow servers to reuse a port without the system being completely sure +the port is no longer in use. + + \termitem{nodelay}{} +Same as \term{nodelay}{true} + + \termitem{nodelay}{Bool} +If \const{true}, disable the Nagle optimization on this socket, which +is enabled by default on almost all modern TCP/IP stacks. The Nagle +optimization joins small packages, which is generally desirable, but +sometimes not. Please note that the underlying TCP_NODELAY setting +to setsockopt() is not available on all platforms and systems +may require additional privileges to change this option. If the option +is not supported, tcp_setopt/2 raises a domain_error exception. +See \url[Wikipedia]{http://en.wikipedia.org/wiki/Nagle's_algorithm} for +details. + + \termitem{broadcast}{} +UDP sockets only: broadcast the package to all addresses matching the +address. The address is normally the address of the local subnet +(i.e. 192.168.1.255). See udp_send/4. + + \termitem{dispatch}{Bool} +In GUI environments (using XPCE or the Windows plwin.exe executable) +this flags defines whether or not any events are dispatched on behalf of +the user interface. Default is \const{true}. Only very specific +situations require setting this to \const{false}. +\end{description} + + \predicate{tcp_fcntl}{3}{+Stream, +Action, ?Argument} +Interface to the Unix \funcref{fcntl}{} call. Currently only suitable +to deal switch stream to non-blocking mode using: + +\begin{code} + ... + tcp_fcntl(Stream, setfl. nonblock), + ... +\end{code} + +As of SWI-Prolog 3.2.4, handling of non-blocking stream is supported. An +attempt to read from a non-blocking stream returns -1 (or +\const{end_of_file} for read/1), but at_end_of_stream/1 fails. On actual +end-of-input, at_end_of_stream/1 succeeds. + + \predicate{tcp_host_to_address}{2}{?HostName, ?Address} +Translate between a machines host-name and it's (IP-)address. If +\arg{HostName} is an atom, it is resolved using +\funcref{gethostbyname}{} and the IP-number is unified to \arg{Address} +using a term of the format \term{ip}{Byte1, Byte2, Byte3, Byte4}. +Otherwise, if \arg{Address} is bound to a \functor{ip}{4} term, it +is resolved by \funcref{gethostbyaddr}{} and the canonical hostname +is unified with \arg{HostName}. + + \predicate{gethostname}{1}{-Hostname} +Return the official fully qualified name of this host. This is achieved +by calling gethostname() followed by gethostbyname() and return the +official name of the host (\const{h_name}) of the structure returned +by the latter function. +\end{description} + + +\subsection{Server applications} + +The typical sequence for generating a server application is defined +below: + +\begin{code} +create_server(Port) :- + tcp_socket(Socket), + tcp_bind(Socket, Port), + tcp_listen(Socket, 5), + tcp_open_socket(Socket, AcceptFd, _), + +\end{code} + +There are various options for . The most commonly used option +is to start a Prolog thread to handle the connection. Alternatively, +input from multiple clients can be handled in a single thread by +listening to these clients using wait_for_input/3. Finally, on Unix +systems, we can use fork/1 to handle the connection in a new process. +Note that fork/1 and threads do not cooperate well. Combinations can be +realised but require good understanding of POSIX thread and +fork-semantics. + +Below is the typical example using a thread. Note the use of +setup_call_cleanup/3 to guarantee that all resources are reclaimed, also +in case of failure or exceptions. + +\begin{code} +dispatch(AcceptFd) :- + tcp_accept(AcceptFd, Socket, _Peer), + thread_create(process_client(Socket, Peer), _, + [ detached(true) + ]), + dispatch(AcceptFd). + +process_client(Socket, Peer) :- + setup_call_cleanup(tcp_open_socket(Socket, In, Out), + handle_service(In, Out), + close_connection(In, Out)). + +close_connection(In, Out) :- + close(In, [force(true)]), + close(Out, [force(true)]). + +handle_service(In, Out) :- + ... +\end{code} + + +\subsection{Client applications} + +The skeleton for client-communication is given below. + +\begin{code} +create_client(Host, Port) :- + setup_call_catcher_cleanup(tcp_socket(Socket), + tcp_connect(Socket, Host:Port), + exception(_), + tcp_close_socket(Socket)), + setup_call_cleanup(tcp_open_socket(Socket, In, Out), + chat_to_server(In, Out), + close_connection(In, Out)). + +close_connection(In, Out) :- + close(In, [force(true)]), + close(Out, [force(true)]). + +chat_to_server(In, Out) :- + ... +\end{code} + +To deal with timeouts and multiple connections, wait_for_input/3 and/or +non-blocking streams (see tcp_fcntl/3) can be used. + + +\subsection{The stream_pool library} + +The \pllib{streampool} library dispatches input from multiple streams +based on wait_for_input/3. It is part of the clib package as it is used +most of the time together with the \pllib{socket} library. On non-Unix +systems it often can only be used with socket streams. + +With SWI-Prolog 5.1.x, multi-threading often provides a good alternative +to using this library. In this schema one thread watches the listening +socket waiting for connections and either creates a thread per +connection or processes the accepted connections with a pool of +\jargon{worker threads}. The library \pllib{http/thread_httpd} provides +an example realising a mult-threaded HTTP server. + +\begin{description} + \predicate{add_stream_to_pool}{2}{+Stream, :Goal} +Add \arg{Stream}, which must be an input stream and ---on non-unix +systems--- connected to a socket to the pool. If input is available +on \arg{Stream}, \arg{Goal} is called. + + \predicate{delete_stream_from_pool}{1}{+Stream} +Delete the given stream from the pool. Succeeds, even if \arg{Stream} +is no member of the pool. If \arg{Stream} is unbound the entire pool +is emtied but unlike close_stream_pool/0 the streams are not closed. + + \predicate{close_stream_pool}{0}{} +Empty the pool, closing all streams that are part of it. + + \predicate{dispatch_stream_pool}{1}{+TimeOut} +Wait for maximum of \arg{TimeOut} for input on any of the streams in +the pool. If there is input, call the \arg{Goal} associated with +add_stream_to_pool/2. If \arg{Goal} fails or raises an exception a +message is printed. \arg{TimeOut} is described with wait_for_input/3. + +If \arg{Goal} is called, there is \emph{some} input on the associated +stream. \arg{Goal} must be careful not to block as this will block +the entire pool.% + \footnote{This is hard to achieve at the moment as none of the + Prolog read-commands provide for a timeout.} + + \predicate{stream_pool_main_loop}{0}{} +Calls dispatch_stream_pool/1 in a loop until the pool is empty. +\end{description} + +Below is a very simple example that reads the first line of input and +echos it back. + +\begin{code} +:- use_module(library(streampool)). + +server(Port) :- + tcp_socket(Socket), + tcp_bind(Socket, Port), + tcp_listen(Socket, 5), + tcp_open_socket(Socket, In, _Out), + add_stream_to_pool(In, accept(Socket)), + stream_pool_main_loop. + +accept(Socket) :- + tcp_accept(Socket, Slave, Peer), + tcp_open_socket(Slave, In, Out), + add_stream_to_pool(In, client(In, Out, Peer)). + +client(In, Out, _Peer) :- + read_line_to_codes(In, Command), + close(In), + format(Out, 'Please to meet you: ~s~n', [Command]), + close(Out), + delete_stream_from_pool(In). +\end{code} + + +\subsection{UDP protocol support} + +The current library provides limited support for UDP packets. The UDP +protocol is a \emph{connection-less} and \emph{unreliable} datagram +based protocol. That means that messages sent may or may not arrive at +the client side and may arrive in a different order as they are sent. +UDP messages are often used for streaming media or for service discovery +using the broadcasting mechanism. + +\begin{description} + \predicate{udp_socket}{1}{-Socket} +Similar to tcp_socket/1, but create a socket using the \const{SOCK_DGRAM} +protocol, ready for UDP connections. + + \predicate{udp_receive}{4}{+Socket, -Data, -From, +Options} +Wait for and return the next datagram. The data is returned as a +Prolog string object (see string_to_list/2). \arg{From} is a term of the +format \mbox{ip(\arg{A},\arg{B},\arg{C},\arg{D}):\arg{Port}} indicating +the sender of the message. \arg{Socket} can be waited for using wait_for_input/3. +Defined \arg{Options}: + + \begin{description} + \termitem{as}{+Type} + Defines the returned term-type. \arg{Type} is one of + \const{atom}, \const{codes} or \const{string} (default). + \end{description} + +The typical sequence to receive UDP data is: + +\begin{code} +receive(Port) :- + udp_socket(S), + tcp_bind(S, Port), + repeat, + udp_receive(Socket, Data, From, [as(atom)]), + format('Got ~q from ~q~n', [Data, From]), + fail. +\end{code} + + \predicate{udp_send}{4}{+Socket, +Data, +To, +Options} +Send a UDP message. Data is a string, atom or code-list providing the +data. \arg{To} is an address of the form \arg{Host}:\arg{Port} where +Host is either the hostname or a term ip/4. \arg{Options} is currently unused. + +A simple example to send UDP data is: + +\begin{code} +send(Host, Port, Message) :- + udp_socket(S), + udp_send(S, Message, Host:Port, []), + tcp_close_socket(S). +\end{code} + +A broadcast is achieved by using \term{tcp_setopt}{Socket, broadcast} +prior to sending the datagram and using the local network broadcast +address as a ip/4 term. +\end{description} + +The normal mechanism to discover a service on the local network is for +the client to send a broadcast message to an agreed port. The server +receives this message and replies to the client with a message +indicating further details to establish the communication. + +\input{uri.tex} + +\section{CGI Support library} + +This is currently a very simple library, providing support for obtaining +the form-data for a CGI script: + +\begin{description} + \predicate{cgi_get_form}{1}{-Form} +Decodes standard input and the environment variables to obtain a list +of arguments passed to the CGI script. This predicate both deals with +the CGI {\bf GET} method as well as the {\bf POST} method. If the +data cannot be obtained, an \const{existence_error} exception is +raised. +\end{description} + +Below is a very simple CGI script that prints the passed parameters. +To test it, compile this program using the command below, copy it to +your cgi-bin directory (or make it otherwise known as a CGI-script) and +make the query \verb$http://myhost.mydomain/cgi-bin/cgidemo?hello=world$ + +\begin{code} +% pl -o cgidemo --goal=main --toplevel=halt -c cgidemo.pl +\end{code} + +\begin{code} +:- use_module(library(cgi)). + +main :- + set_stream(current_output, encoding(utf8)), + cgi_get_form(Arguments), + format('Content-type: text/html; charset=UTF-8~n~n', []), + format('~n', []), + format('~n', []), + format('Simple SWI-Prolog CGI script~n', []), + format('~n~n', []), + format('~n', []), + format('

', []), + print_args(Arguments), + format('~n~n', []). + +print_args([]). +print_args([A0|T]) :- + A0 =.. [Name, Value], + format('~w=~w
~n', [Name, Value]), + print_args(T). +\end{code} + +\subsection{Some considerations} + +Printing an HTML document using format/2 is not a neat way of producing +HTML because it is vulnerable to required escape sequences. A high-level +alternative is provided by \pllib{http/html_write} from the HTTP +library. + +The startup-time of Prolog is relatively long, in particular if the +program is large. In many cases it is much better to use the +SWI-Prolog HTTP server library and make the main web-server relay +requests to the SWI-Prolog webserver. See the SWI-Prolog \url[HTTP +package]{http://www.swi-prolog.org/pldoc/package/http.html} for details. + + +The CGI standard is unclear about handling Unicode data. The above two +declarations ensure the CGI script will send all data in UTF-8 and thus +provide full support of Unicode. It is assumed that browsers generally +send form-data using the same encoding as the page in which the form +appears, UTF-8 or ISO Latin-1. The current version of cgi_get_form/1 +assumes the CGI data is in UTF-8. + + +\section{MIME decoding library} + +MIME (Multipurpose Internet Mail Extensions) is a format for serializing +multiple typed data objects. It was designed for E-mail, but it is also +used for other applications such packaging multiple values using the +HTTP POST request on web-servers. Double Precision, Inc.\ has produced +the C-libraries rfc822 (mail) and rfc2045 (MIME) for decoding and +manipulating MIME messages. The \pllib{mime} library is a Prolog wrapper +around the rfc2045 library for decoding MIME messages. + +The general name `mime' is used for this library as it is anticipated to +add MIME-creation functionality to this library. + +Currently the mime library defines one predicate: + +\begin{description} + \predicate{mime_parse}{2}{Data, Parsed} +Parse \arg{Data} and unify the result to \arg{Parsed}. \arg{Data} is +one of: + +\begin{description} + \termitem{stream}{Stream} +Parse the data from \arg{Stream} upto the end-of-file. + \termitem{stream}{Stream, Length} +Parse a maximum of \arg{Length} characters from \arg{Stream} or +upto the end-of-file, whichever comes first. + \termitem{\arg{Text}}{} +Atoms, strings, code- and character lists are treated as valid +sources of data. +\end{description} + +\arg{Parsed} is a tree structure of \term{mime}{Attributes, Data, +PartList} terms. Currently either \arg{Data} is the empty atom +or \arg{PartList} is an empty list.% + \footnote{It is unclear to me whether a MIME note can contain + a mixture of content and parts, but I believe the + answer is `no'.} +\arg{Data} is an atom holding the message data. The library +automatically decodes \jargon{base64} and \jargon{quoted-printable} +messages. See also the \const{transfer_encoding} attribute below. + + \arg{PartList} is +a list of \functor{mime}{3} terms. \arg{Attributes} is a list holding +a subset of the following arguments. For details please consult the +RFC2045 document. + +\begin{description} + \termitem{type}{Atom} +Denotes the Content-Type, how the \arg{Data} should be interpreted. + \termitem{transfer_encoding}{Atom} +How the \arg{Data} was encoded. This is not very interesting as the +library decodes the content of the message. + \termitem{character_set}{Atom} +The character set used for text data. Note that SWI-Prolog's +capabilities for character-set handling are limited. + \termitem{language}{Atom} +Language in which the text-data is written. + \termitem{id}{Atom} +Identifier of the message-part. + \termitem{description}{Atom} +Descrptive text for the \arg{Data}. + \termitem{disposition}{Atom} +Where the data comes from. The current library only deals with +`inline' data. + \termitem{name}{Atom} +Name of the part. + \termitem{filename}{Atom} +Name of the file the data should be stored in. +\end{description} +\end{description} + +\section{Password encryption library} +\label{sec:crypt} + +The \pllib{crypt} library defines crypt/2 for encrypting and testing +passwords. The clib package also provides crytographic hashes as +described in \secref{sha} + +\begin{description} + \predicate{crypt}{2}{+Plain, ?Encrypted} +This predicate can be used in three modes. To test whether a password +matches an encrypted version thereof, simply run with both arguments +fully instantiated. To generate a default encrypted version of +\arg{Plain}, run with unbound \arg{Encrypted} and this argument is +unified to a list of character codes holding an encrypted version. + +The library supports two encryption formats: traditional Unix +DES-hashes\footnote{On non-Unix systems, crypt() is provided by the +NetBSD library. The license header is added at the end of this +document.} and FreeBSD compatible MD5 hashes (all platforms). MD5 hashes +start with the magic sequence \verb|$1$|, followed by an up to 8 +character \jargon{salt}. DES hashes start with a 2 character +\jargon{salt}. Note that a DES hash considers only the first 8 +characters. The MD5 considers the whole string. + +Salt and algorithm can be forced by instantiating the start of +\arg{Encrypted} with it. This is typically used to force MD5 hashes: + +\begin{code} +?- append("$1$", _, E), + crypt("My password", E), + format('~s~n', [E]). + +$1$qdaDeDZn$ZUxSQEESEHIDCHPNc3fxZ1 +\end{code} + +\arg{Encrypted} is always an ASCII string. \arg{Plain} only supports +ISO-Latin-1 passwords in the current implementation. + +\arg{Plain} is either an atom, SWI-Prolog string, list of characters +or list of character-codes. It is not advised to use atoms, as this +implies the password will be available from the Prolog heap as a +defined atom. +\end{description} + + +\section{SHA1 and SHA2 Secure Hash Algorithms} +\label{sec:sha} + +The library \pllib{sha} provides \jargon{Secure Hash Algorihms} approved +by FIPS (\jargon{Federal Information Processing Standard}). Quoting +\url[Wikipedia]{http://en.wikipedia.org/wiki/SHA-1}: \textit{``The SHA +(Secure Hash Algorithm) hash functions refer to five FIPS-approved +algorithms for computing a condensed digital representation (known as a +message digest) that is, to a high degree of probability, unique for a +given input data sequence (the message). These algorithms are called +`secure' because (in the words of the standard), ``for a given +algorithm, it is computationally infeasible 1) to find a message that +corresponds to a given message digest, or 2) to find two different +messages that produce the same message digest. Any change to a message +will, with a very high probability, result in a different message +digest.''} + +The current library supports all 5 approved algorithms, both computing +the hash-key from data and the \jargon{hash Message Authentication Code} +(HMAC). + +Input is text, represented as an atom, packed string object or +code-list. Note that these functions operate on byte-sequences and +therefore are not meaningful on Unicode text. The result is returned as +a list of byte-values. This is the most general format that is +comfortable supported by standard Prolog and can easily be transformed +in other formats. Commonly used text formats are ASCII created by +encoding each byte as two hexadecimal digits and ASCII created using +\jargon{base64} encoding. Representation as a large integer can be +desirable for computational processing. + +\begin{description} + \predicate{sha_hash}{3}{+Data, -Hash, +Options} +Hash is the SHA hash of Data. \arg{Data} is either an atom, packed +string or list of character codes. \arg{Hash} is unified with a list of +integers representing the hash. The conversion is controlled by Options: + + \begin{description} + \termitem{algorithm}{+Algorithm} +One of \const{sha1} (default), \const{sha224}, \const{sha256}, +\const{sha384} or \const{sha512} + \end{description} + + \predicate{hmac_sha}{4}{+Key, +Data, -HMAC, +Options} +Quoting \url[Wikipedia]{http://en.wikipedia.org/wiki/HMAC}: \textit{``A +keyed-hash message authentication code, or HMAC, is a type of message +authentication code (MAC) calculated using a cryptographic hash function +in combination with a secret key. As with any MAC, it may be used to +simultaneously verify both the data integrity and the authenticity of a +message. Any iterative cryptographic hash function, such as MD5 or +SHA-1, may be used in the calculation of an HMAC; the resulting MAC +algorithm is termed HMAC-MD5 or HMAC-SHA-1 accordingly. The +cryptographic strength of the HMAC depends upon the cryptographic +strength of the underlying hash function, on the size and quality of the +key and the size of the hash output length in bits.''} + +\arg{Key} and \arg{Data} are either an atom, packed string or list of +character codes. \arg{HMAC} is unified with a list of integers +representing the authentication code. \arg{Options} is the same as for +sha_hash/3, but currently only \const{sha1} and \const{sha256} are +supported. +\end{description} + +\subsection{License terms} + +The underlying SHA-2 library is an unmodified copy created by Dr Brian +Gladman, Worcester, UK. It is distributed under the license conditions +below. + +The free distribution and use of this software in both source and binary +form is allowed (with or without changes) provided that: + +\begin{enumerate} +\item + distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + +\item + distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + +\item + the copyright holder's name is not used to endorse products + built using this software without specific written permission. +\end{enumerate} + +ALTERNATIVELY, provided that this notice is retained in full, this +product may be distributed under the terms of the GNU General Public +License (GPL), in which case the provisions of the GPL apply INSTEAD OF +those given above. + + +\section{Memory files} + +The \pllib{memfile} provides an alternative to temporary files, intended +for temporary buffering of data. Memory files in general are faster than +temporary files and do not suffer from security riscs or naming +conflicts associated with temporary-file management. They do +assume proper memory management by the hosting OS and cannot be used +to pass data to external processes using a file-name. + +There is no limit to the number of memory streams, nor the size of them. +However, memory-streams cannot have multiple streams at the same time +(i.e.\ cannot be opened for reading and writing at the same time). + +These predicates are first of all intended for building higher-level +primitives. See also sformat/3, atom_to_term/3, term_to_atom/2 and +the XPCE primitive pce_open/3. + + +\begin{description} + \predicate{new_memory_file}{1}{-Handle} +Create a new memory file and return a unique opaque handle to it. + + \predicate{free_memory_file}{1}{+Handle} +Discard the memory file and its contents. If the file is open it +is first closed. + + \predicate{open_memory_file}{3}{+Handle, +Mode, -Stream} +Open the memory-file. \arg{Mode} is currently one of \const{read} +or \const{write}. The resulting \arg{Stream} must be closed +using close/1. + + \predicate{open_memory_file}{4}{+Handle, +Mode, -Stream, +Options} +Open a memory-file as open_memory_file/3. Options: + +\begin{description} + \termitem{encoding}{+Encoding} +Set the encoding for a memory file and the created stream. Encoding +names are the same as used with open/4. By default, memoryfiles +represent UTF-8 streams, making them capable of storing arbitrary +Unicode text. In practice the only alternative is \const{octet}, turning +the memoryfile into binary mode. Please study SWI-Prolog Unicode and +encoding issues before using this option. + \termitem{free_on_close}{+Bool} +If \const{true} (default \const{false} and the memory file is opened +for reading, discard the file (see free_memory_file/1) if the input +is closed. This is used to realise open_chars_stream/2 in +library(charsio). +\end{description} + + \predicate{size_memory_file}{2}{+Handle, -Bytes} +Return the content-length of the memory-file it \arg{Bytes}. The +file should be closed and contain data. + + \predicate{atom_to_memory_file}{2}{+Atom, -Handle} +Turn an atom into a read-only memory-file containing the (shared) +characters of the atom. Opening this memory-file in mode \const{write} +yields a permission error. + + \predicate{memory_file_to_atom}{2}{+Handle, -Atom} +Return the content of the memory-file in \arg{Atom}. + + \predicate{memory_file_to_atom}{3}{+Handle, -Atom, +Encoding} +Return the content of the memory-file in \arg{Atom}, pretending the data +is in the given \arg{Encoding}. This can be used to convert from one +encoding into another, typically from/to bytes. For example, if we +must convert a set of bytes that contain text in UTF-8, open the memory +file as octet stream, fill it, and get the result using \arg{Encoding} +is \const{utf8}. + + \predicate{memory_file_to_codes}{2}{+Handle, -Codes} +Return the content of the memory-file as a list of character-codes +in \arg{Codes}. + + \predicate{memory_file_to_codes}{3}{+Handle, -Codes, +Encoding} +Return the content of the memory-file as a list of character-codes +in \arg{Codes}, pretending the data is in the given \arg{Encoding}. +\end{description} + + +\section{Time and alarm library} + +The \pllib{time} provides timing and alarm functions. + +\begin{description} + \predicate{alarm}{4}{+Time, :Callable, -Id, +Options} +Schedule \arg{Callable} to be called \arg{Time} seconds from now. +\arg{Time} is a number (integer or float). \arg{Callable} is called +on the next pass through a call- or redo-port of the Prolog engine, +or a call to the PL_handle_signals() routine from SWI-Prolog. \arg{Id} +is unified with a reference to the timer. + +The resolution of the alarm depends on the underlying implementation. On +Unix systems it is based on setitimer(), on Windows on timeSetEvent() +using a resolution specified at 50 milliseconds.\bug{The maximum time +for timeSetEvent() used by the Windows application is 1000 seconds. +Calling with a higher time value raises a \const{resource_error} +exception.} Long-running foreign predicates that do not call +PL_handle_signals() may further delay the alarm. + +\arg{Options} is a list of \term{\arg{Name}}{Value} terms. Defined +options are: + +\begin{description} + \termitem{remove}{Bool} +If \const{true} (default \const{false}), the timer is removed +automatically after fireing. Otherwise it must be destroyed explicitly +using remove_alarm/1. + \termitem{install}{Bool} +If \const{false} (default \const{true}), the timer is allocated but not +scheduled for execution. It must be started later using install_alarm/1. +\end{description} + + \predicate{alarm}{3}{+Time, :Callable, -Id} +Same as \term{alarm}{Time, Callable, Id, []}. + + \predicate{alarm_at}{4}{+Time, :Callable, -Id, +Options} +as alarm/3, but \arg{Time} is the specification of an absolute point in +time. Absolute times are specified in seconds after the Jan 1, 1970 +epoch. See also date_time_stamp/2. + + \predicate{install_alarm}{1}{+Id} +Activate an alarm allocated using alarm/4 with the option +\term{install}{false} or stopped using uninstall_alarm/1. + + \predicate{install_alarm}{1}{+Id, +Time} +As install_alarm/1, but specifies a new timeout value. + + \predicate{uninstall_alarm}{1}{+Id} +Deactivate a running alarm, but do not invalidate the alarm identifier. +Later, the alarm can be reactivated using either install_alarm/1 or +install_alarm/2. Reinstalled using install_alarm/1, it will fire at the +originally scheduled time. Reinstalled using install_alarm/2 causes the +alarm to fire at the specified time from now. + + \predicate{remove_alarm}{1}{+Id} +Remove an alarm. If it is not yet fired, it will not be fired +any more. + + \predicate{current_alarm}{4}{?At, ?:Callable, ?Id, ?Status} +Enumerate the not-yet-removed alarms. \arg{Status} is one of +\const{done} if the alarm has been called, \const{next} if it +is the next to be fired and \arg{scheduled} otherwise. + + \predicate{call_with_time_limit}{2}{+Time, :Goal} +True if \arg{Goal} completes within \arg{Time} seconds. \arg{Goal} is +executed as in once/1. If \arg{Goal} doesn't complete within \arg{Time} +seconds (wall time), exit using the exception +\const{time_limit_exceeded}. See catch/3. + +Please note that this predicate uses alarm/4 and therefore is \emph{not} +capable to break out of long running goals such as sleep/1, blocking I/O +or other long-running (foreign) predicates. Blocking I/O can be handled +using the timeout option of read_term/3. +\end{description} + + +\section{Limiting process resources} + +The \pllib{rlimit} library provides an interface to the POSIX +getrlimit()/setrlimit() API that control the maximum resource-usage +of a process or group of processes. This call is especially useful +for servers such as CGI scripts and inetd-controlled servers to avoid +an uncontrolled script claiming too much resources. + +\begin{description} + \predicate{rlimit}{3}{+Resource, -Old, +New} +Query and/or set the limit for \arg{Resource}. Time-values are +in seconds and size-values are counted in bytes. The following +values are supported by this library. Please note that not all +resources may be available and accessible on all platforms. This +predicate can throw a variety of exceptions. In portable code this +should be guarded with catch/3. The defined resources are: + +\begin{quote} +\begin{tabular}{ll} +\const{cpu} & CPU time in seconds \\ +\const{fsize} & Maximum filesize \\ +\const{data} & max data size \\ +\const{stack} & max stack size \\ +\const{core} & max core file size \\ +\const{rss} & max resident set size \\ +\const{nproc} & max number of processes \\ +\const{nofile} & max number of open files \\ +\const{memlock} & max locked-in-memory address \\ +\end{tabular} +\end{quote} + +When the process hits a limit POSIX systems normally send the process a +signal that terminates it. These signals may be catched using +SWI-Prolog's on_signal/3 primitive. The code below illustrates this +behaviour. Please note that asynchronous signal handling is dangerous, +especially when using threads. 100\% fail-safe operation cannot be +guaranteed, but this procedure will inform the user properly `most of +the time'. + +\begin{code} +rlimit_demo :- + rlimit(cpu, _, 2), + on_signal(xcpu, _, cpu_exceeded), + ( repeat, fail ). + +cpu_exceeded(_Sig) :- + format(user_error, 'CPU time exceeded~n', []), + halt(1). +\end{code} +\end{description} + +\section*{NetBSD Crypt license} + +\begin{code} + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. +\end{code} + +\printindex + +\end{document} + diff --git a/packages/clib/clib.h b/packages/clib/clib.h new file mode 100644 index 000000000..2c13d7cd8 --- /dev/null +++ b/packages/clib/clib.h @@ -0,0 +1,41 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef CLIB_H_INCLUDED +#define CLIB_H_INCLUDED + +#include +#include "error.h" + +#define CompoundArg(name, arity) \ + PL_FUNCTOR, PL_new_functor(PL_new_atom(name), (arity)) +#define AtomArg(name) \ + PL_CHARS, name +#define IntArg(i) \ + PL_INTEGER, (long)(i) + +install_t install_process(void); +install_t install_socket(void); + +#endif /*CLIB_H_INCLUDED*/ diff --git a/packages/clib/config.h b/packages/clib/config.h new file mode 100644 index 000000000..c9bb71c61 --- /dev/null +++ b/packages/clib/config.h @@ -0,0 +1,156 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* "Define if _XOPEN_SOURCE is needed" */ +#define DEFINE_XOPEN_SOURCE 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the `crypt' function. */ +#define HAVE_CRYPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_CRYPT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getrlimit' function. */ +#define HAVE_GETRLIMIT 1 + +/* Define of h_errno is provided */ +#define HAVE_H_ERRNO 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `crypt' library (-lcrypt). */ +#define HAVE_LIBCRYPT 1 + +/* "Define if you have the nsl library (-lnsl)." */ +/* #undef HAVE_LIBNSL */ + +/* "Define if you have the socket library (-lsocket)." */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the `setitimer' function. */ +#define HAVE_SETITIMER 1 + +/* Define to 1 if you have the `setsid' function. */ +#define HAVE_SETSID 1 + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 1 + +/* Define to 1 if the system has the type `ssize_t'. */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#define HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define for multi-thread support */ +/* #undef _REENTRANT */ diff --git a/packages/clib/config.h.in b/packages/clib/config.h.in new file mode 100644 index 000000000..36027e187 --- /dev/null +++ b/packages/clib/config.h.in @@ -0,0 +1,155 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* "Define if _XOPEN_SOURCE is needed" */ +#undef DEFINE_XOPEN_SOURCE + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `crypt' function. */ +#undef HAVE_CRYPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRYPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EXECINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define of h_errno is provided */ +#undef HAVE_H_ERRNO + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `crypt' library (-lcrypt). */ +#undef HAVE_LIBCRYPT + +/* "Define if you have the nsl library (-lnsl)." */ +#undef HAVE_LIBNSL + +/* "Define if you have the socket library (-lsocket)." */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the `setitimer' function. */ +#undef HAVE_SETITIMER + +/* Define to 1 if you have the `setsid' function. */ +#undef HAVE_SETSID + +/* Define to 1 if the system has the type `socklen_t'. */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if the system has the type `ssize_t'. */ +#undef HAVE_SSIZE_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `utime' function. */ +#undef HAVE_UTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define for multi-thread support */ +#undef _REENTRANT diff --git a/packages/clib/config.log b/packages/clib/config.log new file mode 100644 index 000000000..1633c1b13 --- /dev/null +++ b/packages/clib/config.log @@ -0,0 +1,830 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.64. Invocation command line was + + $ ./configure --prefix=/home/vsc/Yap/Prologs/pl-devel --prefix=/home/vsc/Yap/Prologs/pl-devel + +## --------- ## +## Platform. ## +## --------- ## + +hostname = xato +uname -m = x86_64 +uname -r = 2.6.32-22-generic +uname -s = Linux +uname -v = #33-Ubuntu SMP Wed Apr 28 13:28:05 UTC 2010 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/vsc/Yap/Prologs/pl-devel/bin +PATH: /home/vsc/bin +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /sbin +PATH: /bin +PATH: /usr/games +PATH: /home/vsc/lgtsvn/xml +PATH: /home/vsc/lgtsvn/scripts +PATH: /home/vsc/lgtsvn/integration + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2285: checking for gmake +configure:2312: result: make +configure:2328: checking for etags +configure:2344: found /usr/bin/etags +configure:2355: result: etags +configure:2404: checking for a BSD-compatible install +configure:2472: result: /usr/bin/install -c +configure:2531: checking for gcc +configure:2558: result: ../swipl-ld.sh +configure:2787: checking for C compiler version +configure:2796: ../swipl-ld.sh --version >&5 +gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 +Copyright (C) 2009 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2807: $? = 0 +configure:2796: ../swipl-ld.sh -v >&5 +Using built-in specs. +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) +configure:2807: $? = 0 +configure:2796: ../swipl-ld.sh -V >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2807: $? = 1 +configure:2796: ../swipl-ld.sh -qversion >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2807: $? = 1 +configure:2829: checking for C compiler default output file name +configure:2851: ../swipl-ld.sh conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2855: $? = 0 +configure:2892: result: a.out +configure:2908: checking whether the C compiler works +configure:2917: ./a.out +configure:2921: $? = 0 +configure:2936: result: yes +configure:2943: checking whether we are cross compiling +configure:2945: result: no +configure:2948: checking for suffix of executables +configure:2955: ../swipl-ld.sh -o conftest conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2959: $? = 0 +configure:2981: result: +configure:2987: checking for suffix of object files +configure:3009: ../swipl-ld.sh -c conftest.c >&5 +configure:3013: $? = 0 +configure:3034: result: o +configure:3038: checking whether we are using the GNU C compiler +configure:3057: ../swipl-ld.sh -c conftest.c >&5 +configure:3057: $? = 0 +configure:3066: result: yes +configure:3075: checking whether ../swipl-ld.sh accepts -g +configure:3095: ../swipl-ld.sh -c -g conftest.c >&5 +configure:3095: $? = 0 +configure:3136: result: yes +configure:3153: checking for ../swipl-ld.sh option to accept ISO C89 +configure:3217: ../swipl-ld.sh -c -g -O2 conftest.c >&5 +configure:3217: $? = 0 +configure:3230: result: none needed +configure:3251: checking for library containing strerror +configure:3282: ../swipl-ld.sh -o conftest -g -O2 conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3282: $? = 0 +configure:3299: result: none required +configure:3312: checking how to run the C preprocessor +configure:3343: ../swipl-ld.sh -E conftest.c +configure:3343: $? = 0 +configure:3357: ../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3357: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3382: result: ../swipl-ld.sh -E +configure:3402: ../swipl-ld.sh -E conftest.c +configure:3402: $? = 0 +configure:3416: ../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3416: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3445: checking for grep that handles long lines and -e +configure:3503: result: /bin/grep +configure:3508: checking for egrep +configure:3570: result: /bin/grep -E +configure:3575: checking for ANSI C header files +configure:3595: ../swipl-ld.sh -c -g -O2 conftest.c >&5 +configure:3595: $? = 0 +configure:3668: ../swipl-ld.sh -o conftest -g -O2 conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.01 sec, 37,800 bytes +% halt +configure:3668: $? = 0 +configure:3668: ./conftest +configure:3668: $? = 0 +configure:3679: result: yes +configure:3693: checking for sys/types.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for sys/stat.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for stdlib.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for string.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for memory.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for strings.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for inttypes.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for stdint.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3693: checking for unistd.h +configure:3693: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3693: $? = 0 +configure:3693: result: yes +configure:3708: checking for working alloca.h +configure:3725: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3725: $? = 0 +configure:3733: result: yes +configure:3741: checking for alloca +configure:3778: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3778: $? = 0 +configure:3786: result: yes +configure:3896: checking whether byte ordering is bigendian +configure:3911: ../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'a' +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3911: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_ALLOCA 1 +| /* end confdefs.h. */ +| #ifndef __APPLE_CC__ +| not a universal capable compiler +| #endif +| typedef int dummy; +| +configure:3956: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3956: $? = 0 +configure:3974: ../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c: In function 'main': +conftest.c:28: error: 'not' undeclared (first use in this function) +conftest.c:28: error: (Each undeclared identifier is reported only once +conftest.c:28: error: for each function it appears in.) +conftest.c:28: error: expected ';' before 'big' +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3974: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_ALLOCA 1 +| /* end confdefs.h. */ +| #include +| #include +| +| int +| main () +| { +| #if BYTE_ORDER != BIG_ENDIAN +| not big endian +| #endif +| +| ; +| return 0; +| } +configure:4102: result: no +configure:4131: checking for socket +configure:4131: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4131: $? = 0 +configure:4131: result: yes +configure:4181: checking for gethostent +configure:4181: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4181: $? = 0 +configure:4181: result: yes +configure:4233: checking for crypt in -lcrypt +configure:4258: ../swipl-ld.sh -o conftest -fPIC conftest.c -lcrypt >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.01 sec, 37,800 bytes +% halt +configure:4258: $? = 0 +configure:4267: result: yes +configure:4281: checking for crypt +configure:4281: ../swipl-ld.sh -o conftest -fPIC conftest.c -lcrypt >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.01 sec, 37,800 bytes +% halt +configure:4281: $? = 0 +configure:4281: result: yes +configure:4292: checking "Configuring MIME libraries" +configure:4315: result: "Done" +configure:4318: checking h_errno +configure:4337: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4337: $? = 0 +configure:4341: result: yes +configure:4352: checking malloc.h usability +configure:4352: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking malloc.h presence +configure:4352: ../swipl-ld.sh -E conftest.c +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking for malloc.h +configure:4352: result: yes +configure:4352: checking alloca.h usability +configure:4352: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking alloca.h presence +configure:4352: ../swipl-ld.sh -E conftest.c +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking for alloca.h +configure:4352: result: yes +configure:4352: checking for unistd.h +configure:4352: result: yes +configure:4352: checking sys/time.h usability +configure:4352: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking sys/time.h presence +configure:4352: ../swipl-ld.sh -E conftest.c +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking for sys/time.h +configure:4352: result: yes +configure:4352: checking fcntl.h usability +configure:4352: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking fcntl.h presence +configure:4352: ../swipl-ld.sh -E conftest.c +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking for fcntl.h +configure:4352: result: yes +configure:4352: checking utime.h usability +configure:4352: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking utime.h presence +configure:4352: ../swipl-ld.sh -E conftest.c +configure:4352: $? = 0 +configure:4352: result: yes +configure:4352: checking for utime.h +configure:4352: result: yes +configure:4366: checking execinfo.h usability +configure:4366: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking execinfo.h presence +configure:4366: ../swipl-ld.sh -E conftest.c +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking for execinfo.h +configure:4366: result: yes +configure:4366: checking sys/resource.h usability +configure:4366: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking sys/resource.h presence +configure:4366: ../swipl-ld.sh -E conftest.c +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking for sys/resource.h +configure:4366: result: yes +configure:4366: checking crypt.h usability +configure:4366: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking crypt.h presence +configure:4366: ../swipl-ld.sh -E conftest.c +configure:4366: $? = 0 +configure:4366: result: yes +configure:4366: checking for crypt.h +configure:4366: result: yes +configure:4380: checking for sys/types.h +configure:4380: result: yes +configure:4380: checking sys/wait.h usability +configure:4380: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4380: $? = 0 +configure:4380: result: yes +configure:4380: checking sys/wait.h presence +configure:4380: ../swipl-ld.sh -E conftest.c +configure:4380: $? = 0 +configure:4380: result: yes +configure:4380: checking for sys/wait.h +configure:4380: result: yes +configure:4380: checking for sys/stat.h +configure:4380: result: yes +configure:4393: checking netinet/tcp.h usability +configure:4393: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4393: $? = 0 +configure:4393: result: yes +configure:4393: checking netinet/tcp.h presence +configure:4393: ../swipl-ld.sh -E conftest.c +configure:4393: $? = 0 +configure:4393: result: yes +configure:4393: checking for netinet/tcp.h +configure:4393: result: yes +configure:4407: checking for setsid +configure:4407: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4407: $? = 0 +configure:4407: result: yes +configure:4407: checking for strerror +configure:4407: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4407: $? = 0 +configure:4407: result: yes +configure:4407: checking for setitimer +configure:4407: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4407: $? = 0 +configure:4407: result: yes +configure:4407: checking for utime +configure:4407: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4407: $? = 0 +configure:4407: result: yes +configure:4407: checking for getrlimit +configure:4407: ../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:4407: $? = 0 +configure:4407: result: yes +configure:4417: checking for socklen_t +configure:4417: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4417: $? = 0 +configure:4417: ../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c: In function 'main': +conftest.c:50: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:4417: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_ALLOCA 1 +| #define HAVE_LIBCRYPT 1 +| #define HAVE_CRYPT 1 +| #define HAVE_H_ERRNO 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UTIME_H 1 +| #define HAVE_EXECINFO_H 1 +| #define HAVE_SYS_RESOURCE_H 1 +| #define HAVE_CRYPT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_NETINET_TCP_H 1 +| #define HAVE_SETSID 1 +| #define HAVE_STRERROR 1 +| #define HAVE_SETITIMER 1 +| #define HAVE_UTIME 1 +| #define HAVE_GETRLIMIT 1 +| /* end confdefs.h. */ +| +| #include +| #include +| +| +| int +| main () +| { +| if (sizeof ((socklen_t))) +| return 0; +| ; +| return 0; +| } +configure:4417: result: yes +configure:4431: checking for ssize_t +configure:4431: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4431: $? = 0 +configure:4431: ../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c: In function 'main': +conftest.c:51: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:4431: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_ALLOCA 1 +| #define HAVE_LIBCRYPT 1 +| #define HAVE_CRYPT 1 +| #define HAVE_H_ERRNO 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_ALLOCA_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UTIME_H 1 +| #define HAVE_EXECINFO_H 1 +| #define HAVE_SYS_RESOURCE_H 1 +| #define HAVE_CRYPT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_NETINET_TCP_H 1 +| #define HAVE_SETSID 1 +| #define HAVE_STRERROR 1 +| #define HAVE_SETITIMER 1 +| #define HAVE_UTIME 1 +| #define HAVE_GETRLIMIT 1 +| #define HAVE_SOCKLEN_T 1 +| /* end confdefs.h. */ +| +| #include +| #include +| +| +| int +| main () +| { +| if (sizeof ((ssize_t))) +| return 0; +| ; +| return 0; +| } +configure:4431: result: yes +configure:4446: checking _XOPEN_SOURCE +configure:4463: ../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:4463: $? = 0 +configure:4467: result: yes +configure:4610: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on xato + +config.status:846: creating Makefile +config.status:846: creating config.h +config.status:1012: config.h is unchanged + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_bigendian=no +ac_cv_c_compiler_gnu=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_alloca_works=yes +ac_cv_func_crypt=yes +ac_cv_func_gethostent=yes +ac_cv_func_getrlimit=yes +ac_cv_func_setitimer=yes +ac_cv_func_setsid=yes +ac_cv_func_socket=yes +ac_cv_func_strerror=yes +ac_cv_func_utime=yes +ac_cv_header_alloca_h=yes +ac_cv_header_crypt_h=yes +ac_cv_header_execinfo_h=yes +ac_cv_header_fcntl_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_malloc_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_netinet_tcp_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_resource_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_time_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_sys_wait_h=yes +ac_cv_header_unistd_h=yes +ac_cv_header_utime_h=yes +ac_cv_lib_crypt_crypt=yes +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_GREP=/bin/grep +ac_cv_prog_CPP='../swipl-ld.sh -E' +ac_cv_prog_ETAGS=etags +ac_cv_prog_MAKE=make +ac_cv_prog_ac_ct_CC=../swipl-ld.sh +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_search_strerror='none required' +ac_cv_type_socklen_t=yes +ac_cv_type_ssize_t=yes +ac_cv_working_alloca_h=yes + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +ALLOCA='' +CC='../swipl-ld.sh' +CFLAGS='-fPIC' +CIFLAGS='' +CMFLAGS='-fPIC' +COFLAGS='-O2 -fno-strict-aliasing' +CPP='../swipl-ld.sh -E' +CPPFLAGS='' +CRYPTLIBS='-lcrypt ' +CWFLAGS='-Wall' +DEFS='-DHAVE_CONFIG_H' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +ETAGS='etags' +EXEEXT='' +GREP='/bin/grep' +INSTALL_DATA='/usr/bin/install -c -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LD='../swipl-ld.sh' +LDFLAGS='' +LDSOFLAGS='-shared' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +MAKE='make' +NETLIBS='' +OBJEXT='o' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_URL='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +PL='../swipl.sh' +PLARCH='x86_64-linux' +PLBASE='/home/vsc/Yap/Prologs/pl-devel/lib/swipl-5.9.11' +PLINCL='/home/vsc/Yap/Prologs/pl-devel/include' +PLLD='../swipl-ld.sh' +PLLIBS='-lgmp -lrt -lreadline -lncurses -lm -lrt -ldl ' +PLTARGETS='random.pl unix.pl socket.pl cgi.pl memfile.pl filesex.pl mime.pl crypt.pl time.pl rlimit.pl streampool.pl' +SHELL='/bin/bash' +SO='so' +TARGETS='random.so unix.so socket.so cgi.so memfile.so files.so mime.so crypt.so time.so rlimit.so' +ac_ct_CC='../swipl-ld.sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/home/vsc/Yap/Prologs/pl-devel' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_URL "" +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_ALLOCA 1 +#define HAVE_LIBCRYPT 1 +#define HAVE_CRYPT 1 +#define HAVE_H_ERRNO 1 +#define HAVE_MALLOC_H 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_UTIME_H 1 +#define HAVE_EXECINFO_H 1 +#define HAVE_SYS_RESOURCE_H 1 +#define HAVE_CRYPT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_WAIT_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_NETINET_TCP_H 1 +#define HAVE_SETSID 1 +#define HAVE_STRERROR 1 +#define HAVE_SETITIMER 1 +#define HAVE_UTIME 1 +#define HAVE_GETRLIMIT 1 +#define HAVE_SOCKLEN_T 1 +#define HAVE_SSIZE_T 1 +#define DEFINE_XOPEN_SOURCE 1 + +configure: exit 0 diff --git a/packages/clib/configure b/packages/clib/configure new file mode 100755 index 000000000..f0c4481ca --- /dev/null +++ b/packages/clib/configure @@ -0,0 +1,5766 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.64. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +# Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="install-sh" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +ALLOCA +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +MAKE +PLLD +LDSOFLAGS +SO +LD +ETAGS +CMFLAGS +CWFLAGS +CIFLAGS +COFLAGS +PLINCL +PLARCH +PLBASE +PLLIBS +PL +CRYPTLIBS +NETLIBS +PLTARGETS +TARGETS +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_time +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-time Exclude alarm library + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.64 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + + + + + + + + + + + + + + + + + + + + +if test -z "$PLINCL"; then +plcandidates="swipl swi-prolog pl" +for ac_prog in $plcandidates +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_PL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PL"; then + ac_cv_prog_PL="$PL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_PL="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PL=$ac_cv_prog_PL +if test -n "$PL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PL" >&5 +$as_echo "$PL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PL" && break +done +test -n "$PL" || PL=""none"" + +for ac_prog in swipl-ld plld +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_PLLD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PLLD"; then + ac_cv_prog_PLLD="$PLLD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_PLLD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PLLD=$ac_cv_prog_PLLD +if test -n "$PLLD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PLLD" >&5 +$as_echo "$PLLD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PLLD" && break +done +test -n "$PLLD" || PLLD=""none"" + +if test $PLLD = "none"; then + as_fn_error "\"Cannot find SWI-Prolog swipl-ld utility. SWI-Prolog must be installed first\"" "$LINENO" 5 +fi +if test $PL = "none"; then + as_fn_error "\"Cannot find SWI-Prolog. SWI-Prolog must be installed first\"" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking \"Running $PL -dump-runtime-variables\"..." >&5 +$as_echo "$as_me: checking \"Running $PL -dump-runtime-variables\"..." >&6;} + eval `$PL -dump-runtime-variables` +fi +PLINCL=$PLBASE/include +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLBASE=$PLBASE\"" >&5 +$as_echo "\" PLBASE=$PLBASE\"" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLARCH=$PLARCH\"" >&5 +$as_echo "\" PLARCH=$PLARCH\"" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLLIBS=$PLLIBS\"" >&5 +$as_echo "\" PLLIBS=$PLLIBS\"" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLLDFLAGS=$PLLDFLAGS\"" >&5 +$as_echo "\" PLLDFLAGS=$PLLDFLAGS\"" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLSHARED=$PLSHARED\"" >&5 +$as_echo "\" PLSHARED=$PLSHARED\"" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \" PLSOEXT=$PLSOEXT\"" >&5 +$as_echo "\" PLSOEXT=$PLSOEXT\"" >&6; } +if test "$PLTHREADS" = "yes"; then MT=yes; fi +else +PL=../swipl.sh +PLLD=../swipl-ld.sh +fi + +if test "$MT" = yes; then + +$as_echo "#define _REENTRANT 1" >>confdefs.h + +fi + +CC=$PLLD +LD=$PLLD +LDSOFLAGS=-shared +CMFLAGS=-fPIC + +SO="$PLSOEXT" + +for ac_prog in gmake make +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_MAKE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MAKE"; then + ac_cv_prog_MAKE="$MAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MAKE="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MAKE=$ac_cv_prog_MAKE +if test -n "$MAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 +$as_echo "$MAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$MAKE" && break +done +test -n "$MAKE" || MAKE=""make"" + +for ac_prog in etags ctags +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ETAGS+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ETAGS"; then + ac_cv_prog_ETAGS="$ETAGS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ETAGS="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ETAGS=$ac_cv_prog_ETAGS +if test -n "$ETAGS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ETAGS" >&5 +$as_echo "$ETAGS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ETAGS" && break +done +test -n "$ETAGS" || ETAGS="":"" + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done +done +if test -z "$ac_aux_dir"; then + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + rm -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then : + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +fi +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5 +$as_echo_n "checking for library containing strerror... " >&6; } +if test "${ac_cv_search_strerror+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char strerror (); +int +main () +{ +return strerror (); + ; + return 0; +} +_ACEOF +for ac_lib in '' cposix; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_strerror=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_strerror+set}" = set; then : + break +fi +done +if test "${ac_cv_search_strerror+set}" = set; then : + +else + ac_cv_search_strerror=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5 +$as_echo "$ac_cv_search_strerror" >&6; } +ac_res=$ac_cv_search_strerror +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +CFLAGS="$CMFLAGS" +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if test "${ac_cv_os_cray+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + return find_stack_direction () < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +if test ! -z "$GCC"; then + COFLAGS="${COFLAGS--O2 -fno-strict-aliasing}" + CWFLAGS="${CWFLAGS--Wall}" +else + COFLAGS="${COFLAGS--O}" +fi + + +TARGETS="random.$SO unix.$SO socket.$SO cgi.$SO memfile.$SO files.$SO mime.$SO crypt.$SO" + +ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" +if test "x$ac_cv_func_socket" = x""yes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_socket+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = x""yes; then : + NETLIBS="$NETLIBS -lsocket"; LIBS="$LIBS -lsocket" + +$as_echo "#define HAVE_LIBSOCKET 1" >>confdefs.h + +fi + +fi + +ac_fn_c_check_func "$LINENO" "gethostent" "ac_cv_func_gethostent" +if test "x$ac_cv_func_gethostent" = x""yes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostent in -lnsl" >&5 +$as_echo_n "checking for gethostent in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_gethostent+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostent (); +int +main () +{ +return gethostent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostent=yes +else + ac_cv_lib_nsl_gethostent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostent" >&5 +$as_echo "$ac_cv_lib_nsl_gethostent" >&6; } +if test "x$ac_cv_lib_nsl_gethostent" = x""yes; then : + NETLIBS="$NETLIBS -lnsl" + +$as_echo "#define HAVE_LIBNSL 1" >>confdefs.h + +fi + +fi + + +oldlibs="$LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 +$as_echo_n "checking for crypt in -lcrypt... " >&6; } +if test "${ac_cv_lib_crypt_crypt+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypt_crypt=yes +else + ac_cv_lib_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 +$as_echo "$ac_cv_lib_crypt_crypt" >&6; } +if test "x$ac_cv_lib_crypt_crypt" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCRYPT 1 +_ACEOF + + LIBS="-lcrypt $LIBS" + +fi + +CRYPTLIBS="$LIBS" +for ac_func in crypt +do : + ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" +if test "x$ac_cv_func_crypt" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CRYPT 1 +_ACEOF + +fi +done + +LIBS="$oldlibs" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking \"Configuring MIME libraries\"" >&5 +$as_echo_n "checking \"Configuring MIME libraries\"... " >&6; } +case "$CC" in + .*) ACC="../../$CC" + ;; + *) ACC="$CC" +esac +case "$LD" in + .*) ALD="../../$LD" + ;; + *) ALD="$LD" +esac +case "$CPP" in + .*) ACPP="../../$CPP" + ;; + *) ACPP="$CPP" +esac +( CC=$ACC; LD=$ALD; CPP=$ACPP; CFLAGS=$CFLAGS; LDFLAGS=$LDFLAGS; + export CC LD CFLAGS LDFLAGS + + (cd maildrop/rfc822 && $SHELL configure) + (cd maildrop/rfc2045 && $SHELL configure) +) +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Done\"" >&5 +$as_echo "\"Done\"" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking h_errno" >&5 +$as_echo_n "checking h_errno... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ + int x = h_errno; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_H_ERRNO 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +for ac_header in malloc.h alloca.h unistd.h sys/time.h fcntl.h utime.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in execinfo.h sys/resource.h crypt.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in sys/types.h sys/wait.h sys/stat.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in netinet/tcp.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "netinet/tcp.h" "ac_cv_header_netinet_tcp_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet_tcp_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETINET_TCP_H 1 +_ACEOF + +fi + +done + + +for ac_func in setsid strerror setitimer utime getrlimit +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " +#include +#include + +" +if test "x$ac_cv_type_socklen_t" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKLEN_T 1 +_ACEOF + + +fi + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" " +#include +#include + +" +if test "x$ac_cv_type_ssize_t" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SSIZE_T 1 +_ACEOF + + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _XOPEN_SOURCE" >&5 +$as_echo_n "checking _XOPEN_SOURCE... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _XOPEN_SOURCE +#include + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define DEFINE_XOPEN_SOURCE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +with_time=yes + +# Check whether --with-time was given. +if test "${with_time+set}" = set; then : + withval=$with_time; case "$withval" in + yes) with_time=yes ;; + no) with_time=no ;; + esac +fi + + +if test "$with_time" = yes; then + if test "$ac_cv_func_setitimer" = "yes"; then + TARGETS="$TARGETS time.$SO" + else + echo "WARNING: no setitimer(); dropping time.pl from targets" + fi +fi + +if test "$ac_cv_func_getrlimit" = "yes"; then + TARGETS="$TARGETS rlimit.$SO" +else + "WARNING: no getrlimit(); dropping rlimit.pl from targets" +fi + +PLTARGETS=`echo $TARGETS | sed -e "s/\.$SO/.pl/g" -e "s/files.pl/filesex.pl/"` +if echo "$PLTARGETS" | grep socket.pl 2>&1 >/dev/null; then + PLTARGETS="$PLTARGETS streampool.pl" +fi + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + + + diff --git a/packages/clib/configure.in b/packages/clib/configure.in new file mode 100644 index 000000000..faa66881b --- /dev/null +++ b/packages/clib/configure.in @@ -0,0 +1,129 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(install-sh) +AC_PREREQ([2.50]) +AC_CONFIG_HEADER(config.h) + +AC_SUBST(TARGETS) +AC_SUBST(PLTARGETS) +AC_SUBST(NETLIBS) +AC_SUBST(CRYPTLIBS) + +m4_include([../ac_swi_c.m4]) + +TARGETS="random.$SO unix.$SO socket.$SO cgi.$SO memfile.$SO files.$SO mime.$SO crypt.$SO" + +AC_CHECK_FUNC(socket, [], [ + AC_CHECK_LIB(socket, socket, + [NETLIBS="$NETLIBS -lsocket"; LIBS="$LIBS -lsocket"] + AC_DEFINE(HAVE_LIBSOCKET, 1, + "Define if you have the socket library (-lsocket)."))]) +AC_CHECK_FUNC(gethostent, [], [ + AC_CHECK_LIB(nsl, gethostent, + [NETLIBS="$NETLIBS -lnsl"] + AC_DEFINE(HAVE_LIBNSL, 1, + "Define if you have the nsl library (-lnsl)."))]) + +oldlibs="$LIBS" +AC_CHECK_LIB(crypt, crypt) +CRYPTLIBS="$LIBS" +AC_CHECK_FUNCS(crypt) +LIBS="$oldlibs" + +AC_MSG_CHECKING("Configuring MIME libraries") +case "$CC" in + .*) ACC="../../$CC" + ;; + *) ACC="$CC" +esac +case "$LD" in + .*) ALD="../../$LD" + ;; + *) ALD="$LD" +esac +case "$CPP" in + .*) ACPP="../../$CPP" + ;; + *) ACPP="$CPP" +esac +( CC=$ACC; LD=$ALD; CPP=$ACPP; CFLAGS=$CFLAGS; LDFLAGS=$LDFLAGS; + export CC LD CFLAGS LDFLAGS + + (cd maildrop/rfc822 && $SHELL configure) + (cd maildrop/rfc2045 && $SHELL configure) +) +AC_MSG_RESULT("Done") + +AC_MSG_CHECKING(h_errno) +AC_TRY_COMPILE( +[ +#include +#include +#include +#include +], +[ int x = h_errno; +], AC_DEFINE(HAVE_H_ERRNO, 1, + [Define of h_errno is provided]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + +AC_CHECK_HEADERS(malloc.h alloca.h unistd.h sys/time.h fcntl.h utime.h) +AC_CHECK_HEADERS(execinfo.h sys/resource.h crypt.h) +AC_CHECK_HEADERS(sys/types.h sys/wait.h sys/stat.h) +AC_CHECK_HEADERS(netinet/tcp.h) + +AC_CHECK_FUNCS(setsid strerror setitimer utime getrlimit) +AC_CHECK_TYPES(socklen_t, [], [], +[ +#include +#include +]) +AC_CHECK_TYPES(ssize_t, [], [], +[ +#include +#include +]) + +AC_MSG_CHECKING(_XOPEN_SOURCE) +AC_TRY_COMPILE( +[ +#define _XOPEN_SOURCE +#include +], +[ +], AC_DEFINE(DEFINE_XOPEN_SOURCE, 1, + "Define if _XOPEN_SOURCE is needed") + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + +with_time=yes +AC_ARG_WITH(time, [ --without-time Exclude alarm library], + [case "$withval" in + yes) with_time=yes ;; + no) with_time=no ;; + esac]) + +if test "$with_time" = yes; then + if test "$ac_cv_func_setitimer" = "yes"; then + TARGETS="$TARGETS time.$SO" + else + echo "WARNING: no setitimer(); dropping time.pl from targets" + fi +fi + +if test "$ac_cv_func_getrlimit" = "yes"; then + TARGETS="$TARGETS rlimit.$SO" +else + "WARNING: no getrlimit(); dropping rlimit.pl from targets" +fi + +PLTARGETS=`echo $TARGETS | sed -e "s/\.$SO/.pl/g" -e "s/files.pl/filesex.pl/"` +if echo "$PLTARGETS" | grep socket.pl 2>&1 >/dev/null; then + PLTARGETS="$PLTARGETS streampool.pl" +fi + +AC_OUTPUT(Makefile) + + + diff --git a/packages/clib/crypt.c b/packages/clib/crypt.c new file mode 100644 index 000000000..16e41cd31 --- /dev/null +++ b/packages/clib/crypt.c @@ -0,0 +1,165 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2010, University of Amsterdam, VU Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef DEFINE_XOPEN_SOURCE +#define _XOPEN_SOURCE +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_CRYPT_H +#include +#else +extern char *crypt(const char *key, const char *setting); +#endif +#include +#include +#include +#include +#include "clib.h" + +/* md5passwd.c */ +extern char *md5_crypt(const char *pw, const char *salt); + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Simple interface to the Unix password encryption routine. Implemented +for providing authorization in the multi-threaded Prolog based HTTP +deamon and therefore providing a thread-safe interface. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef _REENTRANT +#include + +static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER; +#define LOCK() pthread_mutex_lock(&crypt_mutex) +#define UNLOCK() pthread_mutex_unlock(&crypt_mutex) +#else +#define LOCK() +#define UNLOCK() +#endif + + +static foreign_t +pl_crypt(term_t passwd, term_t encrypted) +{ char *pw, *e; + char salt[20]; + + if ( !PL_get_chars(passwd, &pw, CVT_ATOM|CVT_STRING|CVT_LIST|BUF_RING) ) + return pl_error("crypt", 2, NULL, ERR_ARGTYPE, + 1, passwd, "text"); + + if ( PL_get_chars(encrypted, &e, CVT_ATOM|CVT_STRING|CVT_LIST|BUF_RING) ) + { char *s2; + + if ( strncmp(e, "$1$", 3) == 0 ) /* MD5 Hash */ + { char *p = strchr(e+3, '$'); + size_t slen; + + if ( p && (slen=(size_t)(p-e-3)) < sizeof(salt) ) + { strncpy(salt, e+3, slen); + salt[slen] = 0; + s2 = md5_crypt(pw, salt); + return (strcmp(s2, e) == 0) ? TRUE : FALSE; + } else + { Sdprintf("No salt???\n"); + return FALSE; + } + } else + { int rval; + + salt[0] = e[0]; + salt[1] = e[1]; + salt[2] = '\0'; + + LOCK(); + s2 = crypt(pw, salt); + rval = (strcmp(s2, e) == 0 ? TRUE : FALSE); + UNLOCK(); + + return rval; + } + } else + { term_t tail = PL_copy_term_ref(encrypted); + term_t head = PL_new_term_ref(); + int slen = 2; + int n; + int (*unify)(term_t t, const char *s) = PL_unify_list_codes; + char *s2; + int rval; + + for(n=0; n=0 && i<=255 ) + { salt[n] = i; + } else if ( PL_get_atom_chars(head, &t) && t[1] == '\0' ) + { salt[n] = t[0]; + unify = PL_unify_list_chars; + } else + { return pl_error("crypt", 2, NULL, ERR_ARGTYPE, + 2, head, "character"); + } + + if ( n == 1 && salt[0] == '$' && salt[1] == '1' ) + slen = 3; + else if ( n == 2 && salt[2] == '$' ) + slen = 8+3; + } else + break; + } + + for( ; n < slen; n++ ) + { int c = 'a'+(int)(26.0*rand()/(RAND_MAX+1.0)); + + if ( rand() & 0x1 ) + c += 'A' - 'a'; + + salt[n] = c; + } + salt[n] = 0; + LOCK(); + if ( slen > 2 ) + { s2 = md5_crypt(pw, salt); + } else + { s2 = crypt(pw, salt); + } + rval = (*unify)(encrypted, s2); + UNLOCK(); + + return rval; + } +} + + +install_t +install_crypt() +{ PL_register_foreign("crypt", 2, pl_crypt, 0); +} diff --git a/packages/clib/crypt.pl b/packages/clib/crypt.pl new file mode 100644 index 000000000..ab0dbfb8d --- /dev/null +++ b/packages/clib/crypt.pl @@ -0,0 +1,41 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(crypt, + [ crypt/2 + ]). + +:- use_foreign_library(foreign(crypt), install_crypt). + +% crypt(+Passwd, ?Encripted). +% +% Used to test an encrypted passwd or create one. In the latter +% case, the first 2 letter must be instantiated diff --git a/packages/clib/demo/cgidemo.pl b/packages/clib/demo/cgidemo.pl new file mode 100644 index 000000000..76d192305 --- /dev/null +++ b/packages/clib/demo/cgidemo.pl @@ -0,0 +1,29 @@ +#!/usr/bin/pl -q -g main -s +/* $Id$ + + Part of SWI-Prolog + + This example code is in the public domain +*/ + +:- use_module(library(cgi)). + +main :- + cgi_get_form(Arguments), + format('Content-type: text/html~n~n', []), + format('~n', []), + format('~n', []), + format('Simple SWI-Prolog CGI script output~n', []), + format('~n~n', []), + format('~n', []), + format('

Form arguments

'), + format('

', []), + print_args(Arguments), + format('~n~n', []), + halt. + +print_args([]). +print_args([A0|T]) :- + A0 =.. [Name, Value], + format('~w=~w
~n', [Name, Value]), + print_args(T). diff --git a/packages/clib/demo/fork.pl b/packages/clib/demo/fork.pl new file mode 100644 index 000000000..9dd5a1be8 --- /dev/null +++ b/packages/clib/demo/fork.pl @@ -0,0 +1,33 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi.psy.uva.nl/projects/SWI-Prolog/ + Copying: GPL-2. See the file COPYING or http://www.gnu.org + + Copyright (C) 1990-2001 SWI, University of Amsterdam. All rights reserved. +*/ + +:- use_module(library(unix)). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Simple demo illustrating the combination of fork/1 and pipe/2 to make +Prolog fork a child to do some work and get back when done. Using +wait_for_input/3 you can make the main Prolog task wait for multiple +childs to return results. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +fork_demo(Result) :- + pipe(Read, Write), + fork(Pid), + ( Pid == child + -> close(Read), + format(Write, '~q.~n', [hello(world)]), + flush_output(Write), % stream is fully buffered! + halt + ; close(Write), + read(Read, Result), + close(Read) + ). diff --git a/packages/clib/demo/pipe.pl b/packages/clib/demo/pipe.pl new file mode 100644 index 000000000..bb14faa0c --- /dev/null +++ b/packages/clib/demo/pipe.pl @@ -0,0 +1,60 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi.psy.uva.nl/projects/SWI-Prolog/ + Copying: GPL-2. See the file COPYING or http://www.gnu.org + + Copyright (C) 1990-2000 SWI, University of Amsterdam. All rights reserved. +*/ + +:- module(subcommand, + [ pipe_through_command/3 % +Command, +In, -Out + ]). +:- use_module(library(unix)). + +% pipe_through_command(+Command, +In, -Out) +% +% Pipe text In through command Command and put the output of command +% in Out. +% +% Example: +% +% ?- pipe_through_command(tr('a-z', 'A-Z'), hello, X) +% +% X = 'HELLO' + +pipe_through_command(Command, In, Out) :- + pipe(ChildIn, MeOut), + pipe(MeIn, ChildOut), + fork(Pid), + ( Pid == child, + close(MeOut), + close(MeIn), + dup(ChildIn, 0), + dup(ChildOut, 1), + close(ChildIn), + close(ChildOut), + exec(Command) + ; close(ChildIn), + close(ChildOut), + write(MeOut, In), + close(MeOut), + read_input(MeIn, Out), + close(MeIn), + wait(Pid, _Status) % avoid zombi + ). + + +read_input(In, Atom) :- + get_code(In, C0), + read_input(C0, In, Codes), + atom_codes(Atom, Codes). + +read_input(-1, _, []) :- !. +read_input(C, In, [C|T]) :- + get_code(In, C1), + read_input(C1, In, T). + diff --git a/packages/clib/demo/win.pl b/packages/clib/demo/win.pl new file mode 100644 index 000000000..34c14e695 --- /dev/null +++ b/packages/clib/demo/win.pl @@ -0,0 +1,117 @@ +/* $Id$ + + Part of SWI-Prolog + + This example code is in the public domain +*/ + +:- asserta(library_directory('.')). +:- asserta(user:file_search_path(foreign, '.')). +:- use_module(library(socket)). + + /******************************* + * SOCKET (CLIENT) * + *******************************/ + +get_http_data(Host, URL) :- + tcp_socket(Socket), + tcp_connect(Socket, Host:80), + tcp_open_socket(Socket, Read, Write), + format(Write, 'GET ~w~n~n', URL), + flush_output(Write), + copy_stream(Read, user_output), + close(Read), + close(Write). + +copy_stream(In, Out) :- + get0(In, C0), + copy_stream(C0, In, Out). + +copy_stream(-1, _, _) :- !. +copy_stream(C, In, Out) :- + put(Out, C), + get0(In, C2), + copy_stream(C2, In, Out). + + + /******************************* + * SOCKET (SERVER) * + *******************************/ + +:- dynamic + server/1, + client/2. + +mkserver :- + mkserver(3000). +mkserver(Port) :- + tcp_socket(Socket), + tcp_bind(Socket, Port), + tcp_listen(Socket, 5), + tcp_open_socket(Socket, Read, _), + asserta(server(Read)). + +dispatch :- + repeat, + \+ dispatch1, !. + +dispatch1 :- + findall(C, client(C, _), Clients), + server(Server), + wait_for_input([Server|Clients], Ready, 0), + dispatch(Ready). + +dispatch([]). +dispatch([H|T]) :- + format('Dispatching ~w ... ', [H]), flush, + dispatch_fd(H), + format('ok~n'), + dispatch(T). + +dispatch_fd(Server) :- + server(Server), !, + tcp_accept(Server, ClientSocket, Peer), + format('Connected from ~w~n', [Peer]), + tcp_fcntl(ClientSocket, setfl, nonblock), + tcp_open_socket(ClientSocket, Read, Write), + format(Write, 'Please to meet you!~n', []), + flush_output(Write), + assert(client(Read, Write)). +dispatch_fd(Client) :- + client(Client, Write), + format(Write, 'You typed: ', []), + copy_stream(Client, Write), + ( at_end_of_stream(Client) + -> format('Closing client ~w~n', [Client]), + close(Client), + close(Write), + retractall(client(Client, _)) + ; flush_output(Write) + ). + + /******************************* + * CLIENT * + *******************************/ + +client :- + client(3000). +client(Port) :- + tcp_socket(Socket), + tcp_connect(Socket, localhost:Port), + tcp_open_socket(Socket, In, Out), + format(Out, 'Hello World~n', []), + flush_output(Out), + copy_line(In, user_output), + close(In), + close(Out). + +copy_line(In, Out) :- + get0(In, C0), + copy_line(C0, In, Out). + +copy_line(10, _, _) :- !. +copy_line(C, In, Out) :- + put(Out, C), + get0(In, C2), + copy_line(C2, In, Out). + diff --git a/packages/clib/depcomp b/packages/clib/depcomp new file mode 100755 index 000000000..11e2d3bfe --- /dev/null +++ b/packages/clib/depcomp @@ -0,0 +1,522 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2004-05-31.23 + +# Copyright (C) 1999, 2000, 2003, 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit 0 + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit 0 + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # Dependencies are output in .lo.d with libtool 1.4. + # With libtool 1.5 they are output both in $dir.libs/$base.o.d + # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the + # latter, because the former will be cleaned when $dir.libs is + # erased. + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir$base.o.d" + tmpdepfile3="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + tmpdepfile3="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + elif test -f "$tmpdepfile2"; then + tmpdepfile="$tmpdepfile2" + else + tmpdepfile="$tmpdepfile3" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/packages/clib/error.c b/packages/clib/error.c new file mode 100644 index 000000000..6dcf3ae4b --- /dev/null +++ b/packages/clib/error.c @@ -0,0 +1,209 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2008, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "clib.h" +#include +#include + +int +pl_error(const char *pred, int arity, const char *msg, int id, ...) +{ fid_t fid; + term_t except, formal, swi; + int rc; + va_list args; + + if ( !(fid=PL_open_foreign_frame()) ) + return FALSE; + + except = PL_new_term_ref(); + formal = PL_new_term_ref(); + swi = PL_new_term_ref(); + + va_start(args, id); + switch(id) + { case ERR_ERRNO: + { int err = va_arg(args, int); + const char *action = va_arg(args, const char *); + const char *type = va_arg(args, const char *); + term_t object = va_arg(args, term_t); + + if ( !object ) + object = PL_new_term_ref(); + + msg = strerror(err); + + switch(err) + { case ENOMEM: + rc = PL_unify_term(formal, + CompoundArg("resource_error", 1), + AtomArg("no_memory")); + break; + case EACCES: + case EPERM: + { rc = PL_unify_term(formal, + CompoundArg("permission_error", 3), + AtomArg(action), + AtomArg(type), + PL_TERM, object); + break; + } + case ENOENT: + case ESRCH: + { rc = PL_unify_term(formal, + CompoundArg("existence_error", 2), + AtomArg(type), + PL_TERM, object); + break; + } + default: + rc = PL_unify_atom_chars(formal, "system_error"); + break; + } + break; + } + case ERR_ARGTYPE: + { int argn = va_arg(args, int); + term_t actual = va_arg(args, term_t); + atom_t expected = PL_new_atom(va_arg(args, const char*)); + + if ( PL_is_variable(actual) && expected != PL_new_atom("variable") ) + rc = PL_unify_atom_chars(formal, "instantiation_error"); + else + rc = PL_unify_term(formal, + CompoundArg("type_error", 2), + PL_ATOM, expected, + PL_TERM, actual); + break; + } + case ERR_TYPE: + { term_t actual = va_arg(args, term_t); + atom_t expected = PL_new_atom(va_arg(args, const char*)); + + if ( PL_is_variable(actual) && expected != PL_new_atom("variable") ) + rc = PL_unify_atom_chars(formal, "instantiation_error"); + else + rc = PL_unify_term(formal, + CompoundArg("type_error", 2), + PL_ATOM, expected, + PL_TERM, actual); + break; + } + case ERR_DOMAIN: + { term_t actual = va_arg(args, term_t); + atom_t expected = PL_new_atom(va_arg(args, const char*)); + + rc = PL_unify_term(formal, + CompoundArg("domain_error", 2), + PL_ATOM, expected, + PL_TERM, actual); + break; + } + case ERR_EXISTENCE: + { const char *type = va_arg(args, const char *); + term_t obj = va_arg(args, term_t); + + rc = PL_unify_term(formal, + CompoundArg("existence_error", 2), + PL_CHARS, type, + PL_TERM, obj); + + break; + } + case ERR_PERMISSION: + { term_t obj = va_arg(args, term_t); + const char *op = va_arg(args, const char *); + const char *objtype = va_arg(args, const char *); + + rc = PL_unify_term(formal, + CompoundArg("permission_error", 3), + AtomArg(op), + AtomArg(objtype), + PL_TERM, obj); + break; + } + case ERR_NOTIMPLEMENTED: + { const char *op = va_arg(args, const char *); + term_t obj = va_arg(args, term_t); + + rc = PL_unify_term(formal, + CompoundArg("not_implemented", 2), + AtomArg(op), + PL_TERM, obj); + } + case ERR_RESOURCE: + { const char *res = va_arg(args, const char *); + + rc = PL_unify_term(formal, + CompoundArg("resource_error", 1), + AtomArg(res)); + } + case ERR_SYNTAX: + { const char *culprit = va_arg(args, const char *); + + rc = PL_unify_term(formal, + CompoundArg("syntax_error", 1), + AtomArg(culprit)); + } + default: + assert(0); + } + va_end(args); + + if ( rc && (pred || msg) ) + { term_t predterm = PL_new_term_ref(); + term_t msgterm = PL_new_term_ref(); + + if ( pred ) + { rc = PL_unify_term(predterm, + CompoundArg("/", 2), + AtomArg(pred), + IntArg(arity)); + } + if ( msg ) + { rc = PL_put_atom_chars(msgterm, msg); + } + + if ( rc ) + rc = PL_unify_term(swi, + CompoundArg("context", 2), + PL_TERM, predterm, + PL_TERM, msgterm); + } + + if ( rc ) + rc = PL_unify_term(except, + CompoundArg("error", 2), + PL_TERM, formal, + PL_TERM, swi); + + PL_close_foreign_frame(fid); + + if ( rc ) + return PL_raise_exception(except); + + return rc; +} + diff --git a/packages/clib/error.h b/packages/clib/error.h new file mode 100644 index 000000000..e09305898 --- /dev/null +++ b/packages/clib/error.h @@ -0,0 +1,42 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef H_ERROR_INCLUDED +#define H_ERROR_INCLUDED +#include + +#define ERR_ERRNO -1 +#define ERR_TYPE -2 +#define ERR_ARGTYPE -3 +#define ERR_DOMAIN -4 +#define ERR_EXISTENCE -5 +#define ERR_PERMISSION -6 +#define ERR_NOTIMPLEMENTED -7 +#define ERR_RESOURCE -8 +#define ERR_SYNTAX -9 + +int pl_error(const char *name, int arity, + const char *msg, int id, ...); + +#endif /*H_ERROR_INCLUDED*/ diff --git a/packages/clib/files.c b/packages/clib/files.c new file mode 100644 index 000000000..fa34bd5af --- /dev/null +++ b/packages/clib/files.c @@ -0,0 +1,163 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "clib.h" +#include +#include +#include +#ifdef HAVE_UTIME_H +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +static functor_t FUNCTOR_access1; +static functor_t FUNCTOR_modified1; +static functor_t FUNCTOR_changed1; +static atom_t ATOM_now; + +static int +add_time_option(term_t list, functor_t f, time_t time) +{ term_t tail = PL_copy_term_ref(list); + term_t head = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + { if ( PL_unify_functor(head, f) ) + { term_t a = PL_new_term_ref(); + + return (PL_get_arg(1, head, a) && + PL_unify_float(a, (double)time)); + } + } + + if ( PL_unify_list(tail, head, tail) ) + return PL_unify_term(head, PL_FUNCTOR, f, PL_FLOAT, (double)time); + + return FALSE; +} + + +static int +close_list(term_t list) +{ term_t tail = PL_copy_term_ref(list); + term_t head = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + ; + + return PL_unify_nil(tail); +} + + +static int +get_time_option(term_t list, functor_t f, time_t def, time_t *tme) +{ term_t tail = PL_copy_term_ref(list); + term_t head = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + { if ( PL_is_functor(head, f) ) + { term_t a = PL_new_term_ref(); + double f; + + _PL_get_arg(1, head, a); + if ( !PL_get_float(a, &f) ) + { atom_t now; + + if ( PL_get_atom(a, &now) && now == ATOM_now ) + { time(tme); + return TRUE; + } else + return pl_error(NULL, 0, NULL, ERR_TYPE, a, "time"); + } + *tme = (long)f; + return TRUE; + } + } + + *tme = def; + return TRUE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +set_file_time(+Spec, -Old, +New) + Query/set file-times. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static foreign_t +pl_set_time_file(term_t spec, term_t old, term_t new) +{ char *name; + struct stat sbuf; + + if ( !PL_get_file_name(spec, &name, 0) ) + return FALSE; + + if ( stat(name, &sbuf) ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "stat", "file", spec); + + add_time_option(old, FUNCTOR_access1, sbuf.st_atime); + add_time_option(old, FUNCTOR_modified1, sbuf.st_mtime); + add_time_option(old, FUNCTOR_changed1, sbuf.st_ctime); + close_list(old); + + if ( !PL_get_nil(new) ) +#ifdef HAVE_UTIME + { struct utimbuf tbuf; + + if ( !get_time_option(new, FUNCTOR_access1, + sbuf.st_atime, &tbuf.actime) ) + return FALSE; + if ( !get_time_option(new, FUNCTOR_modified1, + sbuf.st_mtime, &tbuf.modtime) ) + return FALSE; + + if ( utime(name, &tbuf) != 0 ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "set_time", "file", spec); + } +#else + return pl_error(NULL, 0, NULL, ERR_NOTIMPLEMENTED, "set_time", name); +#endif + + return TRUE; +} + + +install_t +install_files() +{ FUNCTOR_access1 = PL_new_functor(PL_new_atom("access"), 1); + FUNCTOR_modified1 = PL_new_functor(PL_new_atom("modified"), 1); + FUNCTOR_changed1 = PL_new_functor(PL_new_atom("changed"), 1); + ATOM_now = PL_new_atom("now"); + + PL_register_foreign("set_time_file", 3, pl_set_time_file, 0); +} diff --git a/packages/clib/filesex.pl b/packages/clib/filesex.pl new file mode 100644 index 000000000..f2fdda69e --- /dev/null +++ b/packages/clib/filesex.pl @@ -0,0 +1,40 @@ +/* $Id + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(files_ex, + [ set_time_file/3 + ]). + +:- use_foreign_library(foreign(files), install_files). + +% set_time_file(+File, -OldTimes, +NewTimes) +% + diff --git a/packages/clib/form.c b/packages/clib/form.c new file mode 100644 index 000000000..b8d3bc65a --- /dev/null +++ b/packages/clib/form.c @@ -0,0 +1,395 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2007, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include "form.h" +#ifdef __WINDOWS__ +#include +#endif + +#include "error.h" + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Breaks a string holding data from a WWW form into its values. Outputs a +sequence of NAME=VALUE commands for a shell. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static int +dehex(int chr) +{ chr &= 0xff; + + if ( chr >= '0' && chr <= '9' ) + return chr - '0'; + if ( chr >= 'A' && chr <= 'F' ) + return chr - 'A' + 10; + if ( chr >= 'a' && chr <= 'f' ) + return chr - 'a' + 10; + + return -1; +} + + +static size_t +form_argument_decode(const char *in, size_t inlen, char *out, size_t outlen) +{ const char *ein = in+inlen; + size_t written = 0; + + for(; in < ein; in++) + { switch(*in) + { case '+': + if ( ++written < outlen ) + *out++ = ' '; + break; + case '%': + if ( in+2 < ein ) + { int h1 = dehex(*(++in)); + int h2 = dehex(*(++in)); + + if ( h1 < 0 || h2 < 0 ) + return (size_t)-1; + + if ( ++written < outlen ) + *out++ = h1<<4|h2; + } else + return (size_t)-1; /* syntax error */ + break; + default: + if ( ++written < outlen ) + *out++ = *in; + break; + } + } + + if ( written < outlen ) + *out++ = '\0'; + + return written; +} + + +#define SHORTVALUE 512 + +int +break_form_argument(const char *formdata, + int (*func)(const char* name, + size_t namelen, + const char *value, + size_t valuelen, + void *closure), + void *closure) +{ while ( *formdata ) + { char value[SHORTVALUE]; + char *eq = strchr(formdata, '='); + + if ( eq ) + { size_t nlen = eq-formdata; + char *end; + size_t vlen; + + eq++; + end = strchr(eq, '&'); + if ( !end ) + end = eq+strlen(eq); /* end of the string */ + + if ( (vlen=form_argument_decode(eq, end-eq, value, SHORTVALUE)) >= SHORTVALUE ) + { char *buf; + + if ( (buf=malloc(vlen+1)) ) + { size_t vlen2 = form_argument_decode(eq, end-eq, buf, vlen+1); + int rc; + + assert(vlen2 == vlen); + rc = (func)(formdata, nlen, buf, vlen2, closure); + free(buf); + + if ( !rc ) + return rc; + } else + return ERROR_NOMEM; + } else if ( vlen == (size_t)-1 ) + { return ERROR_SYNTAX_ERROR; + } else + { int rc = (func)(formdata, nlen, value, vlen, closure); + + if ( !rc ) + return rc; + } + + if ( *end ) + formdata = end+1; + else + formdata = end; + } + } + + return TRUE; +} + + +static char * +find_boundary(const char *data, const char *end, const char *boundary) +{ size_t blen = strlen(boundary); + + while ( data < end && + !(strncmp(data, boundary, blen) == 0) ) + data++; + + if ( data < end ) + { while(data[-1] == '-') + data--; + return (char *)data; + } + + return NULL; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Find a named attribute in a mime header of a multipart form +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static char * +attribute_of_multipart_header(const char *name, char *header, char *endheader) +{ char *value; + size_t nlen = strlen(name); + + while( header < endheader && + !(header[nlen] == '=' && strncmp(header, name, nlen) == 0) ) + header++; + + if ( header < endheader ) + { header += nlen+1; + + if ( header[0] == '"' ) + { char *end; + + value = ++header; + if ( (end = strchr(value, '"')) ) + { *end = '\0'; + return value; + } + } else + { char *end; + + value = header; + + for(end=header; *end && isalnum(*end&0xff); end++) + ; + *end = '\0'; + return value; + } + } + + return NULL; +} + + +static char * +looking_at_blank_lines(const char *line, int n) +{ while(n-- > 0) + { if ( (line[0] == '\r' && line[1] == '\n') ) + line += 2; + else if ( line[0] == '\n' ) + line += 1; + else + return NULL; + } + + return (char *)line; +} + + +char * +next_line(const char *in) +{ if ( (in = strchr(in, '\n')) ) + return (char *)(in+1); + + return NULL; +} + + +int +break_multipart(char *formdata, size_t len, + const char *boundary, + int (*func)(const char *name, + size_t namelen, + const char *value, + size_t valuelen, + const char *filename, + void *closure), + void *closure) +{ char *enddata = formdata+len; + + while(formdata < enddata) + { char *header; + char *name, *filename; + char *data = NULL; + char *end; + + if ( !(formdata=find_boundary(formdata, enddata, boundary)) || + !(formdata=next_line(formdata)) ) + break; + + header = formdata; + /* find the end of the header */ + for( ; formdata < enddata; formdata++ ) + { char *end; + + if ( (end = looking_at_blank_lines(formdata, 2)) ) + { formdata[0] = '\0'; + formdata = data = end; + break; + } + } + + if ( !data ) + break; + + if ( !(name = attribute_of_multipart_header("name", header, data)) ) + { term_t t = PL_new_term_ref(); + PL_put_atom_chars(t, "name"); + + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, "field", t); + } + filename = attribute_of_multipart_header("filename", header, data); + + if ( !(formdata=find_boundary(data, enddata, boundary)) ) + break; + end = formdata-1; + if ( end[-1] == '\r' ) + end--; + end[0] = '\0'; + + if ( !(func)(name, strlen(name), data, end-data, filename, closure) ) + return FALSE; + } + + return TRUE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Get the raw data from the standard input or QUERY_STRING. If `lenp' is +provided, it is filled with the length of the contents. The input value +for lenp is the maximum acceptable content-length. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +int +get_raw_form_data(char **data, size_t *lenp, int *must_free) +{ char *method; + char *s; + + if ( (method = getenv("REQUEST_METHOD")) && + strcmp(method, "POST") == 0 ) + { char *lenvar = getenv("CONTENT_LENGTH"); + char *q; + long len; + + if ( !lenvar ) + { term_t env = PL_new_term_ref(); + PL_put_atom_chars(env, "CONTENT_LENGTH"); + + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, "environment", env); + } + len = atol(lenvar); + if ( len < 0 ) + { term_t t = PL_new_term_ref(); + + if ( !PL_put_integer(t, len) ) + return FALSE; + return pl_error(NULL, 0, "< 0", ERR_DOMAIN, t, "content_length"); + } + if ( lenp ) + { if ( *lenp && (size_t)len > *lenp ) + { term_t t = PL_new_term_ref(); + char msg[100]; + + if ( !PL_put_integer(t, len) ) + return FALSE; + sprintf(msg, "> %ld", *lenp); + + return pl_error(NULL, 0, msg, ERR_DOMAIN, t, "content_length"); + } + *lenp = len; + } + + q = s = malloc(len+1); + if ( !q ) + return pl_error(NULL, 0, NULL, ERR_RESOURCE, "memory"); + while(len > 0) + { int done; + + while( (done=read(fileno(stdin), q, len)) > 0 ) + { q+=done; + len-=done; + } + if ( done < 0 ) + { int e; + term_t obj; + + no_data: + e = errno; + obj = PL_new_term_ref(); + + free(s); + PL_put_nil(obj); + return pl_error(NULL, 0, NULL, ERR_ERRNO, e, "read", "cgi_data", obj); + } + } + if ( len == 0 ) + { *q = '\0'; + *data = s; + *must_free = TRUE; + return TRUE; + } else + goto no_data; + } else if ( (s = getenv("QUERY_STRING")) ) + { if ( lenp ) + *lenp = strlen(s); + *data = s; + *must_free = FALSE; + return TRUE; + } else + { term_t env = PL_new_term_ref(); + PL_put_atom_chars(env, "QUERY_STRING"); + + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, "environment", env); + } +} + + diff --git a/packages/clib/form.h b/packages/clib/form.h new file mode 100644 index 000000000..efc54e14d --- /dev/null +++ b/packages/clib/form.h @@ -0,0 +1,57 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define MAXNAME 256 + +#define ERROR_NAME_TOO_LONG -1 +#define ERROR_SYNTAX_ERROR -2 +#define ERROR_NOMEM -3 + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +typedef struct +{ char *ptr; + char *name; +} form_arg; + +/* form.c */ +int break_form_argument(const char *formdata, + int (*func)(const char *name, + size_t namelen, + const char *value, + size_t valuelen, + void *closure), void *closure); +int break_multipart(char *formdata, size_t len, + const char *boundary, + int (*func)(const char *name, + size_t namelen, + const char *value, + size_t valuelen, + const char *filename, + void *closure), + void *closure); +int get_raw_form_data(char **data, size_t *lenp, int *must_free); diff --git a/packages/clib/install-sh b/packages/clib/install-sh new file mode 100755 index 000000000..ab74c882e --- /dev/null +++ b/packages/clib/install-sh @@ -0,0 +1,238 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# 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. +# + + +# 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}" + +tranformbasename="" +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/packages/clib/maildrop/COPYING b/packages/clib/maildrop/COPYING new file mode 100644 index 000000000..b10a7641b --- /dev/null +++ b/packages/clib/maildrop/COPYING @@ -0,0 +1,3 @@ +This software is released under the GPL, version 2 (see COPYING.GPL). +Additionally, compiling, linking, and/or using the OpenSSL toolkit in +conjunction with this software is allowed. diff --git a/packages/clib/maildrop/COPYING.GPL b/packages/clib/maildrop/COPYING.GPL new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/packages/clib/maildrop/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/packages/clib/maildrop/LICENSE.MAIL b/packages/clib/maildrop/LICENSE.MAIL new file mode 100644 index 000000000..b36bbbbc8 --- /dev/null +++ b/packages/clib/maildrop/LICENSE.MAIL @@ -0,0 +1,67 @@ +From mrsam@courier-mta.com Mon May 23 03:56:05 2005 +Received: from mail.courier-mta.com [216.254.115.84] + by smtp.science.uva.nl with ESMTP (sendmail 8.11.6p2/config 11.35). + id j4N1u1l31610; Mon, 23 May 2005 03:56:01 +0200 +Received: from localhost (localhost [127.0.0.1]) + (uid 8) + by commodore.email-scan.com with local; Sun, 22 May 2005 21:56:05 -0400 + id 0000000000137668.0000000042913835.00006534 +X-IMAP-Sender: mrsam@courier-mta.com +References: <200505222138.13486.wielemak@science.uva.nl> +Message-ID: +X-Mailer: http://www.courier-mta.org/cone/ +From: Sam Varshavchik +To: Jan Wielemaker +X-PGP-KEY: http://www.courier-mta.org/KEYS.bin +Subject: Re: Use of maildrop rfc822 and rfc2047 libraries in SWI-Prolog +Date: Sun, 22 May 2005 21:56:05 -0400 +Mime-Version: 1.0 +Content-Type: multipart/signed; + boundary="=_mimegpg-commodore.email-scan.com-24916-1116813365-0003"; + micalg=pgp-sha1; + protocol="application/pgp-signature" +X-Virus-Scanned: by amavisd-new +X-Spam-Status: No, hits=0.0, required=5.0, tests=BAYES_50 +X-Spam-Rating: 0 +X-UID: 13043 +X-Length: 2555 + +This is a MIME GnuPG-signed message. If you see this text, it means that +your E-mail or Usenet software does not support MIME signed messages. + +--=_mimegpg-commodore.email-scan.com-24916-1116813365-0003 +Content-Type: text/plain; format=flowed; charset="US-ASCII" +Content-Disposition: inline +Content-Transfer-Encoding: 7bit + +Jan Wielemaker writes: + +> Now the trouble is that your libraries are GPL, while the core of +> SWI-Prolog and all its core packages are LGPL. In theory, loading +> the mime library, which causes your code to be loaded as a shared +> object, turns the entire process with whatever the user has added +> to it to GPL. This is undesirable. +> +> I would like to ask permission to either distribute these libraries +> under the LGPL or make a statement that allows use with SWI-Prolog +> without turning everything to GPL. + +The current versions of librfc822 and librfc2047 may be distributed under +the terms of LGPL 2.1 only as part of, and in conjunction with SWI-Prolog. + + + +--=_mimegpg-commodore.email-scan.com-24916-1116813365-0003 +Content-Type: application/pgp-signature +Content-Transfer-Encoding: 7bit + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.2.4 (GNU/Linux) + +iD8DBQBCkTg1x9p3GYHlUOIRAnbaAJ9atylLK74/CO/oZ2x4U0hZPhLYaACdH/Ub +ocEI7RDpO9vBq26cnyw1UFE= +=mXhm +-----END PGP SIGNATURE----- + +--=_mimegpg-commodore.email-scan.com-24916-1116813365-0003-- + diff --git a/packages/clib/maildrop/README b/packages/clib/maildrop/README new file mode 100644 index 000000000..d76b57565 --- /dev/null +++ b/packages/clib/maildrop/README @@ -0,0 +1,16 @@ +This directory contains the subdirectories rfc822 and rfc2045 from the +maildrop system (version 1.5.3). They are included with the SWI-Prolog +package source to simplify building the package. + +maildrop is written by: + + Sam Varshavchik + Double Precision, Inc. + PO Box 637 + Harriman, NY 10926-0637 + +Although initially distributed under GPL, Sam gave permission to +redistribute the library with SWI-Prolog under the LGPL. See file +LICENSE.MAIL in this directory. + + diff --git a/packages/clib/maildrop/rfc2045/Makefile b/packages/clib/maildrop/rfc2045/Makefile new file mode 100644 index 000000000..a76703850 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/Makefile @@ -0,0 +1,38 @@ +################################################################ +# Makefile for librfc2045.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=../../../swipl-ld.sh +CFLAGS=-fPIC -Wall -I./.. -DHAVE_CONFIG_H +LIBS= +AR=ar +RANLIB=ranlib + +OBJ= rfc2045.o rfc2045acchk.o rfc2045acprep.o \ + rfc2045appendurl.o rfc2045cdecode.o rfc2045decode.o \ + rfc2045enomem.o \ + rfc2045_base64encode.o rfc2045_fromfd.o \ + rfc2045find.o rfc2045mkboundary.o rfc2045rewrite.o \ + rfc2045tryboundary.o rfc2045xdump.o + +all: librfc2045.a + +librfc2045.a: $(OBJ) + rm -f librfc2045.a + $(AR) r librfc2045.a $(OBJ) + $(RANLIB) librfc2045.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc2045.a + rm -f rfc2045charset.h stamp-h1 + rm -rf autom4te.cache diff --git a/packages/clib/maildrop/rfc2045/Makefile.in b/packages/clib/maildrop/rfc2045/Makefile.in new file mode 100644 index 000000000..867f47239 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/Makefile.in @@ -0,0 +1,48 @@ +################################################################ +# Makefile for librfc2045.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ + +ifeq (@PROLOG_SYSTEM@,yap) + +srcdir=@srcdir@ + +SHLIB_CFLAGS=@SHLIB_CFLAGS@ + +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) -I$(srcdir) -I$(srcdir)/.. $(SHLIB_CFLAGS) $< -o $@ +endif + +OBJ= rfc2045.o rfc2045acchk.o rfc2045acprep.o \ + rfc2045appendurl.o rfc2045cdecode.o rfc2045decode.o \ + rfc2045enomem.o \ + rfc2045_base64encode.o rfc2045_fromfd.o \ + rfc2045find.o rfc2045mkboundary.o rfc2045rewrite.o \ + rfc2045tryboundary.o rfc2045xdump.o + +all: librfc2045.a + +librfc2045.a: $(OBJ) + rm -f librfc2045.a + $(AR) r librfc2045.a $(OBJ) + $(RANLIB) librfc2045.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc2045.a + rm -f rfc2045charset.h stamp-h1 + rm -rf autom4te.cache diff --git a/packages/clib/maildrop/rfc2045/Makefile.in~ b/packages/clib/maildrop/rfc2045/Makefile.in~ new file mode 100644 index 000000000..54060c828 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/Makefile.in~ @@ -0,0 +1,48 @@ +################################################################ +# Makefile for librfc2045.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ + +ifeq (@PROLOG_SYSTEM@,yap) + +srcdir=@srcdir@ + +SHLIB_CFLAGS=@SHLIB_CFLAGS@ + +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $< -o $@ +endif + +OBJ= rfc2045.o rfc2045acchk.o rfc2045acprep.o \ + rfc2045appendurl.o rfc2045cdecode.o rfc2045decode.o \ + rfc2045enomem.o \ + rfc2045_base64encode.o rfc2045_fromfd.o \ + rfc2045find.o rfc2045mkboundary.o rfc2045rewrite.o \ + rfc2045tryboundary.o rfc2045xdump.o + +all: librfc2045.a + +librfc2045.a: $(OBJ) + rm -f librfc2045.a + $(AR) r librfc2045.a $(OBJ) + $(RANLIB) librfc2045.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc2045.a + rm -f rfc2045charset.h stamp-h1 + rm -rf autom4te.cache diff --git a/packages/clib/maildrop/rfc2045/Makefile.mak b/packages/clib/maildrop/rfc2045/Makefile.mak new file mode 100644 index 000000000..e87d8df6c --- /dev/null +++ b/packages/clib/maildrop/rfc2045/Makefile.mak @@ -0,0 +1,35 @@ +# Destinations. Please edit +prefix=c:\Documents and Settings\jan +LIBDIR=$(prefix)\lib64 +INCDIR=$(prefix)\include + +CC=cl.exe +AR=lib.exe +CFLAGS=/MD /W3 /O2 /EHsc /DNDEBUG /D__WINDOWS__ /I.. /nologo /c + +OUT=rfc2045.lib + +OBJ= rfc2045.obj rfc2045acchk.obj rfc2045acprep.obj \ + rfc2045appendurl.obj rfc2045cdecode.obj rfc2045decode.obj \ + rfc2045enomem.obj \ + rfc2045_base64encode.obj rfc2045_fromfd.obj \ + rfc2045find.obj rfc2045mkboundary.obj rfc2045rewrite.obj \ + rfc2045tryboundary.obj rfc2045xdump.obj + +.c.obj: + @$(CC) $(CFLAGS) /Fo$@ $< + +$(OUT): $(OBJ) + del $@ + $(AR) /out:$@ /nologo $(OBJ) + +install: $(OUT) + copy $(OUT) "$(LIBDIR)" + copy rfc2045.h "$(INCDIR)" + +clean:: + del *~ *.obj + +distclean: clean + del $(OUT) + diff --git a/packages/clib/maildrop/rfc2045/aclocal.m4 b/packages/clib/maildrop/rfc2045/aclocal.m4 new file mode 100644 index 000000000..5f6395127 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/aclocal.m4 @@ -0,0 +1,1044 @@ +# generated automatically by aclocal 1.9.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.1])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 6 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# serial 7 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 7 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/packages/clib/maildrop/rfc2045/config.h b/packages/clib/maildrop/rfc2045/config.h new file mode 100644 index 000000000..9db2a3000 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/config.h @@ -0,0 +1,106 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define if gethostname() is provided */ +#define HAS_GETHOSTNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Specify package */ +#define RFC2045PKG "" + +/* Specify version */ +#define RFC2045VER "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/packages/clib/maildrop/rfc2045/config.h.in b/packages/clib/maildrop/rfc2045/config.h.in new file mode 100644 index 000000000..94ee985a6 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/config.h.in @@ -0,0 +1,105 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define if gethostname() is provided */ +#undef HAS_GETHOSTNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Specify package */ +#undef RFC2045PKG + +/* Specify version */ +#undef RFC2045VER + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/packages/clib/maildrop/rfc2045/config.log b/packages/clib/maildrop/rfc2045/config.log new file mode 100644 index 000000000..46018408f --- /dev/null +++ b/packages/clib/maildrop/rfc2045/config.log @@ -0,0 +1,810 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = xato +uname -m = x86_64 +uname -r = 2.6.32-22-generic +uname -s = Linux +uname -v = #33-Ubuntu SMP Wed Apr 28 13:28:05 UTC 2010 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/vsc/Yap/Prologs/pl-devel/bin +PATH: /home/vsc/bin +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /sbin +PATH: /bin +PATH: /usr/games +PATH: /home/vsc/lgtsvn/xml +PATH: /home/vsc/lgtsvn/scripts +PATH: /home/vsc/lgtsvn/integration + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2175: checking for gcc +configure:2202: result: ../../../swipl-ld.sh +configure:2431: checking for C compiler version +configure:2440: ../../../swipl-ld.sh --version >&5 +gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 +Copyright (C) 2009 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2451: $? = 0 +configure:2440: ../../../swipl-ld.sh -v >&5 +Using built-in specs. +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) +configure:2451: $? = 0 +configure:2440: ../../../swipl-ld.sh -V >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2451: $? = 1 +configure:2440: ../../../swipl-ld.sh -qversion >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2451: $? = 1 +configure:2471: checking whether the C compiler works +configure:2493: ../../../swipl-ld.sh -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2497: $? = 0 +configure:2546: result: yes +configure:2549: checking for C compiler default output file name +configure:2551: result: a.out +configure:2557: checking for suffix of executables +configure:2564: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2568: $? = 0 +configure:2590: result: +configure:2612: checking whether we are cross compiling +configure:2620: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2624: $? = 0 +configure:2631: ./conftest +configure:2635: $? = 0 +configure:2650: result: no +configure:2655: checking for suffix of object files +configure:2677: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2681: $? = 0 +configure:2702: result: o +configure:2706: checking whether we are using the GNU C compiler +configure:2725: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2725: $? = 0 +configure:2734: result: yes +configure:2743: checking whether ../../../swipl-ld.sh accepts -g +configure:2763: ../../../swipl-ld.sh -c -g conftest.c >&5 +configure:2763: $? = 0 +configure:2804: result: yes +configure:2821: checking for ../../../swipl-ld.sh option to accept ISO C89 +configure:2885: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2885: $? = 0 +configure:2898: result: none needed +configure:2920: checking for ar +configure:2936: found /usr/bin/ar +configure:2948: result: ar +configure:2999: checking for ranlib +configure:3015: found /usr/bin/ranlib +configure:3026: result: ranlib +configure:3055: checking how to run the C preprocessor +configure:3086: ../../../swipl-ld.sh -E conftest.c +configure:3086: $? = 0 +configure:3100: ../../../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3100: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3125: result: ../../../swipl-ld.sh -E +configure:3145: ../../../swipl-ld.sh -E conftest.c +configure:3145: $? = 0 +configure:3159: ../../../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3159: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3188: checking for grep that handles long lines and -e +configure:3246: result: /bin/grep +configure:3251: checking for egrep +configure:3313: result: /bin/grep -E +configure:3318: checking for ANSI C header files +configure:3338: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3338: $? = 0 +configure:3411: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3411: $? = 0 +configure:3411: ./conftest +configure:3411: $? = 0 +configure:3422: result: yes +configure:3435: checking for sys/types.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for sys/stat.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for stdlib.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for string.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for memory.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for strings.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for inttypes.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for stdint.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3435: checking for unistd.h +configure:3435: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3435: $? = 0 +configure:3435: result: yes +configure:3449: checking minix/config.h usability +configure:3449: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c:52:26: error: minix/config.h: No such file or directory +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3449: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:3449: result: no +configure:3449: checking minix/config.h presence +configure:3449: ../../../swipl-ld.sh -E conftest.c +conftest.c:19:26: error: minix/config.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3449: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:3449: result: no +configure:3449: checking for minix/config.h +configure:3449: result: no +configure:3470: checking whether it is safe to define __EXTENSIONS__ +configure:3488: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3488: $? = 0 +configure:3495: result: yes +configure:3516: checking for ANSI C header files +configure:3620: result: yes +configure:3631: checking for unistd.h +configure:3631: result: yes +configure:3631: checking sys/wait.h usability +configure:3631: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3631: $? = 0 +configure:3631: result: yes +configure:3631: checking sys/wait.h presence +configure:3631: ../../../swipl-ld.sh -E conftest.c +configure:3631: $? = 0 +configure:3631: result: yes +configure:3631: checking for sys/wait.h +configure:3631: result: yes +configure:3631: checking for strings.h +configure:3631: result: yes +configure:3643: checking for missing gethostname prototype +configure:3666: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c:33: error: conflicting types for 'gethostname' +/usr/include/unistd.h:895: note: previous declaration of 'gethostname' was here +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3666: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_STRINGS_H 1 +| /* end confdefs.h. */ +| +| #if HAVE_UNISTD_H +| #include +| #endif +| +| extern int gethostname(int,int); +| +| int +| main () +| { +| +| +| ; +| return 0; +| } +configure:3676: result: no +configure:3688: checking for an ANSI C-conforming const +configure:3753: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:58: warning: 't' is used uninitialized in this function +conftest.c:74: warning: 'b' may be used uninitialized in this function +configure:3753: $? = 0 +configure:3760: result: yes +configure:3768: checking for off_t +configure:3768: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3768: $? = 0 +configure:3768: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:65: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3768: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAS_GETHOSTNAME 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((off_t))) +| return 0; +| ; +| return 0; +| } +configure:3768: result: yes +configure:3779: checking for size_t +configure:3779: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3779: $? = 0 +configure:3779: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:65: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3779: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAS_GETHOSTNAME 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((size_t))) +| return 0; +| ; +| return 0; +| } +configure:3779: result: yes +configure:3790: checking for pid_t +configure:3790: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3790: $? = 0 +configure:3790: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:65: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3790: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAS_GETHOSTNAME 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((pid_t))) +| return 0; +| ; +| return 0; +| } +configure:3790: result: yes +configure:3802: checking for strncasecmp +configure:3802: ../../../swipl-ld.sh -o conftest -fPIC -Wall conftest.c >&5 +conftest.c:52: warning: conflicting types for built-in function 'strncasecmp' +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3802: $? = 0 +configure:3802: result: yes +configure:3809: checking for strcasecmp +configure:3809: ../../../swipl-ld.sh -o conftest -fPIC -Wall conftest.c >&5 +conftest.c:52: warning: conflicting types for built-in function 'strcasecmp' +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3809: $? = 0 +configure:3809: result: yes +configure:3968: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on xato + +config.status:817: creating Makefile +config.status:817: creating rfc2045charset.h +config.status:817: creating config.h +config.status:978: config.h is unchanged + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_env_CC_set=set +ac_cv_env_CC_value=../../../swipl-ld.sh +ac_cv_env_CFLAGS_set=set +ac_cv_env_CFLAGS_value=-fPIC +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set=set +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_strcasecmp=yes +ac_cv_func_strncasecmp=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_minix_config_h=no +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_sys_wait_h=yes +ac_cv_header_unistd_h=yes +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_GREP=/bin/grep +ac_cv_prog_AR=ar +ac_cv_prog_CPP='../../../swipl-ld.sh -E' +ac_cv_prog_ac_ct_CC=../../../swipl-ld.sh +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_safe_to_define___extensions__=yes +ac_cv_type_off_t=yes +ac_cv_type_pid_t=yes +ac_cv_type_size_t=yes +rfc2045_cv_SYS_GETHOSTNAME=no + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +AR='ar' +CC='../../../swipl-ld.sh' +CFLAGS='-fPIC -Wall -I./..' +CPP='../../../swipl-ld.sh -E' +CPPFLAGS='' +DEFS='-DHAVE_CONFIG_H' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +EXEEXT='' +GREP='/bin/grep' +LDFLAGS='' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +OBJEXT='o' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_URL='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +RANLIB='ranlib' +RFC2045CHARSET='us-ascii' +SHELL='/bin/bash' +ac_ct_CC='../../../swipl-ld.sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +rfc822includedir='' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_URL "" +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define __EXTENSIONS__ 1 +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +#define _POSIX_PTHREAD_SEMANTICS 1 +#define _TANDEM_SOURCE 1 +#define STDC_HEADERS 1 +#define HAVE_UNISTD_H 1 +#define HAVE_SYS_WAIT_H 1 +#define HAVE_STRINGS_H 1 +#define HAS_GETHOSTNAME 1 +#define RFC2045PKG "" +#define RFC2045VER "" + +configure: exit 0 diff --git a/packages/clib/maildrop/rfc2045/configure b/packages/clib/maildrop/rfc2045/configure new file mode 100755 index 000000000..93a84f0a7 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/configure @@ -0,0 +1,5153 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.65. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="rfc2045.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +RFC2045CHARSET +rfc822includedir +EGREP +GREP +CPP +RANLIB +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AR +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_package +with_version +enable_mimecharset +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-mimecharset=charset Default MIME charset to set on new messages + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_type + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers config.h" + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = x""yes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +if test "$GCC" = yes ; then + CXXFLAGS="$CXXFLAGS -Wall" + CFLAGS="$CFLAGS -Wall" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in unistd.h sys/wait.h strings.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for missing gethostname prototype" >&5 +$as_echo_n "checking for missing gethostname prototype... " >&6; } +if test "${rfc2045_cv_SYS_GETHOSTNAME+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if HAVE_UNISTD_H +#include +#endif + +extern int gethostname(int,int); + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + rfc2045_cv_SYS_GETHOSTNAME=yes +else + rfc2045_cv_SYS_GETHOSTNAME=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rfc2045_cv_SYS_GETHOSTNAME" >&5 +$as_echo "$rfc2045_cv_SYS_GETHOSTNAME" >&6; } + +if test $rfc2045_cv_SYS_GETHOSTNAME = "no" +then + +cat >>confdefs.h <<_ACEOF +#define HAS_GETHOSTNAME 1 +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = x""yes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = x""yes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = x""yes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + + +ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" +if test "x$ac_cv_func_strncasecmp" = x""yes; then : + +else + CFLAGS="$CFLAGS -Dstrncasecmp=strnicmp" +fi + +ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" +if test "x$ac_cv_func_strcasecmp" = x""yes; then : + +else + CFLAGS="$CFLAGS -Dstrcasecmp=stricmp" +fi + + + +# Check whether --with-package was given. +if test "${with_package+set}" = set; then : + withval=$with_package; package="$withval" +else + + package="$PACKAGE" + ac_configure_args="$ac_configure_args --with-package=$PACKAGE" + +fi + + + +# Check whether --with-version was given. +if test "${with_version+set}" = set; then : + withval=$with_version; version="$withval" +else + + version="$VERSION" + ac_configure_args="$ac_configure_args --with-version=$VERSION" + +fi + + + +cat >>confdefs.h <<_ACEOF +#define RFC2045PKG "$package" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define RFC2045VER "$version" +_ACEOF + + +# Check whether --enable-mimecharset was given. +if test "${enable_mimecharset+set}" = set; then : + enableval=$enable_mimecharset; RFC2045CHARSET="$enableval" +else + RFC2045CHARSET="us-ascii" +fi + + +CFLAGS="$CFLAGS -I${srcdir}/.." + + + +ac_config_files="$ac_config_files Makefile rfc2045charset.h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "rfc2045charset.h") CONFIG_FILES="$CONFIG_FILES rfc2045charset.h" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + "$ac_file" | "$ac_file":* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for "$ac_file"" >`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/packages/clib/maildrop/rfc2045/configure.in b/packages/clib/maildrop/rfc2045/configure.in new file mode 100644 index 000000000..a3d7f21ae --- /dev/null +++ b/packages/clib/maildrop/rfc2045/configure.in @@ -0,0 +1,82 @@ +dnl $Id$ +dnl +dnl Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +dnl distribution information. +AC_INIT(rfc2045.c) +AC_PREREQ([2.50]) + +AC_CONFIG_HEADER(config.h) +AC_SUBST(AR) + +dnl Checks for programs. +AC_PROG_CC +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB + +AC_USE_SYSTEM_EXTENSIONS + +if test "$GCC" = yes ; then + CXXFLAGS="$CXXFLAGS -Wall" + CFLAGS="$CFLAGS -Wall" +fi + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h sys/wait.h strings.h) + +AC_CACHE_CHECK([for missing gethostname prototype],rfc2045_cv_SYS_GETHOSTNAME, + +AC_TRY_COMPILE([ +#if HAVE_UNISTD_H +#include +#endif + +extern int gethostname(int,int); +],[ +],rfc2045_cv_SYS_GETHOSTNAME=yes,rfc2045_cv_SYS_GETHOSTNAME=no +) + +) + +if test $rfc2045_cv_SYS_GETHOSTNAME = "no" +then + AC_DEFINE_UNQUOTED(HAS_GETHOSTNAME, 1, + [Define if gethostname() is provided]) +fi + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_PID_T + +dnl Checks for library functions. +AC_CHECK_FUNC(strncasecmp,,CFLAGS="$CFLAGS -Dstrncasecmp=strnicmp") +AC_CHECK_FUNC(strcasecmp,,CFLAGS="$CFLAGS -Dstrcasecmp=stricmp") + +AC_ARG_WITH(package, [], package="$withval", + [ + package="$PACKAGE" + ac_configure_args="$ac_configure_args --with-package=$PACKAGE" + ]) + +AC_ARG_WITH(version, [], version="$withval", + [ + version="$VERSION" + ac_configure_args="$ac_configure_args --with-version=$VERSION" + ]) + +AC_DEFINE_UNQUOTED(RFC2045PKG,"$package",[Specify package]) +AC_DEFINE_UNQUOTED(RFC2045VER,"$version",[Specify version]) + +AC_ARG_ENABLE(mimecharset, + [ --enable-mimecharset=charset Default MIME charset to set on new messages], + RFC2045CHARSET="$enableval", RFC2045CHARSET="us-ascii") + +CFLAGS="$CFLAGS -I${srcdir}/.." +AC_SUBST(rfc822includedir) + +AC_SUBST(RFC2045CHARSET) +AC_OUTPUT(Makefile rfc2045charset.h) diff --git a/packages/clib/maildrop/rfc2045/librfc2045.a b/packages/clib/maildrop/rfc2045/librfc2045.a new file mode 100644 index 0000000000000000000000000000000000000000..2707708a78bca486ea0e97954dcfbbb165c295ba GIT binary patch literal 78170 zcmd^o4S1bZmF}0eKq-Y&5TOX_5epQdZCVPnKp`z0I4G3}t=17uLw-o4O+s=`DO?K0 zG)#|&Xhy~9JmT1KM#aB-dmVo&12sS;LA@FUA`>pMrHz!~XEiq+BeP>sRPiNDH`dm|EU01HYGZ)irY~9$@+Sc421CXt; zskuJCA=l7C|0PnqC%D|$o^NZc@4PK$(%9P7(caaXYi(~UW8To-mTPLuwbgGd$)#9b zYh&!)pvI=IhR)UwvYF(zp}y^=eEm(6`D|=FKPG1EAV|3#(QkmjrHIux)HSp;HQXGN zNov*AmlCYLqob*;xp+|bz6(B9Y-=-5!OD0z33u|2RhwY6_-+8Dbs zkPDVJwN+s5J5{FlgKh3?-`HG|qPf)*Y2(dxlM=GC>DJEHTuI4luWQb?m9&%Vylt}2 z&5iku9nqq&fNSYZdMsXAD&JaKobI9eh3$)GDW)3rkUC!vKJH@dAscVDSbCtw%R>+; zpUy%Cg_GT{sTNmPFHWc9-wT#5O{bSES#tgbT2tMXx#r4gRaL04oT-W~jY>8{qiFZy z(tC}()haJ&CG01f9{OfQe3+~TX;HKa7=sp z^Rv`x&iKjh&6DjRk;pN>9uZgu?!(|dlr5|s96uZM!`ULlK_JDo06o6BQ_QtMB1eee zzCB*mhlmeG`F2AKnGql(QEFQ&;sbOfTbv_~1wLSNktkVIdUc$`7@Ff8i<&qp;n?wx z@nGy&$c!S)(I}rPsef$T=~m*@)1T`3H0Gx!;<8_4k}~rn6>S}*x#Yls18VP}{oL5Tbtm~Eb5I`;(Ai5I2|W;yh`pR- zS3n~6a*`bZiP+0Ywg)6)FDK~>NW@-7QnT6eI`zFdNQ@TWu_bV<^&M*i$E@#|EqB~H z8i*zKaSSlr21-Eqsp}LU4h=h{~K&T{^!kl4RK1H{rbDb=Us* zb%*G?xEeuaMy@UlW($vG3qNr|bnl%Xl;A@CxnkzI?U@7F-qlhp9+Wns@Lh{&tmQcn z0FlY>2j2;*2dYZhyJ>|^TJ=ylx$8gxWvI@&`>W!2q>HGNT2Xdos$_d0czFwidPpTQ zX$osc3#*?Se>YU>L@U&yT0pHO>}#tXpW0=JX0}QLtzAa6C~YEY(36y=ri`Y>p)Pw! zJ#v33IgshMK(+aPVCK*q&PvGbzt<((arfSAP%>GeQ6JWu zU}<2!aw!2dP=eSlbye*g4?^SHTT8`G6l!OVzs9++I_et+Q{w0zlE3FNqArq+SZ}Rm zdc#j#jH=Z>U!KKU_mm<>0a^5fe(v}&c!PM%GDK}bT^l{ z-qnDw&)&UnyZCu{vy_Y;_i%+n^1dOG%r0l6Gm4^JU=A=>$;O3D|3GFRWzdR2-Cf*Q zoQvGFXVIU*cfi*mItS7jU|lpAm%EkDNitkfN`U4% z&})65F_wobB#dz1*bh;W^toEDM4TDy&g`RkfXZEHXpjNL1)rq~fM zH-cP^MWblNd87iM#BMt#>`MfC&v3kU52G!02Ll=|Zj8c}bSy#o3Nzqq#N zxMBlIy0`R4xr+i>kREf(q2g8!`B2VSZ}+1>&XK%x;0LfW)ENx*);rWTEsLD-AXFU1 zg~AmVFj!a4ct9$5@b=V(V#?mtNKDCuNK*S%6Hxmvk35)v*V&q2DV83bC69(vDq#l; z=O_QhO2E8kOKIck+(K;@kw*@!VJ9}#vlbGGiddwhvDLnSVS-DB_Vc1}c(*hX0$Zj@ z_56`b))7QxCkKu>^iPyzE5d<(QPvb-N$(z+25gxLUdZeiN9B;&QQS&b)(prUnH{cL z;G3&icOYNvi1I%)f391Gf~!&@v1+6zzpxy7kh7_i(|jg4qe;r_jH#Upkk3vlhpZH) zdQLt9oFsQ*fUhyqJczu>Jjlja8j@jGjk6V2`K;uY0z6pK&iGekq0i5Nwy4oifmP)S z>=Om{l@!RDr!Q7upHpBTMDL>lS!1SpE|pG|6AmrM-y9WZS2uwItwE(F;iscBgfgH= zfz6>g&i5ROHLyLVZhl>~rst6<%Xw^5u*qpL(53ANb`!@#;NQTyNGTO`3SNpS7{nFR@T9o=){~1wQMi-Y`n7w^zFTma% zb3NM;lx5{^{6PE1N_1T7&)4xc7z^aLXS^amu$3HXj35YOmmfy&4j19oXqYm?Ev#h+k>P0vag6N{SPi0T!Z@zDdT;NE$7dUUkbUGI zkHB~d9s2Hx`KfKahoVAleZ?WzoSs8rJ$OL*gHp_`%Iq6IioGB-irwghqE~-$rayHr zr`L*^ec2sWmXWd01KKhiTv69CcmG4)$5xKxzWd{p0B6X7;nt?djJ# zxPWFYvtI_W`!R^+Yz~KXB-+-GDSdyuHivUVh5QQykxehoyl~f1lEmXD6;}%?(@HMv z7hXJYpnRmqNvO3>I+t0?#Di_ zzGLqH$BlePkP!Uxahr1=30fAgX0LI?_@Li~K$-JIuQ$NgnCs$zW>QmgFt5XCcgLo` zq)<6gH8$u*d50P5H_;m(>wQUHKRpv(uS@cp>Up25LOfMLO~tK}q!&q2x_$zZ)G0kT z8#6g0RpXej!b8#_H{WZrMv|MX{CCPbz@xvWa9?p%-DH*gHw*V63g_Cn!_6g6((B)w zW)CZaorjr@u}>y?y{kN1{}-m!BNzk7+`pey;*zS3{N#ysPTx^x6z|^J-}7w`G9zk; zfzjtVLS^;FN#)!*a6=)jkuLt6*rGLovvb<6Hj9?Fyxu%W7{A3NM=6Y2WqYvCK@!Gh z5MrLJZ0Zb^id0SmTel(t$h1)`2rJjDKNF6xFT2p9Gp6!!u3x$``+`o)#kmu7Ca53k zxj3`$uBX5fjhWL_f2^tVTr6DwA+;?lB?j|f(%!D#T^deilu_yf{B$dmGe_eEEKwtS zl8jc8L}un4gHe;jwe1&YMpM0?L1enoUXRb!O5$v5v(8M(xuscGPMjfE_8z+ikm;`)zbPSFYbq*37c?WPIi`(Y_Q`SO`*0n&c@Yokoa_0SpC!$GLKrR z+Bpf6<;B%cf$OmAMx2aNG=5@;{wW8pR<=^x?xx%llk7SK4gtWs?3)`(R;;_pRdN0b z@m<7#7QJdKoh{}k487Y8q!@{r;GSb|!rS@WDvi_{8-BaM&3+d$?;G9PaQA+k4$?u)MI&cNUbcBb$Z1mWz8 zB*`Jmuz0WlsT+HjVU3H4_5?D+;|sboFLJJFL`vd|cl9NC7a_~i2?bet)EY%h=rr=T|H>Sw(8xI{iau|}q)`IVoYpIRAJ=D4^_tm8-7 z+#F|)3)2*r{)_q9T<&MH?*|3R{8XroT+b_iT&b3j%8zs3Qfce5i)_&*8`Xn1VTgKm z()UWgX0Xb%Y)u2cQ9F((RQNul+~ej4O_4xxQE{p2RFWKxgGvRSXqO8tsH>43**?^+ z#}n8bXRYZ7t7{G#MSUQyENgN7Qb<5HdWKXl!fOsgjO2}OAz;vp{ zQ#}rA`*Z>zd6y3bcojYfSUl2I-kocSt$e0OvRTH)*LAJKB#5G|sM|k|nI>tx_9N-% zpj5bqJ3m&;y!gapwnBWtf@mWajJIOJd2UgZYucP!)Ulzywar5tTW@OW%0(NSy1KAv zdlA<0E?crBvK6*bI*Pbfd%>or&MvO@*45Pua<_Ffl`Nh0ZC%YxoeN|kbZgs9v5U9f zJjSq|+_?Db$PJ6vj~gHhxy^#r`t`Ex+yJgBUv^__E^^D~^IZ$-yBb2u-vA^eAKoMfQ+AN&dYEmgPo z_;SA8g;%R?vcx*@$B*SSxADhwqn`O)grU)E_eT(6m+j|_( z?drB1PO;nDoZDZi+r_>c-pR9H-F{WU?Z*e+_LI+ zSp~O7b!)2Nw)G(X?pL>k75wc!h}%;Kaoc|ox7pIgL7u7*-h6etByfuscHOoySAQd( zxlZ?Nu{UmWTF53STG&{htB)4m*wqy+>}+?IhW3pcu>mPs*w&tFT6oo4*DgSPj-5XX z#amNLU2`Y*CcR814L;1WtiOFzqm~_S@=@$#E4N0c!X9EI*lE6J&(bI;mmYa zDKmUM6aU0D>k$$&9E59l7}mLPAkQTK7M}SJ?cC17@U_?*S!CgJZq7G>HDbL)tlB5S z``9@Sm>1yY-=3@BZtp(nv5Z&+6VkHG5ewy?qyB3&e;TVW{@1}F)G2AV(*dSM9hrXg zYyMg1(J*;K-4n0XeM0rLcqWv;lI$d(Sn52rU@DttHvXy0FnmnGR}6o>6v!xA8$>P) zAKoh((#?o|eV~%#^ol7)IVx#_cpwCry7ExMEncsK+cfb1xF)Fei`Y*g{sAqh(l-Id z_M3QG^(6fgU|Gex7!Zu~AMm^u|D^vd6$j&O`GTB5W`R2^8q)te`yVjUN5S(J{1eZf zLR9+$crtwAPrsUI6iL4X&+YgpUZWZ3y>x_O8%6wcic5b47-z7FKc{#j>@;7;Kk?nK z6>DVp$QkR}>M7rRIF=Zar>x&xXOe?;+P6gPT0PmeTHDXl%G$EDB^_nbbd6^Ww11^*ME zPcserG74ypf!_1?3HT8x50&UoOu#u-V7L~Zj7Jd8ISKSjl)hhOkueJ1S0&J2m4Lrh z`5dcNfs9$e=Us|hf8jX|=jH@HT?zQ@%4fFL12VP&uMa3*r#R~i8upPZ>Fx6g_?MK= z$293>ECW9M3H0Adz@JLMf0Tg#ECK&j0{*)Md=~UxDZa-8XMXs?>7tfM`ssK*D}ny} z1pJBw{B6qraV^)J*q6V4Xzk>S&3IQ`TF_^FDw1^6Px?^nFvv5PKK{08m6X)_$z zzVC&lJ=xf)Z?iLY>Htp_kYfk1ksmwMJ2`=p??At}sZRF8cSViu8(Q0%BHiuI*_^tz z_SUwRChP(CQ4rR(G}SjYbw(ZaUGSf4zqzTcE85V0Yg1=k8RS_eJIkC;T`=cU=g;}n z<#f)cE}ZkJt1#!oGX!+Prmn)APhB|YBb&x!AK{!&9p`-H37Nl~-P$SyQ)W<*I8kbTpO_%lAA^l)E(_Sa~_`2N(xeR+Q2;Xa>Z z(0&>pUk|VIa9^H_JlyC1wgjC09pmqZyVb*eKHp2gWnB&!h5EF4x)A45K?|2{o9VO9 z!~JmoIstz=0sn0Rei{XV3FTpXSP8!&0lzH)|7ZgK*9rL33Hb8~_(?}pmhTqA4)d_fNR*8NdUX9OHI!CrEP-RNsm;w=3AdSjD^`}%yZ zcG8W%syFIXJe23G6H5F!wzqHxJls$B-+8!C|JqkMJ{GQ$Me71wrx&92ic=oH{=Ye( zXI(?HE5I#YyFEU>-kuETS2#A&-+AqVhbuMQ z8x$uWzubKz0e=E#iqVkXFGtUMxS#INo-E`-@0a(xb)JWOI0s>JzW$UFy^nuLag#sm z$fA#X^uGLG@o2KB zCg5|w^0~pI_vPvEaG%e159i#RrQ_#4{2~wkwc;lKE)Dm$9=#v#v8Oo##>)@)3=j9i z&3d>W?gtdNa39fdKkCu@;eOh~{cxWM_2`+R0-MQ8H-MET5CJWR*a zJlyBA)Wdx}yu-tNJ$%f=eLkP@@D-57((x#r{|xnia{~T8#Vuar8n5?z^uB)1PdkE; z|MwH{Bi`WXjlaoxtm2{GnmpXE&u{T?Uk`T#{HY6?Z63WZ|EE0M=d<*5=P!)cpL)12 z&tH1D&*w44r-9uu_}}l?M&I`6{r<^|9)1aEO+UxK(Rrjie!Fm%hu3)YmwLFLAF>|q z^V#mTIS+xsFupbTH$9x{;XeO&dblrt zhll&&-tOT(pHFzWpN>Nw?(;c{o?)ippXqD;qKgB3oJ25h3vi3qI~AV+8b3d@dH5A@ zGy3;?eCWsU`#qfU{44%x_IP~!e&&-N&R65}V~>x|e>4H#@A2{V_8$rKb2)g1F}+zi zO)DPiVM#!5{g%!Ew-1lEC-CVD=x0t84Pgy?($rK z+jkfH)Mawo_uA7meGIqnwaWtBzPqdmaQj|s^Gn9ZzRU8vAC2Mm-S-OtZr^1G1KhsL zJ{REjT~-)-{O!B!X$;WA?R)UD0Jrb8YXaQ9%XS2~eeb+Cz}wRjT=YPIKcM*D0RO4t zBLQyTeP0Z4`wlvHx(kQS{I~C>O9R}#C)EbHeLvn1;P(A^dw|>bRGwf zI+sL!*YF3w-dVZT*kv$W$UjwD);wI?+7Bu&#CO|ShGD~s=Fzba@&!w)i*{C0zPOef z%dp$d_T6CpH;&elwVQ5*bj{{ql{_eTKmvCwRB(dl2^M}AOh4X0e;jPX10t2V=_+g8 zG~UyU>2?wUmhGTC>CRbn+YOF;$zQ9WoQSe2+bgZ)D1t!jxMv@W!fR`NnqY&HG4~=E z2gtn@VSuTgZRG77CT&B&?$8zs>_O&_NqWj>cT+egp`2cpa12{41y2@+#jQ$50F@-I zs2c9LBp2=z$v4XO+M{(NNxX#LlDMR-&AzV$Wlcq-%E~(mr6>-d!2Lq_4|mw+&aVvf zScVGJN9|??8b3l5Tgbf7z2yZQ3UD{I4+Xf44-IrV+g{+XHPHsG4v`Gm(YAGo-L`dA z%1wPjQRX@CsY%PpK;{K7#?eeqRpoD`KzYgU#jP&*T*E6H{MaX4;L}n)_c4N%^p?M~ zOd%apkZ6i|Xlg2Q;YrcXFRWZ}vp$WdWZ8dlAvYx4lE+fk#swYto{y!l8=Cz67q$dI zwq&^d3+|lsXz{}8XiB>kbc%D*UIk8h=(I<)kL`xHZW*@d4`q$6#7!dPei&8Xa7ru0 z=stJ0qq4S~<17}^nGQbW8eMB!l{|igVR0Nqp4uge>89$R^Td>kZM$#G|7AXichdT1 zIV{AGoyyG3+BcY2hL-#rpH*fgus9?~YQ(d|?J%K`?be}k{XOQ=)2ZJpyN z=DLTB+v(T*8-6^nQ1|pQsNvVs;+ar>+C$xwyyIx+NxBVqWp*MIhEJ?g_$|zEF#pRv z;@>d**dcf!-7C39m%&w96YKD!_?To4XKf^t&tDs9<@gQ2HEGNE^ZQ&S{L%#c@&x?N z3HUn`@YV!8pMbNoT1ieeca`wZCE&IM$aT_73&-NiP%1Ar;`$w1or8COy-;vxiMQe? zUfg5Ljt+Xsj9a6IaCAkGtjLL2PH9+HndfZ|Y6C$SmLV27!)=a&^ehU7|1sWajNZxv z^-2@c|J=cXvkV%a>FUw=*qq)>#mR@Cg^m7A9)6sMa}6>L>3#lP0sq$u71n@z^eJG* z|04nY8A^Y@N6-9W^q=!^)?tP}6!5Wd_j>e1qFij}`JjG2v=Qy%xL4X^d^F2Pk z-rnKizTS3txUaX}0sm?Zx8I}ZXI=}}*2d78`A4G}J(EEH&jEkq^UDN!o_0k;{je`( z^jy){Cx_xTS6{4HKT^yq#5zw>aP|LZ8YC#Uf_Q*l0geZI@X zeR-@OWbw89a7)17^x&`6@#XvrkH0UcKi9!@WPMKah)3`9`KgEdeA42}rHdx1An}|= zM`u$9CN&N8a0Y*#0^OSR??&l>c?)+2L5_R8CvYN< zL;FaQ9iRfl&@tYckNw-azuuiIP$Db62{$)j=7GALEWzkG9G>Q9J0Hvp<90bv1+rO= zjH(W#kkf%gObk6!J*+Lp-h>}_2m+=xa;M>^b8+{?wA8ly;lF!gdTQGQUdDcjP$?OX zd$?ppKIMX7QjI<3xg0B}6AIBR6Bjf%s9%HVuX0*&))gs;@avKy9rhBv+mt9J5egqq+-_E7l z$Rj5)g(k-arFx#mag{DZJ@FV=CYeb?V;%fXY2XW{tiNauwoku?1m4(}t?-2E$e&M@oc z*Y(q9;obb3UXsT4HOh38`nQM0+qZ|Z(`~Z`G+!N=oa|GF;U|slcT!lGUG5S8hT+E! z!3*jBJI40ZXO*`P*7W>(;M^BlgC~vDn|QMP5r3Q@jID=fxgvhD=7S@}6;&;sRbGml zKC_CO-SWisigWxxWB3htCm$=1hLa|F-zHOQvYC$i8!MSga~aJb^ye&U)Z?vqnk)** zqc;KnSOWgZ1iUmCAf4NIGN8VJc6a1WUFWT0!PYN*q8q$Eb(xrB~I29 z!}O%*A7Xx|= z_iq%Z{UrPw{ci$#E9W++YW$54Kh4pE`0)X5eEjtpz22cfw1*9$oL^oarBHMkWFdeP)K-@y@Uf^LxK{4kA8t<3@&ZY>*2)a0d^FO^Pa7 z2V-mRjOp3#{^_wDH@G>$CS6?d4-g0J5Usi7id7eK_#cFgFYY4Vj|A>VCXL@A^zLl0 zOtB(oH(DD5hw`si{~boCPt(7_*Wo49Dcy#2 z4kW9Dw9>EnxAaRI!`kV_5sX{aG^eOc=iB zRQ5``S8@!?`iNspGmqH|p0DJ0YvxDmA9+E_SyYv9ra#AwCZE)Uz}}U>=f(uQH38q8 zfZvsX-;;nRja5GaddmNVW-_U(f!T1;9Y%tIB@Q>iXX84YveDAsh_f?tEeQk2^08t( zob2e}fEA2*!~~C`sC;e)2b?(ALeICLt)7RzcKXLk*wG(yWGrQcp}uKYR#_IUZ_Jr} z8sZ$!8GeR``(wt7JUr#m^9(B*@?kzOKARM$`i}JQ_b1?=@c8)h{Lch@kB9qmKI!4U zoU%q1a!^jzJtn6=R-&Ak!56bg(>;ureZfh&_M-n zgvu>K-)=a{%}2KkBZVEykXr7wuUcN+b?~l#df-W2If@>h-3Myv~a z+J<|$UUVUi;9}arRQE4oW7r6s-VbuAQmW@s^@%|F5$*Bv6_q#%TkiDSRuD2=wQYAt zem{HmBiX_rzk%VRx-xNcTtO_NblqgZC$g4ByF-OXF$}@Q@{W7q`)5B=7&N{dpvaPJ z)q;NB(jZdrdxCeV*g(M4s^Yoz$rvBF3&JH?EM1vGE?t>e+b5hN@VZsfO-3OHo}?7? zR=OY_@*vIqJ72OG+wFE=;V@i!FYcNi0yEs_0I^JCkI$Ia2sPo}=)1QJ9f0eme~jtg z;O^b;w3KZ|SeoJzLOp5}ZbIWF7uy~pK~UjsM{G9*Zd5m;tOZk>o@fD6@` zs<;6%W<&0mG~CJ@?vWu!u7%a^U577s@A@Ef9B;Z7Vo?w;KK_^kFy4vPI+%TAlzDq7 z`$*H!G>FwNVySpzcetGG2U$rnh>9zNeAzgt>V8x&x}Ovip&yw{KMi-0B=Z09Wcuj` zqvu6LkBm%X4jp-9V#d)!+cUr7D?k1gGe3T0Vj7`e@^$1$Lc_HG!Vd)l*wk0o{z~$1 zzp2wz4iZ0=7lod;cX(Q&w_hfDQ?V<1`-OSy&J4}~*FjVbL#g*|lET6;Di;Hn_lv7_ z6wdrVYRNgiAds#++hDBivJIk$KrNn{Z3b^;8AiCcgvn)_-I7I0B?*%x>sgRcC-1^U z&jYw(X2u!wnY*!WV=-qDc13cD7AOWr@BMdNWBhN-SC+}1ahZ$-p?~}i1ja(NORssq zWLEAdNY!68?&bn0#@Unzd4Kh;Y}F$oTxsTk);;W+$3uS#k8n>!xP{D*ySMx}%FRTg zk8#bJaE2E|4Y$E_$$mf7{Q%U>Sse*v3gMyV5oN7ldz`w5l?41UI}q+3Jpzq|-Cr+l z3#VarSOn2xbZ3Tfwbn3;d&ysR`JV2x1c`D|!oq5#-21WI9 z-pHGxc`Cc(@hgrP5dsa_CGhx+$1@`?3Q*kN;RAvx?g%Jue1+pQK;}?0Du20L16q!m zLpo6@p3J{c=&8uRF5}>mk;d$KCrS><9U)BO&mmK$Qrq(ww%Qy@?8tG|Ul8Ca8%luLvKzmv#qrPEJY?j3n7eQ9Y^ak~lh zAQNMcOOb&C-!IKy&WB17HNU$w-*uPX0EwW>9gYPjVE zD3UdeHrJ+iOytxpJI(Wp*SYxbQ@0jA%^zOr_61@vl2C!$pmUP%z`j4u?LDV%wS1aC z#6#dekh#6PICh2`*pNjj4t4E0WPCjN;#r4ezaKM2?GF#M#s zJ@aq-=FNZFUi6tXw`cxu3FtZQ^-a>;-eR5GoaYncopGhH=PK`A9Q0?c`u8!un?J*o z=JwW^|Gn$LC2I5G3SX?I=4(MSl|8U&QvAoG| z`G?sg%sYUh-6V!NHwZAWI-&}{q_ezUKe1+j^H;T6cC!e=yV%VDTI>qmkArg8P>fWmO-|HM~3+!f+*QZ$O8Krwx zI#>KwIE7`6)Jb!AA4{PBWCH%x1pGS*_>&3v-zMPWz&WRw(I`vX0;~#puN1GDz)3${ z>pj+MG^Z)PNO5Uv=%AB|Xv-Vg8=EjQ>0atO>u-%V=y2M9`3I<`jChF^l#C6hpgVO(H?UIby5-ZwTnEKHnVR zR-b<)z^y*t72sBnv3{hXEd00nYLp<1;Z|R1HRbA)DePHUyu5m;TN^X=Ju7zi7{jmO z4}R?&4x2i1OyD>&~LoFfchee!@==OF}}kpjnlKmJVWKQ3YMwJ>XqTE?Go+L z8kBDkVg&`Kj9jo7VIuhMErU`1Z-P0~Wf)J!QH+JnLs+f?!6=deV5*@Mz)v`Y?cTc# z%PG8z6JNG<5ObyVsiRiOF=^6Rsis2u(XaVuJ3_-gd#HQjqZ)oaEuK+0MraRZ zr(=B1fO?n>jCE2Ne$rTJP}@`~mt?3W4BznZNxD~Zti_04{QEIn(@6>1`2)i|z~PwnDL7W5VR>g6 zG(3%W8q)juChR+yyeg*KL_d|b`uq#@!}HYJ>iJ%#s-bXEsjc=umU2_wwfS7Sy*Z8H zL3`(IQ2Kvn4c}=9iT^b0|Ho|;-)a6p+8~LWi;?_>Z9q~RG{g)A^HSTOHO~8_-!S~7 zHfXB;liDEjuhT}c9A0)4EU67@P#-U~4f^9a#PXLg{G>K$yLz)el5w#*-0VqhkPJRR zWNi)W0s1xnh9|W_{h+0(caQitl%ICLE-^yeTc1`BY=hX|gyAQ(LEAO|U11FM8HOJ? z$5zt)ceFti;N@s*m@aHP%vd>21E|ynv8}0u+vJB<;_*HzTwc|ViZr3k(VD-msk5`a zQ$)}%jij~T)-YXZSgxni)+{v|y)KECTO-VX$ApUO0 zubc8IZtS!0sawM*mgl_{_HN%h8Dk`d;b3OMk!5#0$oeFUr6sa_2Om`@x?YpuR`M0E zAIbJ&9SXj@f-59=JX`qQs0K2D&&N_Cu*k`6#Rttqwo1l=6WOyN1=m=mdal7ZQKNGA zzCQR4zVi=c?kCHE%ntXE@xEh?Ll3q+iX1nPp+9_Z?ki;O9oq~9ujPweWNFC#fO~7J zoag0_ZaD>ZZkmXrBa3am+OMB=3z;3_VOro}TC#_a6f^f@1xP@E#ZH;+aOobIF6Rmq zGdpDENCmQOaO)mP^`6+{V)T(mCXPIMr~={EV&)^=BbQBf>A6D&-hM>yz({^8=grHb zbH}U!A$BhJ7T0di?%2NOh@IV;d$DW)_HBWEYq|YChE#&OGkw!lQ<=Why|-a_4lc47 zVCO9I%oe#;5<=W7QfGF$Z5ju@KVH?x%z@AMZh=Sq`Tjrs4R}gDuF{<2!S+qOp0e9~ z0AAT1Eh7f=ZT@&}?5A0Kei9oS&yA#iD1EhXFz8id63wK(T2{a9ZP$jF^)OqGu&q5) z@#(^?^ivZ8>J)~b)K@eA*%C{6O9%F(zMA=88PJFRllp3RtNil<|I`7EJy&_};-EjD zN{GMtGuouS+5_sp!wB_h`ZqYKuQsHOsOj%;`)YGFq3SIleTMSWu34mvvR@nbLG?g! zShtw`)>lmItI+}G>+TW%hT+E!!3*hL$-Wxp_xIp4AJLqSf8v*j&GljU%6v||h87sp z1K%snJFwpJzs0U3p_-SYFUWlB_XVZy1om#l%`WvOF!tCg^#!*p{m=2Fk-8MmzrcSb z`Uetl>r?7SK)D8$UmV@H!W;9=`qt2vi`w(Kj(o1JIp1dP{NQN)OXtHe(C>JaoDR`T zE#txue)<7%(w9TThsMT)EDJ0;mj1fLLCOg6rTC{|-HqY`F#f{$h zFuiCDH$JyHcoP2M1pMOxZsC4eamvo|gW>&(hv7bvfS;-bH>6(`;KqMlfLpva1h~-` z0^I079^giA`#mTR%c9}`1aU_HZ>FsQj5MSxhQ+FoMx&-{M6Y%c`xaF&VSDd^# zjx+hwc&DMWl8D{>8E)l!ow%0htsF19K!-?E98)c+UUt~?bhgfeBGiZ+H8@+~Xm<|W z-TP|NIL7|r@BHMzfndB*>>>CdQ%aURV2LPwXA3>Uz_Z;C^Kn4W>K^+EoYV)Y%6xQB z#ALhS#((z}AG}5!FFvCDLU9^n=_&T?qYFnQz5DrAbfl#vsq8E}Hw!mS>AtIS7KB0f z!(+mTvTh}g-br?9aiwAi%wbV89erXBtW%x;h2gTM;4>89Y zeUmuFXsN9>D6wy>eVcwIWLKHtu)d&~>mG^g4!4uIf?-+qO;X=@s{XBSTq`g)#zaAppE+t$>i)T!K2E7?Cp-$*FQwdGa)IXEN{2R{p zs!}(6RKtHK+9aCx5=C3pLsH*5sc&oF!tU?`$9oul;2c{?_e%C{8BnG5 zat^myJK9R7QXiJ>lHbR)^7aPcmHLJkCg7a?s6@{`Q6-$|S_ywo0)BG>9(O65JKHxl zH=;Lc9Z3fybRjo%H8tHFla}9F?=FJxY^pDSD|Rc-gIqK$1I**r##;p$;&+i4 zhB))2(LY2GhB(JzhW{Nw7~=jO*&{V0hWxD$NBlVa8=sXPJ^R6ir}0i>eGX@fmlZa* zwl(tFoI~E5^HSF9toI6TjRfrVExPyB_-k1(vxOx)8SX5>Kbl`$mh%<(8KpnBA(Q9T za5Gy~zii(5T9o=){~4@sIKlZvklFb*XY%-(A?!Y@8mj8Y4jIh4((9gnOtRv%&;ri2 z>Bc&rsj<#~N&Ro@&&|=-OBUuY7Z$J&6>DZ*oOv0nHu;hOw|FnIVf|F+0WQ4Yu+M#%<8{(&M2^yWo$IrA@0$r>vxSEzaF#~l zD=*;JpAQ&a+&|EB8X6~h%=Y%o^xCP%dtQ%bkZ2m{9+KGRV62Wk>T!WxGhgVLOOL(m z2SvsEoF%izip=^NoBy!(QA*rI6YeK$+mreh`?V1n z^x77_hHXpIx4xxbU)u|QQr{-2Z!uN>*0%_QGyfcK`bMJ@L(B0-tU5;A%azLTP<@kC z>Ob%vy*Cs{3BvG`zV+F?waWs=rhkL4!%LW^blc4a0cNgyNZ){d&A;JE^C1tY{PpVJ z9-;iSSBh$__AMsV1KXR!>6>I#(9c-F`V7MloMS8LUdg@*1FAH?;qavS5Ys-XN~Tg@ zhTn+%c@itfX9KU)*SIVJzajyzO~9ESEAg*Oz?&2BjR`pCw<_`flLY*u3AlBMHr{+= zd%mr)9t(9#Q!yKFt}`^Dua#@Xlrqj#YiaMwwQ+hG?;Wj;QJ35$*?jPG(rm^j*Lhnh zoP;SG>m#y^`tvXAV5cGO_r+QSbvXMS)~CxW&a%dCzu_NLoP7NGmyauM^yp-W@xR^q z^xq8VjsHI;@c*TUv!8DCHu$1EK7N80+z_{Yki?lUjL!;>o^_PrZ&lplW!=QvJ$gT0 zJ3QR~CiV>v_xD-aw?4|lc?t_RjdvP`%YQSA7FRFUZm>KKwa#$y(#6Z&SG1|GUEj@t zikcdE`hDTf)%Eu_2MiiMTwozbk9<@(`Bd>Iv7e9(7_nvgw$|vc-xHIVVOW ztg)iU6lZ(ATF}vl(Eo%M*1Jf&SG5p_S23(AtcFyLoXzPoQJf)iGMtm3v~-hS{&;px zs^<*oN(H$iy1#a)$6fI_dNtDQ4Glzu1+BE3M#n5BqSohv5t2E7kK2 ziLpEL2Co?7aNf~)-=kE22A4g|>gIi;I&3Az`N4P)LhrDOXjchU9>)&3$U=!L%GjLg z2yi}+Bk;K>B8+~IVFc4dzPy_ZV*=(hZyix7){F_}Im@L}NEm;rjK?a8da-5>GktYg zV0SnP+<82tfT*k|Kv-FTv@F}zxzMqu*wZASwxlj}KDJdk0QwnC-wlz>(qSP;sJ%U8;re^iR3G$&B>u^MUG$7ebV zPTIm^aVTm>l-jm4_9HjKuXH5PReVW2buW3zLF327b}%Zg-61RKpOM-C0bXBLEx+2u z=|Xq`ole>mSRi4QSU*2eA=b|dSY8vc1cZ|%t_W~mEX$gr@bGRF6~83NjM$F>B9@3# z58boH>|9N)2L&#zR&i@!*tU))167mS_AEMG13l!1z+y+lDkqsTwXGinE@S@F zOmqXk+A{*$OJ=3E{Vg0~W;I!G;{mBE4eY8JTz{DAS;(05iq{9(6P|P`TB_$5kaRyR z(Mt9F9yArDdKTqT8I_*}i1Kt@kX^A{2%=)O5PqZ07rK{O`5*Ccwz8(IoG?`)oZ-sh zL5LSAaqdiOIg0l&ylg{RgK#B*I$U3UAF`nPyYZ978;#SgZ zzV+Z*-S&Y)Dt=p=NAjAAX|s(Tbq&apRZa(#1l2r$;9sQr*E;y?m@-I8r?mC7T!z@g zVMfdrO1kf$$%D%kD{3v)?5n{}Qzf;HxoRpYliKziqi)rtL@X36)iZ&V9ee1IggBQ$ zqsECFFKW4g_}lD3#BHEC$BBb%+=Y8#X0rC=Mf;BOx35vfx8ynX+DK|%u!6srveHK!8$VEgcRay zj2C%1*Fw)zUc5B-yM9`Jjqy`>0Fj8(&-!^t;$Pr^(n8N*1wQxfCWzaV#C44KobBl$ zk6xLo8ohbHUm(taa}Z=f^6A*0m%=S>oe46i?e@4blxc-xuSCQpv%3Y!X-H%?xYQXk zM9S??f91=;=`522(K`;&Lj`k;>tt+&Bf7p;@-c>UuierO!oYitj83!)`_GG(b)uDx z4>{-xdu8~9#qL;XmLts}dm;Zq0R#QQ>QM}+%jZTUl50nct6#`sh~;wh8h|#!*;lO$ zvYaj`tRBIELc=aMv#$nEKwZzH$VEH)x^}pXBdd)vj-!SAbKuA$vY}hJM%Xjjy=5Z0 zO$*={ATS?RjvW5E`bo*-kX(Ss2`5s1Eff@O?9*gn(@>5~t1gHm1Lw@BtFRgVWQIp$ zF%=n&&o7l;h=lke6m%oFh^oAY*1hG$D33}>lih{6{LxLvx;*%eeU&`nYA~l76%Mk* zs=|r<9Go`yS8iUx7)+M@D%A zx62&d%ey`EYoORq8=${&v4P?$M(lr&Q(ais)|=VChx5YB8}|$7>rfTdU)tXstJIuy z0E~Hv5vB_-LFiAtZ;8~V)Mt_eizWponZxCvCmt)EbL@7=uEs}*1#fTa>}qXqyC}VQ zVYPmuPT5T##wQX^yRJH^JjZN`=5gsz~p9 zS&$>wlFj_dmMZ$2d~P%L(zdjArSVsvUVZiI%!20j&W-gs!~rL(bamC=)U+_2zPdSm zTYEl@)v@UusdG)6bLrL`C?FW1`W)RmXJr;_#F32YuJ-2Kt@WKv>Bjb^t~53bq`UGR z9qpaDgb=zG&WdI&kVONHrMCqOW?}Ez3TS%@ixrU$Q(3RLmkDNT2s+Ep9s4)m4exXD z&uX1U*4UUo*y+|m2bh25PvCYhF_^pg6SzG<4CZ5~4njAP5Abvr4A0+bu#VuL=Fj=kj}|9g9AW$jWmPt}nTNE!=rd`}hWW48 z^fzxNzuA-4Y}|daqnKxe`ZRX-Tm{_TebP^UY9=GV@FzPDR;CKEVP8Gb(*0_g$KKAq=0@M40yU zH*z|Eqv)N1V#4qp)#P8&y^?D-IQ{SM&$f6mj>OGwX~Vr1#4Z1u`=yFodKiAW;%Pi- zjL+40C!hI(mh{OsfOvI)b59EK8pSQ6wHU7YwQxHXx4n~wZ&BRNDK&ZS0q(D>-3vR- zhwx9_?EfZc6y2{lhp04{xQF~!S_AV}a3LSw>p~;#7@oWFPy81u|J`(ic?|!=+cZ;2 z`vvTKiXW}{QQ9tGPvajaR>$eW@Aou6#XtGXRs~3V25eOEbxLUI`5VPs6t}ymf2;WC zv_6!!23Qs1L;fq6kzk}#cm+3hzxJC+e7B2n19Q*ap1%IC>`OBvu91NJ#q_%JKoBYKtMZtZNv-d-%wx;0)fRoB_xo+|@*i~|U8>!qy7YQ}gZYHq~A4(`{T?I1v1edkRI z@)QV%b>uqrZ9`LYjzg7AJXg#-Z^(DG=sQk^=VJV2H{t|(<>wEv49mp~H`Q;*H$gTI zjbwa;;nBjS)l1Ih$CO`JR0yY#sHg-dadPQo%Z z(VHDJfde|-IrR-3jMd#(x1qg3uII#Y^tNto(w@O)*?3r=Yi}iKTSI+U6A$^+v-0b% zzP1i4-x{KPn>?EF+a-=lXG`7en0t2yKGwQ0;dp+^!+rWMCh-4S0{ss>ocvG6Kg|)^1q$PJnd0^bCdX7_Q zY+s42BOrZanM^8D)i{?mOHqUU0pH2|wql%Naug^~h^lumH zDEb?Zp1e&SyJI5cf8P2z~?_adOyC$YegOE=M9Qa%2yul$9H1_pSwMJKfb#>{9G@+F5|K^7|Wlh zJ8RVF;eNX36eo5L{w>{~_2^kYd{+7Vvq!(gqd)REM__uee#J7y$^Sf$etiP|rGSs+ z&+mEkOFcfXO1W^!|9lU>Nbyjf>jV5662SC&d@g|9^zgqD@UJBBc{0E$7fr1WQW+fe z`4B;v`#hYq7ViBXPI}It(0pBS(w>cfqaXBezaFU8@wn;1=r8ne^1nv;uTebY-{9ds z|NA}sO`bg8^!St4Y51r4PJpKc#r)$5?#1M^{^ZF4K2PaS4{(+Nnzt*?FxmI9_~rt7 zEk4nm9!@>1Q$6%}d@l0%-0RUZ49lM%PQX9u@wwRJ^Vb3WC2*s8FvK-~J`&*8pMTop zPaYQEzYpjQe=Y%^2yhVwKPONrFqSUH=QWB`2P^Pz_*ntHjYk%SIGMs+72u}NYd!v) z+cy613Fxi--kE^^Jix79vV^mE8K0C2V7SdwU+Ljw`A3>h)_OQ~Vf=3jaN|GZ;q2#I zy#6@>U#JrYCXex77T_l5$^`uS1pI~s{9^%b;ie%o4dvm#8Oy(h?^TC&`ZV0;>vI8a z^YVQGZu9bA2ymO19}IAtmwzt6ZT@|RrklxQ^O*kp0NrdJ^OAtx=Gm>DFg`Yqp9|=1 z9=|WZZ61Ho;>F7kXRqGUWy=ox+=~4=#-mDV_=8`&6E54m4{OuhrY&2n)LVcUXAfJ@pXXV}VjU7<&&@uH-3%#cgMN~@NPsapd!_CxqFXnJOXyN+h1 zdcG*A3qytA${HsQ$aD#94d$v0?X8_=ugf33)t1l8E~fky=7JSU4#Dc&GVZyYmlyA&cXf2D*>*rA9PSAihkN2T${mBlLh&;8 z56Go4A8tHzEW1UJDF4?Yq$~?9QOULP$RrwiO@*uCbv;@)xOdjN z)=oKIRM-7oS`yLL2KT^+E!Hi`F(1+oGg2fg!CWm&IJ<&7MQ%Oab15L7iJPquehze8 z*vuzuyP~|gb-w$7Ibppms6C@VyC3FnWGjVx5qwb`N**oHQif9suKJ~PE>9sB@=#Tm ztXSuKvACr^xDW~GRs)L@mXtB`SWZV~I7w7fwy1nPS{lu%iJNs$8C0X}+S*H5+GYzj zU0%1K6!ns@^jci|9DM4^$#W4IZyh9L!}8-YUb4KA^6SajJT~a%TLbkrGWOQ%uwS{1 z7|i9!0HNC&afzbakldkLhq~R#r^oXTWsOgf9T?99)+lL>Prr@{C)5Ln%2cgRCCR!g zvgNpexK5c867!ufAjLzNeSGo^{SPT&jry~Pg>Ux7cwzWVTHly|og#{zNb4JpCx})1 zAl`qZ;m-?j^KZ{paJP4#^mk!I)iI<^TH_;!FTl@spDEtM_+JOCQc%0K@4sICGyUk- z{Ikr^aOf85p19ptRZoj&LiuSAbx-nYRs39K&aoN0!(sR&s}z1#2XnUs0R~q1u53v6 zO0Mxa3H-Sh!;Hm?^FPGRZcp~5iR+L)c3-WyrH9eqsCXJr8pHXGk9_6}T1xxvuyf6b z8L1;-`7_1MF7+d@Pvf6_EZ-Y{cGZYmeQG#hq?1(ge2vYQ@y2jJqCra?tFAA{+LK4X z%XAh8ikD{+@Si2%&nMvjo`6%8mBKwK0p}W>O7!O>;Fl%fT$9JO7{_YXl6DC)HYLz+ zNWkseHqMT*_1IV!VXt!eJXRY_0_ynXzl=(*ztE#^#2bLF*4vvVQBCsMyrKT4aw;x} z@R>)g3(vdof(xVf^06!`JLjhEs%x%Ywep&}Yp=ZW`plZTH7i$Llc}><)qztTB@5RY zV97!G5y<5W3Z}fCVAA>qTPjc{qpp;YB?Cw!8l9SuI+00eHN@-0)zy{6PE)&;GuEL# zepx`zx|8Ng_lWsxH5t7{aq{3$$mSqg0{Z!C?+S3X!!)ci2;HHPs1f1oZ#=C@(fO-|F#)d}>rzTN1J&$|-nSzpi?z3~s%E*Q@J-bT-9aEtGa zic=3*?eSrrGWs6`^p@X7J)C+_YxKN_`}~ih1%?lz^$!n3vkQ-wjK>R54ixh zc2Miz&5iku9Xz=GQ0HGQU3}pMZVqnh=U>J;u?PeQ@JwjD(B27d6#0 z6FGomV;pl)?Vg)4b3%JZ+C6LMV#j0eX+2~a?@gRN@9M&D<>=Gz>-1aUSxk8BCXrNP z&TowzUa?#m;Sn(61fHFoB2!?Mx$v-=oN=jrsa)3C453XKfazOQ&Pi^#;qxU5E3;1~ z?B6&MmA&Zuv7FSs2zFz8<83i+7VP$;=QFx4N}tg+EAsbOmbN@%?QGQ0 zQs3Ftl#4Fc=NjG5n6`b8ad$XcrG0E;kiMd|3yXJKbJ(;Q$wFlhNWYb5NjA5l&&?O# z0}{{nrKzLiv;C(9+sTs#gDp zJBPMe!>w;>9KFdEM@YuT+$@Xp>=5fWBhy*hVQ%i@1%Pr=g=5d zr8y<4-Ji>nI)}tCFUOn`$19q&!qa{hB;XtiRieKFIOl3iKB@o6tgN%j3mMpJP1t&& z2Laps0yaiq?|P@PsFMyadBR-l9+Fp>wQMZV5a7$y-l=g{S*Uw<9}a(w>j_8{Q++Lxxb7iH|0bX}`Ckn1f`-feWi+9FPEb6Qe_23p{B7T)@%fNr8(kgH zn|^G6c*x)OGZ-Jvh10YvAJY5!=??fCeKCRl69K)+|JeZlyo8GVHUVz(f5YSNm*4LO z^baYYr#*UK{+}n%|0aR{NbN|_*{>h$t`x(+so|a+(3|{cDjw=T8_?Ta-n9X4eBP75 hM{m%G^VNvT^Zo=rf0n=}t^ODi literal 0 HcmV?d00001 diff --git a/packages/clib/maildrop/rfc2045/makemime.c b/packages/clib/maildrop/rfc2045/makemime.c new file mode 100644 index 000000000..03ddcbcc5 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/makemime.c @@ -0,0 +1,1000 @@ +/* +** Copyright 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include "rfc2045.h" +#include "rfc2045charset.h" +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SYS_WAIT_H +#include +#endif +#include "numlib/numlib.h" + +#if HAS_GETHOSTNAME +#else +int gethostname(const char *, size_t); +#endif + +static const char rcsid[]="$Id$"; + +struct arg_list { + struct arg_list *next; + char *arg; + } ; + +/****************************************************************************** + +Open some file or a pipe for reading and writing. + +******************************************************************************/ + +static FILE *openfile_or_pipe(const char *filename, const char *mode) +{ +int fd; +FILE *fp; + + if (strcmp(filename, "-") == 0) /* stdin or stdout */ + fd=dup( strcmp(mode, "r") ? 1:0); + else if (*filename == '&') + fd=dup( atoi(filename+1)); /* file descriptor */ + else fd=open(filename, (strcmp(mode, "r") ? O_WRONLY|O_CREAT|O_TRUNC: + O_RDONLY), 0666); /* or a file */ + if (fd < 0) + { + perror(filename); + exit(1); + } + fp=fdopen(fd, mode); + if (!fp) + { + perror("fdopen"); + exit(1); + } + return (fp); +} + +/****************************************************************************** + +Open some file. If we get a pipe, open a temporary file, and drain pipe's +contents into it. + +******************************************************************************/ + +static FILE *openfile(const char *filename) +{ +FILE *fp=openfile_or_pipe(filename, "r"); +int fd=fileno(fp); +off_t orig_pos; + + if ((orig_pos=lseek(fd, 0L, SEEK_CUR)) == -1 || + lseek(fd, 0L, SEEK_END) == -1 || + lseek(fd, 0L, SEEK_CUR) == -1 || + lseek(fd, orig_pos, SEEK_SET) == -1) /* Must be a pipe */ + { + FILE *t=tmpfile(); + int c; + + if (!t) + { + perror("tmpfile"); + exit(1); + } + + while ((c=getc(fp)) != EOF) + putc(c, t); + if (ferror(fp) || fflush(t) + || ferror(t) || fseek(t, 0L, SEEK_SET) == -1) + { + perror("write"); + exit(1); + } + fclose(fp); + fp=t; + } + return (fp); +} + +/****************************************************************************** + +Build argv/argc from a file. + +******************************************************************************/ + +static void read_args(int *argcp, char ***argvp, const char *file) +{ +FILE *fp=openfile_or_pipe(file, "r"); +struct arg_list *argfirst=0, *arglast=0, *argp; +char buffer[BUFSIZ]; +char *p; +int c; + + *argcp=0; + while (fgets(buffer, sizeof(buffer), fp) != 0) + { + const char *q; + + if ((p=strchr(buffer, '\n')) != 0) + *p=0; + else while ((c=getc(fp)) != '\n' && c != EOF) + ; /* Just dump the excess */ + + /* Skip the filler. */ + + q=buffer; + while (*q && isspace((int)(unsigned char)*q)) + ++q; + if (!*q) continue; + if (*q == '#') continue; + if (strcmp(buffer, "-") == 0) break; + + argp=(struct arg_list *)malloc(sizeof(struct arg_list)+1+ + strlen(q)); + if (!argp) + { + perror("malloc"); + exit(1); + } + if (arglast) + arglast->next=argp; + else + argfirst=argp; + arglast=argp; + ++*argcp; + argp->next=0; + argp->arg=strcpy((char *)(argp+1), q); + } + + if ((*argvp=malloc(sizeof (char *) * (*argcp+1))) == 0) + { + perror("malloc"); + exit(1); + } + c=0; + for (argp=argfirst; argp; argp=argp->next) + { + (*argvp)[c]= argp->arg; + ++c; + } + (*argvp)[c]=0; +} + +static void usage() +{ + fprintf(stderr, +"Usage:\n" +" makemime -c type [-o file] [-e encoding] [-a \"Header: Contents\"] file\n" +" -m [ type ] [-o file] [-e encoding] [-a \"Header: Contents\"] file\n" +" -j [-o file] file1 file2\n" +" @file\n" +"\n" +" file: filename - read or write from filename\n" +" - - read or write from stdin or stdout\n" +" &n - read or write from file descriptor n\n" +" \\( opts \\) - read from child process, that generates [ opts ]\n" +"\n" +"Options:\n" +"\n" +" -c type - create a new mime section from \"file\" with this\n" +" Content-Type: (default is application/octet-stream).\n" +" -m [ type ] - create a multipart mime section from \"file\" of this\n" +" Content-Type: (default is multipart/mixed).\n" +" -e encoding - use the given encoding (7bit, 8bit, quoted-printable,\n" +" or base64), instead of guessing.\n" +" -j file1 file2 - join mime section file2 to multipart section file1.\n" +" -o file - write ther result to file, instead of stdout (not\n" +" allowed in child processes).\n" +" -a header - prepend an additional header to the output.\n" +"\n" +" @file - read all of the above options from file, one option or\n" +" value on each line.\n" + ); + exit (0); +} + +/****************************************************************************** + +The arguments are parsed into the following structure, as a tree. + +******************************************************************************/ +struct mimestruct { + + /* + ** One or two input files. We initialize either file or child, + ** depending on the source being a file, or a child process. + ** Later, we open a file pointer in either case. + */ + + const char *inputfile1, *inputfile2; + struct mimestruct *inputchild1, *inputchild2; + FILE *inputfp1, *inputfp2; + pid_t child1, child2; + + /* Output file. Defaults to "-", stdout */ + + const char *outputfile; + FILE *outputfp; + + /* The handler and open functions */ + + void (*handler_func)(struct mimestruct *); + void (*open_func)(struct mimestruct *); + + /* The new mime type, and encoding (-e) */ + const char *mimetype; + const char *mimeencoding; + + /* A list of -a headers */ + struct arg_list *a_first, *a_last; + } ; + +static void createsimplemime(struct mimestruct *); +static void createmultipartmime(struct mimestruct *); +static void joinmultipart(struct mimestruct *); + +static void opencreatesimplemime(struct mimestruct *); +static void opencreatemultipartmime(struct mimestruct *); +static void openjoinmultipart(struct mimestruct *); + +/****************************************************************************** + +Recursively build the mimestruct tree. + +******************************************************************************/ + +struct mimestruct *parseargs(int *argcp, char ***argvp) +{ +struct mimestruct *m=malloc(sizeof(struct mimestruct)); +int argc= *argcp; +char **argv= *argvp; + + if (!m) + { + perror("malloc"); + exit(1); + } + memset(m, 0, sizeof(*m)); + + if (argc == 0 || argv[0][0] != '-') usage(); + + if (strncmp(argv[0], "-c", 2) == 0) + { + m->handler_func= &createsimplemime; + m->open_func= &opencreatesimplemime; + if (argv[0][2]) + { + m->mimetype=argv[0]+2; + --argc; + ++argv; + } + else + { + --argc; + ++argv; + if (argc && argv[0][0] != '-' && argv[0][0] != ')') + { + m->mimetype=argv[0]; + --argc; + ++argv; + } + else + m->mimetype="application/octet-stream"; + } + + while (isspace((int)(unsigned char)*m->mimetype)) + ++m->mimetype; + } + else if (strncmp(argv[0], "-m", 2) == 0) + { + m->handler_func= &createmultipartmime; + m->open_func= &opencreatemultipartmime; + if (argv[0][2]) + { + m->mimetype=argv[0]+2; + --argc; + ++argv; + } + else + { + --argc; + ++argv; + if (argc && argv[0][0] != '-' && argv[0][0] != ')') + { + m->mimetype=argv[0]; + --argc; + ++argv; + } + else + m->mimetype="multipart/mixed"; + } + while (isspace((int)(unsigned char)*m->mimetype)) + ++m->mimetype; + } + else if (strncmp(argv[0], "-j", 2) == 0) + { + const char *filename; + + m->handler_func= &joinmultipart; + m->open_func= &openjoinmultipart; + if (argv[0][2]) + { + filename=argv[0]+2; + --argc; + ++argv; + } + else + { + --argc; + ++argv; + if (argc == 0) usage(); + filename=argv[0]; + --argc; + ++argv; + } + + while (isspace((int)(unsigned char)*filename)) + ++filename; + + if (strcmp(filename, "(") == 0) + { + m->inputchild2=parseargs(&argc, &argv); + if (argc == 0 || strcmp(argv[0], ")")) + usage(); + --argc; + ++argv; + } + else + m->inputfile2=filename; + } + + /* Handle common options */ + + while (argc) + { + if (strncmp(argv[0], "-o", 2) == 0) + { + const char *f=argv[0]+2; + + ++argv; + --argc; + if (*f == 0) + { + if (!argc) usage(); + f=argv[0]; + ++argv; + --argc; + } + while (isspace((int)(unsigned char)*f)) + ++f; + m->outputfile=f; + continue; + } + + if (strncmp(argv[0], "-e", 2) == 0) + { + char *f=argv[0]+2, *q; + + ++argv; + --argc; + + if (*f == 0) + { + if (!argc) usage(); + f=argv[0]; + ++argv; + --argc; + } + + for (q=f; *q; q++) + *q=tolower((int)(unsigned char)*q); + + while (isspace((int)(unsigned char)*f)) + ++f; + + if (strcmp(f, "7bit") && strcmp(f, "8bit") && + strcmp(f, "quoted-printable") && + strcmp(f, "base64")) + usage(); + + m->mimeencoding=f; + continue; + } + + if (strncmp(argv[0], "-a", 2) == 0) + { + char *f=argv[0]+2; + struct arg_list *a; + + ++argv; + --argc; + + if (*f == 0) + { + if (!argc) usage(); + f=argv[0]; + ++argv; + --argc; + } + + while (isspace((int)(unsigned char)*f)) + ++f; + + a=malloc(sizeof(struct arg_list)); + if (!a) + { + perror("malloc"); + exit(1); + } + if (m->a_last) + m->a_last->next=a; + else m->a_first=a; + m->a_last=a; + a->arg=f; + a->next=0; + continue; + } + break; + } + + /* We must now have the input file argument */ + + if (!argc) usage(); + + if (strcmp(argv[0], "(") == 0) + { + --argc; + ++argv; + m->inputchild1=parseargs(&argc, &argv); + if (argc == 0 || strcmp(argv[0], ")")) + usage(); + --argc; + ++argv; + } + else + { + m->inputfile1=argv[0]; + --argc; + ++argv; + } + + *argcp=argc; + *argvp=argv; + return (m); +} + +/****************************************************************************** + +After we're done, terminate with a zero exit code if all child processes also +terminated with a zero exit code. Otherwise, terminate with a non-zero exit +code thus propagating any child's non-zero exit code to parent. + +******************************************************************************/ + +static void goodexit(struct mimestruct *m, int exitcode) +{ + if (m->outputfp && (fflush(m->outputfp) || ferror(m->outputfp))) + { + perror("makemime"); + exit(1); + } + + /* + ** Drain any leftover input, so that the child doesn't get + ** a SIGPIPE. + */ + + while (m->inputfp1 && !feof(m->inputfp1) && !ferror(m->inputfp1)) + getc(m->inputfp1); + + while (m->inputfp2 && !feof(m->inputfp2) && !ferror(m->inputfp2)) + getc(m->inputfp2); + + if (m->inputfp1) + { + if (ferror(m->inputfp1)) + { + perror("makemime"); + exitcode=1; + } + + fclose(m->inputfp1); + } + if (m->inputfp2) + { + if (ferror(m->inputfp2)) + { + perror("makemime"); + exitcode=1; + } + + fclose(m->inputfp2); + } + + while (m->child1 > 0 && m->child2 > 0) + { + int waitstat; + pid_t p=wait(&waitstat); + + if (p <= 0 && errno == ECHILD) break; + + if (p == m->child1) + m->child1=0; + else if (p == m->child2) + m->child2=0; + else continue; + if (waitstat) exitcode=1; + } + exit(exitcode); +} + +int main(int argc, char **argv) +{ +struct mimestruct *m; + + signal(SIGCHLD, SIG_DFL); + if (argc > 1 && argv[1][0] == '@') + read_args(&argc, &argv, argv[1]+1); + else if (argc > 1) + { + --argc; + ++argv; + } + + m=parseargs(&argc, &argv); + if (argc) usage(); /* Some arguments left */ + + (*m->open_func)(m); + (*m->handler_func)(m); + goodexit(m, 0); + return (0); +} + +static struct mimestruct *base64m; + +static void putbase64(const char *p, size_t l) +{ + fwrite(p, 1, l, base64m->outputfp); +} + +static void createsimplemime(struct mimestruct *m) +{ +int c; +struct arg_list *a; + + /* Determine encoding by reading the file, as follows: + ** + ** Default to 7bit. Use 8bit if high-ascii bytes found. Use + ** quoted printable if lines more than 200 characters found. + ** Use base64 if a null byte is found. + */ + + if (m->mimeencoding == 0) + { + int l=0; + int longline=0; + long orig_pos=ftell(m->inputfp1); + + if (orig_pos == -1) + { + perror("ftell"); + goodexit(m, 1); + } + + m->mimeencoding="7bit"; + + while ((c=getc(m->inputfp1)) != EOF) + { + unsigned char ch= (unsigned char)c; + + if (ch >= 0x80) + m->mimeencoding="8bit"; + if (ch == 0) + { + m->mimeencoding="base64"; + longline=0; + break; + } + if (ch == '\n') l=0; + else if (++l > 200) + longline=1; + + } + if (ferror(m->inputfp1) + || fseek(m->inputfp1, orig_pos, SEEK_SET)<0) + { + perror("fseek"); + goodexit(m, 1); + } + if (longline) + m->mimeencoding="quoted-printable"; + } + + + for (a=m->a_first; a; a=a->next) + fprintf(m->outputfp, "%s\n", a->arg); + + fprintf(m->outputfp, "Content-Type: %s\n" + "Content-Transfer-Encoding: %s\n\n", + m->mimetype, m->mimeencoding); + + if (strcmp(m->mimeencoding, "quoted-printable") == 0) + { + int l=0; + int c; + + while ((c=getc(m->inputfp1)) != EOF) + { + if (l > 72) + { + fprintf(m->outputfp, "=\n"); + l=0; + } + if (c == '\n') + l=0; + else if (c < ' ' || c == '=' || c > 0x7F) + { + fprintf(m->outputfp, "=%02X", + (int)(unsigned char)c); + l += 3; + continue; + } + else ++l; + putc(c, m->outputfp); + } + return; + } + if (strcmp(m->mimeencoding, "base64") == 0) + { + char buf[BUFSIZ]; + int l; + + base64m=m; + rfc2045_base64encode_start( &putbase64 ); + while ((l=fread(buf, 1, sizeof(buf), m->inputfp1)) > 0) + rfc2045_base64encode(buf, l); + rfc2045_base64encode_end(); + return; + } + + /* 7bit or 8bit */ + + while ((c=getc(m->inputfp1)) != EOF) + putc(c, m->outputfp); +} + +/****************************************************************************** + +Satisfy paranoia by making sure that the MIME boundary we picked does not +appear in the contents of the bounded section. + +******************************************************************************/ + +static int tryboundary(struct mimestruct *m, FILE *f, const char *bbuf) +{ +char buf[BUFSIZ]; +char *p; +int l=strlen(bbuf); +int c; +long orig_pos=ftell(f); + + if (orig_pos == -1) + { + perror("ftell"); + goodexit(m, 1); + } + + while ((p=fgets(buf, sizeof(buf), f)) != 0) + { + if (p[0] == '-' && p[1] == '-' && + strncmp(p+2, bbuf, l) == 0) + break; + + if ((p=strchr(buf, '\n')) != 0) + *p=0; + else while ((c=getc(f)) != EOF && c != '\n') + ; + } + + if (ferror(f) || fseek(f, orig_pos, SEEK_SET)<0) + { + perror("fseek"); + goodexit(m, 1); + } + + return (p ? 1:0); +} + +/****************************************************************************** + +Create a MIME boundary for some content. + +******************************************************************************/ + +static const char *mkboundary(struct mimestruct *m, FILE *f) +{ +pid_t pid=getpid(); +time_t t; +static unsigned n=0; +static char bbuf[NUMBUFSIZE*4]; +char buf[NUMBUFSIZE]; + + time(&t); + + do + { + strcpy(bbuf, "=_"); + strcat(bbuf, str_size_t(++n, buf)); + strcat(bbuf, "_"); + strcat(bbuf, str_time_t(t, buf)); + strcat(bbuf, "_"); + strcat(bbuf, str_pid_t(pid, buf)); + } while (tryboundary(m, f, bbuf)); + return (bbuf); +} + +static void createmultipartmime(struct mimestruct *m) +{ +const char *b=mkboundary(m, m->inputfp1); +struct arg_list *a; +int c; + + if (m->mimeencoding == 0) + m->mimeencoding="8bit"; + + for (a=m->a_first; a; a=a->next) + fprintf(m->outputfp, "%s\n", a->arg); + fprintf(m->outputfp, "Content-Type: %s; boundary=\"%s\"\n" + "Content-Transfer-Encoding: %s\n\n" + RFC2045MIMEMSG + "\n--%s\n", + m->mimetype, b, + m->mimeencoding, + b); + while ((c=getc(m->inputfp1)) != EOF) + putc(c, m->outputfp); + fprintf(m->outputfp, "\n--%s--\n", b); +} + +static void joinmultipart(struct mimestruct *m) +{ +const char *new_boundary; +char *old_boundary=0; +int old_boundary_len=0; +char buffer[BUFSIZ]; +char *p; +int c; + + do + { + new_boundary=mkboundary(m, m->inputfp1); + } while (tryboundary(m, m->inputfp2, new_boundary)); + + /* Copy the header */ + + for (;;) + { + if (fgets(buffer, sizeof(buffer), m->inputfp2) == 0) + { + buffer[0]=0; + break; + } + + if (buffer[0] == '\n' || strncmp(buffer, "--", 2) == 0) + break; + + if (strncasecmp(buffer, "content-type:", 13)) + { + fprintf(m->outputfp, "%s", buffer); + if ((p=strchr(buffer, '\n')) != 0) continue; + while ((c=getc(m->inputfp2)) != EOF && c != '\n') + putc(c, m->outputfp); + continue; + } + + if ((p=strchr(buffer, '\n')) == 0) + while ((c=getc(m->inputfp2)) != EOF && c != '\n') + ; + + p=strchr(buffer+13, ';'); + if (p) *p=0; + fprintf(m->outputfp, "Content-Type:%s; boundary=\"%s\"\n", + buffer+13, new_boundary); + + for (;;) + { + c=getc(m->inputfp2); + if (c != EOF) ungetc(c, m->inputfp2); + if (c == '\n' || !isspace((int)(unsigned char)c)) + break; + while ((c=getc(m->inputfp2)) != EOF && c != '\n') + ; + } + } + + do + { + if (strncmp(buffer, "--", 2) == 0) + { + if (old_boundary == 0) + { + old_boundary=malloc(strlen(buffer)+1); + if (!old_boundary) + { + perror("malloc"); + exit(1); + } + strcpy(old_boundary, buffer); + if ((p=strchr(old_boundary, '\n')) != 0) + *p=0; + p=old_boundary+strlen(old_boundary); + if (p >= old_boundary+4 && + strcmp(p-2, "--") == 0) + p[-2]=0; + old_boundary_len=strlen(old_boundary); + } + + + if (strncasecmp(buffer, old_boundary, + old_boundary_len) == 0) + { + if ((p=strchr(buffer, '\n')) != 0) + *p=0; + else while ((c=getc(m->inputfp2)) != '\n' + && c != EOF) + ; + + c=strlen(buffer); + if (c >= 4 && strcmp(buffer+(c-2), "--") == 0) + break; + fprintf(m->outputfp, "--%s\n", + new_boundary); + continue; + } + } + fprintf(m->outputfp, "%s", buffer); + if ((p=strchr(buffer, '\n')) == 0) + while ((c=getc(m->inputfp2)) != '\n' && c != EOF) + ; + } while (fgets(buffer, sizeof(buffer), m->inputfp2) != 0); + + fprintf(m->outputfp, "--%s\n", new_boundary); + + while ((c=getc(m->inputfp1)) != EOF) + putc(c, m->outputfp); + + fprintf(m->outputfp, "\n--%s--\n", new_boundary); + goodexit(m, 0); +} + +/****************************************************************************** + +Open input from a child process + +******************************************************************************/ + +static FILE *openchild(struct mimestruct *parent, struct mimestruct *child, + pid_t *pidptr, + int usescratch) +{ +int pipefd[2]; +char buf[NUMBUFSIZE]; +char buf2[NUMBUFSIZE+1]; +FILE *fp; + + if (pipe(pipefd) < 0) + { + perror("pipe"); + exit(1); + } + + *pidptr=fork(); + + if (*pidptr < 0) + { + perror("fork"); + exit(1); + } + + if (*pidptr == 0) + { + /* Duplicate pipe on stdout */ + + close(pipefd[0]); + close(1); + dup(pipefd[1]); + close(pipefd[1]); + + /* Close any input files opened by parent */ + + if (parent->inputfp1) fclose(parent->inputfp1); + if (parent->inputfp2) fclose(parent->inputfp2); + + /* Open, then execute the child process */ + + (*child->open_func)(child); + (*child->handler_func)(child); + goodexit(child, 0); + } + close(pipefd[1]); + + /* + ** Open the pipe by calling openfile(), automatically creating + ** the scratch file, if necessary. + */ + + buf[0]='&'; + strcpy(buf+1, str_size_t(pipefd[0], buf2)); + + fp= usescratch ? openfile(buf):openfile_or_pipe(buf, "r"); + close(pipefd[0]); /* fd was duped by openfile */ + return (fp); +} + +static void openoutput(struct mimestruct *m) +{ + if (!m->outputfile) + m->outputfile="-"; + + m->outputfp= openfile_or_pipe(m->outputfile, "w"); +} + +static void openjoinmultipart(struct mimestruct *m) +{ + /* number two is the multipart section */ + if (m->inputchild2) + m->inputfp2=openchild(m, m->inputchild2, &m->child2, 1); + else + m->inputfp2=openfile(m->inputfile2); + + + if (m->inputchild1) + m->inputfp1=openchild(m, m->inputchild1, &m->child1, 1); + else + m->inputfp1=openfile(m->inputfile1); + openoutput(m); +} + +static void opencreatesimplemime(struct mimestruct *m) +{ + if (m->inputchild1) + m->inputfp1=openchild(m, m->inputchild1, &m->child1, + m->mimeencoding ? 0:1); + else + m->inputfp1= m->mimeencoding + ? openfile_or_pipe(m->inputfile1, "r") + : openfile(m->inputfile1); + openoutput(m); +} + +static void opencreatemultipartmime(struct mimestruct *m) +{ + if (m->inputchild1) + m->inputfp1=openchild(m, m->inputchild1, &m->child1, 1); + else + m->inputfp1=openfile_or_pipe(m->inputfile1, "r"); + openoutput(m); +} + diff --git a/packages/clib/maildrop/rfc2045/makemime.html b/packages/clib/maildrop/rfc2045/makemime.html new file mode 100644 index 000000000..9f75fce81 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/makemime.html @@ -0,0 +1,362 @@ + + + + makemime - MIME utility + + + + + + +

makemime - MIME utility

+ +

SYNOPSIS

+makemime [options] + +

makemime @file

+ +

DESCRIPTION

+ +

The makemime tool creates MIME-encoded messages of arbitrary +complexity. makemime reads one or more individual files, encodes them +appropriately, adds basic MIME headers, and adds additional headers specified +via command line options. The result is saved to another file or standard +output. Complex MIME-encoded messages are created by using options that direct +makemime to run additional instances of itself, as child processes. The +child processes create individual parts of a complex MIME message, then the +parent makemime process combines them together.

+ +

In simple cases, options for makemime are specified directly on the +command line. @file specifies that options will be read from a file. +"@&n" reads options from a pipe on file descriptor #n. "@-" is a shortcut for +"@&0", which reads options from standard input.

+ +

When options are read from a file or a pipe, each option must be on a line +by itself. If an option requires an argument, the argument must follow on the +next line.

+ +

For readability, leading whitespace on each line is deleted when options +are read from a file or a pipe. Empty lines are also ignored, as well as lines +that begin with the '#' character.

+ +

Options and their arguments may contain characters that are special +characters to the shell, such as '(' and ')'. These characters must be +backslashed when specified on the command line, to avoid their special meaning +to the shell. These characters MUST NOT be backslashed when options are read +from a file or a pipe. Similarly, the contents of most headers nearly always +include spaces. Therefore they must be quoted when specified on the command +line. Header contents MUST NOT be quoted when options come from a file or a +pipe.

+ +

makemime reads the contents to be encoded into a MIME message from +other files. Those files can also be pipes. It is possible to supply both the +options and a file from the same pipe, by terminating the list of option with +a line containing the single character "-". The remainder of the pipe will be +available to be used as an input file (which must be explicitly specified via +some other option). Of course, only one input file can come from a single +pipe.

+ +

MIME overview

+ +

A MIME message consists of one or several MIME sections. MIME headers +specify how multiple MIME sections are to be interpreted as a whole (whether +they are attached together, or whether they are alternative representations of +the same object, or something even more esoteric). This manual page gives a +very brief, terse, overview of basic MIME concepts. The description is biased +towards describing the functionality of the makemime utility. The +complete description of MIME encoding is found in RFCs 2045 through 2048, +where a formal definition is found.

+ +

Each file in a MIME message is encoded as a single MIME section. A MIME +section consists of at least one header line, "Content-Type". The +"Content-Type" headers gives the type of the data contained in the file. Other +header lines may also be present. Their relative order does not matter. MIME +headers are followed by a blank line, then the contents of the file, encoded +appropriately. All MIME sections generated by makemime will always +contain another header, "Content-Transfer-Encoding". This header gives the +encoding method used for the file.

+ +

The encoding method defaults to "7bit" if this header is absent. 7bit +encoding is only suitable for plain text messages in the US-ASCII character +set. The "8bit" encoding method is used by plain text messages in other +character sets which contain high-bit characters, with their 8th bit set. An +alternative to 8bit encoding is "quoted-printable". The "base64" encoding +method is used for files containing binary data.

+ +

MIME sections that contain text messages have their "Content-Type" header +set to "text/plain"; or "text/html" for HTML messages. There are also several +other, rare, content types that can be used. MIME sections that contain other +kinds of data will use some other, appropriate Content-Type header, such as +"image/gif", or "audio/x-wav".

+ +

MIME sections that contain textual content may use the base64 encoding +method, they are not required to use 7bit, 8bit, or quoted-printable. +"text/pdf" sections, that contain PDF files, typically consist of binary data, +and must use base64 encoding. Consequently, MIME sections that typically +contain binary data, such as image/gif and audio/x-wav, are free to use other +encoding methods besides base64, as long as all the data can be represented by +printable characters (but, in practice, that never happens).

+ +

MIME sections may also contain other, optional, headers such as +"Content-Disposition", "Content-ID", and "Content-Name". Consult the +appropriate RFCs for the specific usage of these headers. These headers can be +added by makemime by using the -a option, as described below. These +headers play no part in creating the overall structure of a MIME-encoded +message, and makemime does not care much about these headers. It simply +includes them, and their content, upon request.

+ +

Multiple files are encoded into a single message by initially creating a +MIME section for each file, and then creating a single MIME section that +contains other MIME sections. A "multipart/mixed" MIME section contains a +collection of MIME sections that represent different objects, attached +together. A "multipart/alternative" MIME section contains a collection of MIME +sections which are alternative representations of the same object, such as an +HTML and a plain text version of the same message. Other "multipart" MIME +sections also exist, and their usage is defined by their respective RFCs.

+ +

Creating a single MIME section

+
    makemime -c "type" [-e "encoding"] [-o file] \
+            [-a "header: value"] [-a "header: value"] file
+ +

The -c option reads file, encodes it appropriately, adds a +"Content-Type" and "Content-Transfer-Encoding" MIME headers, then writes the +result to standard output. type can be any valid MIME type, except for +multipart. file can be "-", which specifies standard input. file +can be "&n" to read the file from file descriptor #n.

+ +

The optional encoding argument should be specified. It's more +efficient to do so. encoding must be one of the following: 7bit, 8bit, +quoted-printable, or base64.

+ +

If encoding is not specified, makemime reads the file +twice - once to select the best encoding method, and the second time to encode +it. If file is a pipe makemime will be forced to create a +temporary file, which is less efficient if the file is large. However +letting makemime pick the encoding is probably more convenient if files +are relatively small.

+ +

By default the encoded MIME section is written to standard output. The -o +option writes the MIME section to a file. file can be "&n", +which writes the MIME section to a pipe on file descriptor #n.

+ +

makemime does not generate any other headers. Particularly, the +"Mime-Version" header (and others) is required to send a MIME message via +E-mail. Additional headers are specified by the -a option, which may be used +multiple times to insert multiple headers. makemime doesn't do anything +with them except to insert the headers into the generated MIME section.

+ +

Note that "Mime-Version" is only required for the top level MIME section. +This header is not required for individual MIME sections that are later +combined into a multipart MIME collection.

+ +

Note that the -c option is required to be listed first, the remaining +options must follow the -c option.

+ +

Creating a multipart MIME collection

+
    makemime -m "type" [-e "encoding"] [-o file] \
+            [-a "header: value"] [-a "header: value"] file
+ +

The -m option is identical in usage to the -c option, except for three +differences.

+ +

type must be either "multipart/mixed", "multipart/alternative", or +some other MIME multipart content type. Additionally, "encoding" can only be +"7bit" or "8bit", and will default to "8bit" if not specified. Finally, +file must be a MIME-encoded section, NOT a regular file. Usually +file is also created by makemime (it can also be a pipe, like +the -c option), but it can be created via any other means.

+ +

The -m option creates an initial multipart MIME collection, that contains +only one MIME section, taken from file. The collection is written to +standard output, or the pipe or the file specified by the -o option. The -j +option is used to add additional MIME sections to this collection.

+ +

Creating a multipart MIME section

+
    makemime -j file1 [-o file] file2
+ +

This option appends a MIME section to an existing MIME collection. +file1 contains a MIME collection that's been created by the -m option. +file2 must contain a MIME section that's been created by the -c option. +The MIME section in file2 is appended after the last MIME section in +file1. The result is written to standard output or the file specified +by the -o option.

+ +

file1 and/or file2 can be "&n", which reads the corresponding +file from a pipe on the indicated file descriptor. The -o option, as always, +can also specify a file descriptor.

+ +

file1 and file2 should ideally be created by makemime +as well. It's also possible to use files created by other software, but with +some degree of care. makemime is not intended to be a MIME parser, but +a MIME generator. However some amount of MIME parsing is necessary to append a +MIME section to an existing MIME collection. makemime's parsing does a +sufficient job to append a new section to a MIME collection, as long as the +MIME headers in the MIME collections are straightforward. Very convoluted MIME +headers may confuse makemime, and it may not be able to handle +them.

+ +

Recursive MIME collections

+ +

MIME collection may contain other MIME collections as well as MIME +sections. The -m and the -j option may use a multipart MIME collection in +place of a MIME section automatically, simply because a multipart MIME +collection is just a special type of a MIME section. The following example +encodes a text message that can be alternatively represented as HTML or plain +text, with some additional attachments:

+ +

1. Create a MIME collection containing a text/plain and a text/html MIME +section.

+ +

2. Create a MIME collection consisting of the MIME section generated in +step one, plus additional MIME sections containing other attachments.

+ +

For example:

+
    # Take two files containing the text and the html version of a message, and
+    # add MIME headers to them.
+
+    makemime -c "text/plain; charset=iso-8859-1" -o tmp1.txt msg.txt
+    makemime -c "text/html; charset=iso-8859-1" -o tmp1.html msg.html
+
+    # Combine the result into a multipart/alternative collection
+
+    makemime -m "multipart/alternative" -a "Content-Disposition: inline" \
+                                        -o tmp.ma1 tmp1.txt
+    makemime -j tmp.ma1 -o tmp.ma2 tmp1.html
+
+    # Add MIME headers to an image attachment.
+
+    makemime -c "image/gif" -a "Content-Disposition: attachment" \
+                            -o tmp2.gif attachment.gif
+
+    # Create the final multipart/mixed collection
+
+    makemime -m "multipart/mixed" -a "Mime-Version: 1.0" \
+                                  -o tmp.mm1 tmp.ma2
+    makemime -j tmp.mm1 -o output.msg tmp2.gif
+ +

output.msg now contains the complete MIME collection. Just add the +subject, from, and to headers (can also be done by additional -a options, of +course), and send it on its way.

+ +

Building complex MIME encodings

+ +

There are several different ways to build complete MIME encodings from +multiple MIME sections. One way is to use temporary files to create MIME +sections, then combine them together into a single MIME collection. A slightly +more complicated approach involves setting up pipes between multiple makemime +processes, in order to avoid using temporary files.

+ +

This can be done manually, by hand. It is also possible to have +makemime do this automatically. makemime will set up these pipes +and run multiple instances of itself to create a single MIME collection, with +multiple attachments of arbitrary complexity.

+ +

Any file that's read by the -c, -m, and -j options (-o specifies a file to +create, and doesn't count) may be replaced by a single argument containing a +left parenthesis, additional options, then a single argument containing a +right parenthesis. A single invocation of makemime can only use one -c, +-m, or -j option. However, another -c, -m, or -j option may be specified +inside the left and the right parenthesis, and its output is used in place of +the file it replaced. In the previous example the third and the fourth +invocation of makemime can be replaced with the following command:

+
    makemime -j \(                           \
+                   -m "multipart/alternative" \
+                   -a "Content-Disposition: inline" tmp1.txt \
+                 \) -o tmp.ma2                    \
+                 tmp1.html
+ +

Note that the parenthesis must be backslashed, to avoid their special +meaning to the shell. An equivalent argument file would have the following +contents:

+
    -j
+       (
+          -m
+              multipart/alternative
+          -a
+              Content-Disposition: inline
+          tmp1.txt
+       )
+       -o
+          tmp.ma2
+     tmp1.html
+ +

These constructs can be arbitrarily nested, and are limited by the amount +of available memory and resources. The entire sequence in the previous +section is equivalent to the following command:

+
    makemime -j                                                 \
+             \(                                                 \
+                -m "multipart/mixed"                            \
+                -a "Mime-Version: 1.0"                          \
+                \(                                              \
+                    -j                                          \
+                    \(                                          \
+                       -m "multipart/alternative"               \
+                       -a "Content-Disposition: inline"         \
+                       \(                                       \
+                          -c "text/plain; charset=iso-8859-1"   \
+                          msg.txt                               \
+                       \)                                       \
+                    \)                                          \
+                    \(                                          \
+                        -c "text/html; charset=iso-8859-1"      \
+                        msg.html                                \
+                    \)                                          \
+                \)                                              \
+             \)                                                 \
+             -o output.msg                                      \
+             \(                                                 \
+                -c "image/gif"                                  \
+                -a "Content-Disposition: attachment"            \
+                attachment.gif                                  \
+             \)
+ +

An equivalent argument file would be:

+
    -j
+    (
+       -m
+           multipart/mixed
+       -a
+           Mime-Version: 1.0
+       (
+           -j
+           (
+               -m
+                   multipart/alternative
+               -a
+                   Content-Disposition: inline
+               (
+                   -c
+                       text/plain; charset=iso-8859-1
+                   msg.txt
+               )
+           )
+           (
+               -c
+                   text/html; charset=iso-8859-1
+               msg.html
+           )
+       )
+    )
+    -o
+       output.msg
+    (
+       -c
+           image/gif
+       -a
+           Content-Disposition: attachment
+       attachment.gif
+    )
+ +

SEE ALSO

+maildrop(1), maildropfilter(1), reformail(1), reformime(1), egrep(1), grep(1), courier(8), sendmail(8), RFC 2045, RFC 2046, RFC 2047, RFC 2048. + diff --git a/packages/clib/maildrop/rfc2045/reformime.c b/packages/clib/maildrop/rfc2045/reformime.c new file mode 100644 index 000000000..030ead0ac --- /dev/null +++ b/packages/clib/maildrop/rfc2045/reformime.c @@ -0,0 +1,962 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#include +#include +#include +#include +#include +#include "rfc2045.h" +#include "rfc822/rfc2047.h" +#include "rfc2045charset.h" +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SYS_WAIT_H +#include +#endif +//#include "numlib/numlib.h" + +#if HAS_GETHOSTNAME +#else +int gethostname(const char *, size_t); +#endif + + +static const char rcsid[]="$Id$"; + +void rfc2045_error(const char *errmsg) +{ + fprintf(stderr, "reformime: %s\n", errmsg); + exit(1); +} + +static void do_print_structure(struct rfc2045 *p, struct rfc2045id *id, void *ptr) +{ + p=p; + ptr=p; + + while (id) + { + printf("%d%c", id->idnum, id->next ? '.':'\n'); + id=id->next; + } +} + +static int decode_to_file(const char *p, size_t n, void *ptr) +{ +FILE *fp=(FILE *)ptr; + + while (n) + { + --n; + if (putc(*p++, fp) == -1) + { + perror("write"); + exit(1); + } + } + return (0); +} + +void usage() +{ + fprintf(stderr, "Usage: reformime [options]\n"); + fprintf(stderr, " -d - parse a delivery status notification.\n"); + fprintf(stderr, " -e - extract contents of MIME section.\n"); + fprintf(stderr, " -x - extract MIME section to a file.\n"); + fprintf(stderr, " -X - pipe MIME section to a program.\n"); + fprintf(stderr, " -i - show MIME info.\n"); + fprintf(stderr, " -s n.n.n.n - specify MIME section.\n"); + fprintf(stderr, " -r - rewrite message, filling in missing MIME header.\n"); + fprintf(stderr, " -r7 - also convert 8bit/raw encoding to quoted-printable, if possible.\n"); + fprintf(stderr, " -r8 - also convert quoted-printable encoding to 8bit, if possible.\n"); + fprintf(stderr, " -c charset - when rewriting, specify default charset.\n"); + fprintf(stderr, " -m [file] [file]... - create a MIME message digest.\n"); + exit(1); +} + +static char *tempname(const char *tempdir) +{ +char pidbuf[NUMBUFSIZE], timebuf[NUMBUFSIZE], hostnamebuf[256]; +static unsigned counter=0; +time_t t; +char *p; + + str_pid_t(getpid(), pidbuf); + time(&t); + str_time_t(t, timebuf); + hostnamebuf[sizeof(hostnamebuf)-1]=0; + if (gethostname(hostnamebuf, sizeof(hostnamebuf))) + hostnamebuf[0]=0; + p=malloc(strlen(tempdir)+strlen(pidbuf)+strlen(timebuf)+ + strlen(hostnamebuf)+100); + if (!p) return (0); + sprintf(p, "%s/%s.%s-%u.%s", tempdir, timebuf, pidbuf, counter++, + hostnamebuf); + return (p); +} + +struct rfc2045 *read_message() +{ +char buf[BUFSIZ]; +struct rfc2045 *p=rfc2045_alloc_ac(); +FILE *tempfp=0; + + if (fseek(stdin, 0L, SEEK_END) < 0 || + fseek(stdin, 0L, SEEK_SET) < 0) /* Pipe, save to temp file */ + { + tempfp=tmpfile(); + } + + while (fgets(buf, sizeof(buf), stdin)) + { + int l=strlen(buf); + + rfc2045_parse(p, buf, l); + if (tempfp && fwrite(buf, l, 1, tempfp) != 1) + { + perror("fwrite"); + exit(1); + } + } + + if (tempfp) /* Replace stdin */ + { + close(0); + dup(fileno(tempfp)); + fclose(tempfp); + } + return (p); +} + +void print_structure(struct rfc2045 *p) +{ + rfc2045_decode(p, &do_print_structure, 0); +} + +static void notfound(const char *p) +{ + fprintf(stderr, "reformime: MIME section %s not found.\n", p); + exit(1); +} + +static void do_print_info(struct rfc2045 *s) +{ +const char *content_type, *transfer_encoding, *charset; +off_t start, end, body; +const char *disposition; +const char *disposition_name; +const char *disposition_filename; +const char *content_name; +off_t nlines, nbodylines; +const char *p; + + rfc2045_mimeinfo(s, &content_type, &transfer_encoding, &charset); + rfc2045_mimepos(s, &start, &end, &body, &nlines, &nbodylines); + rfc2045_dispositioninfo(s, &disposition, &disposition_name, + &disposition_filename); + content_name=rfc2045_contentname(s); + printf("content-type: %s\n", content_type); + if (content_name) + { + char *s=rfc2047_decode_simple(content_name); + + if (!s) + { + perror("rfc2047_decode_simple"); + exit(1); + } + printf("content-name: %s\n", s); + free(s); + } + + printf("content-transfer-encoding: %s\n", transfer_encoding); + printf("charset: %s\n", charset); + if (disposition && *disposition) + printf("content-disposition: %s\n", disposition); + if (disposition_name && *disposition_name) + { + char *s=rfc2047_decode_simple(disposition_name); + + if (!s) + { + perror("rfc2047_decode_simple"); + exit(1); + } + printf("content-disposition-name: %s\n", s); + free(s); + } + + if (disposition_filename && *disposition_filename) + { + char *s=rfc2047_decode_simple(disposition_filename); + + if (!s) + { + perror("rfc2047_decode_simple"); + exit(1); + } + printf("content-disposition-filename: %s\n", s); + free(s); + } + + if (*(p=rfc2045_content_id(s))) + printf("content-id: <%s>\n", p); + if (*(p=rfc2045_content_description(s))) + { + char *s=rfc2047_decode_simple(p); + + if (!s) + { + perror("rfc2047_decode_simple"); + exit(1); + } + printf("content-description: %s\n", s); + free(s); + } + if (*(p=rfc2045_content_language(s))) + printf("content-language: %s\n", p); + if (*(p=rfc2045_content_md5(s))) + printf("content-md5: %s\n", p); + + printf("starting-pos: %lu\n", (unsigned long)start); + printf("starting-pos-body: %lu\n", (unsigned long)body); + printf("ending-pos: %lu\n", (unsigned long)end); + printf("line-count: %lu\n", (unsigned long)nlines); + printf("body-line-count: %lu\n", (unsigned long)nbodylines); +} + +static void do_print_info_multiple(struct rfc2045 *p, struct rfc2045id *id, + void *ptr) +{ + printf("section: "); + do_print_structure(p, id, ptr); + do_print_info(p); + printf("\n"); +} + +void print_info(struct rfc2045 *p, const char *mimesection) +{ +struct rfc2045 *s; + + if (mimesection) + { + s=rfc2045_find(p, mimesection); + if (!s) + notfound(mimesection); + printf("section: %s\n", mimesection); + do_print_info(s); + return; + } + rfc2045_decode(p, &do_print_info_multiple, 0); +} + +static void do_print_section(struct rfc2045 *s, FILE *fp) +{ +off_t start, end, body; +off_t nlines; +off_t nbodylines; + + rfc2045_mimepos(s, &start, &end, &body, &nlines, &nbodylines); + + if (fseek(stdin, body, SEEK_SET) == -1) + { + perror("fseek"); + exit(1); + } + + rfc2045_cdecode_start(s, &decode_to_file, fp); + while (body < end) + { + char buf[BUFSIZ]; + size_t n=sizeof(buf); + + if ((off_t)n > end-body) n=end-body; + n=fread(buf, 1, n, stdin); + if (n == 0) + { + perror("fread"); + exit(1); + } + rfc2045_cdecode(s, buf, n); + body += n; + } + rfc2045_cdecode_end(s); +} + +void print_decode(struct rfc2045 *p, const char *mimesection) +{ +struct rfc2045 *s; + + if (!mimesection) + usage(); + + s=rfc2045_find(p, mimesection); + if (!s) + notfound(mimesection); + + do_print_section(s, stdout); +} + +void rewrite(struct rfc2045 *p, int rwmode) +{ + rfc2045_ac_check(p, rwmode); + if (rfc2045_rewrite(p, fileno(stdin), fileno(stdout), + "reformime (" RFC2045PKG " " RFC2045VER ")")) + { + perror("reformime"); + exit(1); + } +} + +static char *get_suitable_filename(struct rfc2045 *r, const char *pfix, + int ignore_filename) +{ +const char *disposition_s; +const char *disposition_name_s; +const char *disposition_filename_s; +char *filename_buf; +const char *content_name_s; +char *p, *q; +char *dyn_disp_name=0; + + rfc2045_dispositioninfo(r, &disposition_s, &disposition_name_s, + &disposition_filename_s); + + content_name_s=rfc2045_contentname(r); + + if (!disposition_filename_s || !*disposition_filename_s) + disposition_filename_s=disposition_name_s; + if (!disposition_filename_s || !*disposition_filename_s) + disposition_filename_s=content_name_s; + + filename_buf=rfc2047_decode_simple(disposition_filename_s); + + if (!filename_buf) + { + perror("rfc2047_decode_simple"); + exit(1); + } + + if (strlen(filename_buf) > 32) + { + p=filename_buf; + q=filename_buf + strlen(filename_buf)-32; + while ( (*p++ = *q++) != 0) + ; + } + + disposition_filename_s=filename_buf; + + if (ignore_filename) + { + char numbuf[NUMBUFSIZE]; + static size_t counter=0; + const char *p=str_size_t(++counter, numbuf); + + dyn_disp_name=malloc(strlen(disposition_filename_s) + + strlen(p)+2); + if (!dyn_disp_name) + { + perror("malloc"); + exit(1); + } + disposition_filename_s=strcat(strcat(strcpy( + dyn_disp_name, p), "-"), + disposition_filename_s); + } + else if (!disposition_filename_s || !*disposition_filename_s) + { + dyn_disp_name=tempname("."); + disposition_filename_s=dyn_disp_name+2; /* Skip over ./ */ + } + + p=malloc((pfix ? strlen(pfix):0)+strlen(disposition_filename_s)+1); + if (!p) + { + perror("malloc"); + exit(1); + } + *p=0; + if (pfix) strcpy(p, pfix); + q=p+strlen(p); + for (strcpy(q, disposition_filename_s); *q; q++) + if (!isalnum(*q) && *q != '.' && *q != '-') + *q='_'; + + if (dyn_disp_name) free(dyn_disp_name); + + if (!pfix) + { + const char *content_type_s; + const char *content_transfer_encoding_s; + const char *charset_s; + int c; + static char filenamebuf[256]; + char *t; + FILE *tty; + + if ((tty=fopen("/dev/tty", "r+")) == 0) + { + perror("/dev/tty"); + exit(1); + } + + rfc2045_mimeinfo(r, &content_type_s, + &content_transfer_encoding_s, &charset_s); + + fprintf (tty, "Extract %s? ", content_type_s); + fflush(tty); + c=getc(tty); + if (c != '\n' && c != EOF) + { + int cc; + + while ((cc=getc(tty)) != '\n' && cc != EOF) + ; + } + if (c != 'y' && c != 'Y') + { + free(p); + fclose(tty); + free(filename_buf); + return (0); + } + fprintf (tty, "Filename [%s]: ", p); + fgets(filenamebuf, sizeof(filenamebuf)-1, tty); + fclose(tty); + t=strchr(filenamebuf, '\n'); + if (t) *t=0; + else + { + fprintf(stderr, "Filename too long.\n"); + exit(1); + } + if (filenamebuf[0]) + { + free(p); + p=strdup(filenamebuf); + if (!p) + { + perror("malloc"); + exit(1); + } + } + } + free(filename_buf); + return (p); +} + +static void extract_file(struct rfc2045 *p, + const char *filename, int argc, char **argv) +{ +char *f; +FILE *fp; +int ignore=0; + + for (;;) + { + int fd; + + f=get_suitable_filename(p, filename, ignore); + if (!f) return; + + fd=open(f, O_WRONLY|O_CREAT|O_EXCL, 0666); + if (fd < 0) + { + if (errno == EEXIST) + { + printf("%s exists.\n", f); + free(f); + ignore=1; + continue; + } + + perror(f); + exit(1); + } + fp=fdopen(fd, "w"); + if (!fp) + { + perror("fdopen"); + exit(1); + } + break; + } + + do_print_section(p, fp); + if (fflush(fp) || ferror(fp)) + { + perror("write"); + exit(1); + } + fclose(fp); + free(f); +} + +static void extract_pipe(struct rfc2045 *p, + const char *filename, + int argc, char **argv) +{ +char *f=get_suitable_filename(p, "FILENAME=", 0); +int pipefd[2]; +pid_t pid, p2; +FILE *fp; +int waitstat; + + if (argc == 0) + { + fprintf(stderr, "reformime: Invalid -X option.\n"); + exit(1); + } + + if (pipe(pipefd)) + { + perror("pipe"); + exit(1); + } + + if ((fp=fdopen(pipefd[1], "w")) == 0) + { + perror("fdopen"); + exit(1); + } + + while ((pid=fork()) == -1) + { + sleep(2); + } + + if (pid == 0) + { + const char *content_type_s; + const char *content_transfer_encoding_s; + const char *charset_s; + + if (!f) f="FILENAME=attachment.dat"; + putenv(f); + rfc2045_mimeinfo(p, &content_type_s, + &content_transfer_encoding_s, &charset_s); + f=malloc(strlen(content_type_s) + +sizeof("CONTENT_TYPE=")); + if (!f) + { + perror("malloc"); + exit(1); + } + strcat(strcpy(f, "CONTENT_TYPE="), content_type_s); + putenv(f); + close(0); + dup(pipefd[0]); + close(pipefd[0]); + close(pipefd[1]); + execv(argv[0], argv); + perror("exec"); + _exit(1); + } + close(pipefd[0]); + signal(SIGPIPE, SIG_IGN); + do_print_section(p, fp); + signal(SIGPIPE, SIG_DFL); + fclose(fp); + close(pipefd[1]); + + while ((p2=wait(&waitstat)) != pid && p2 != -1) + ; + free(f); +} + +static void extract_section(struct rfc2045 *top_rfcp, const char *mimesection, + const char *extract_filename, int argc, char **argv, + void (*extract_func)(struct rfc2045 *, const char *, + int, char **)) +{ + if (mimesection) + { + top_rfcp=rfc2045_find(top_rfcp, mimesection); + if (!mimesection) + notfound(mimesection); + if (top_rfcp->firstpart) + { + fprintf(stderr, "reformime: MIME section %s is a compound section.\n", mimesection); + exit(1); + } + (*extract_func)(top_rfcp, extract_filename, argc, argv); + return; + } + + /* Recursive */ + + if (top_rfcp->firstpart) + { + for (top_rfcp=top_rfcp->firstpart; top_rfcp; + top_rfcp=top_rfcp->next) + extract_section(top_rfcp, mimesection, + extract_filename, argc, argv, extract_func); + return; + } + + if (!top_rfcp->isdummy) + (*extract_func)(top_rfcp, extract_filename, argc, argv); +} + +static void print_dsn_recip(char *addr, char *action) +{ +char *p, *q; + + if (!action || !addr) + { + if (action) free(action); + if (addr) free(addr); + return; + } + + for (p=action; *p; ++p) + *p=tolower((int)(unsigned char)*p); + + for (p=addr; *p && isspace((int)(unsigned char)*p); ++p) + ; + + if (strncasecmp(p, "rfc822;", 7)) + { + free(action); + free(addr); + return; + } + for (q=action; *q && isspace((int)(unsigned char)*q); ++q) + ; + p += 7; + while (*p && isspace((int)(unsigned char)*p)) + ++p; + printf("%s %s\n", q, p); + free(action); + free(addr); +} + +static void dsn(struct rfc2045 *p, int do_orig) +{ +const char *content_type_s; +const char *content_transfer_encoding_s; +const char *charset_s; +off_t start_pos, end_pos, start_body; +off_t dummy; +const char *q; +char buf[BUFSIZ]; +unsigned i; +int ch; +char *recip; +char *action; +char *orecip; + + rfc2045_mimeinfo(p, &content_type_s, &content_transfer_encoding_s, + &charset_s); + if (strcasecmp(content_type_s, "multipart/report") || + (q=rfc2045_getattr(p->content_type_attr, "report-type")) == 0 || + strcasecmp(q, "delivery-status") || + !p->firstpart || !p->firstpart->next || + !p->firstpart->next->next) + _exit(1); + p=p->firstpart->next->next; + rfc2045_mimeinfo(p, &content_type_s, &content_transfer_encoding_s, + &charset_s); + rfc2045_mimepos(p, &start_pos, &end_pos, &start_body, &dummy, &dummy); + if (strcasecmp(content_type_s, "message/delivery-status") || + fseek(stdin, start_body, SEEK_SET) == -1) + _exit(1); + + i=0; + recip=0; + orecip=0; + action=0; + while (start_body < end_pos) + { + if ((ch=getchar()) == EOF) break; + ++start_body; + if (i < sizeof(buf)-1) + buf[i++]= ch; + if (ch != '\n') continue; + ch=getchar(); + if (ch != EOF) ungetc(ch, stdin); + if (ch != '\n' && isspace((int)(unsigned char)ch)) + continue; + buf[i-1]=0; + if (buf[0] == 0) + { + if (orecip) + { + if (recip) free(recip); + recip=orecip; + orecip=0; + } + print_dsn_recip(recip, action); + recip=0; + action=0; + } + if (strncasecmp(buf, "Final-Recipient:", 16) == 0 && + recip == 0) + { + recip=strdup(buf+16); + if (!recip) + { + perror("strdup"); + exit(2); + } + } + if (strncasecmp(buf, "Original-Recipient:", 19) == 0 && + orecip == 0 && do_orig) + { + orecip=strdup(buf+19); + if (!orecip) + { + perror("strdup"); + exit(2); + } + } + if (strncasecmp(buf, "Action:", 7) == 0 && action == 0) + { + action=strdup(buf+7); + if (!action) + { + perror("strdup"); + exit(2); + } + } + i=0; + } + if (orecip) + { + if (recip) free(recip); + recip=orecip; + orecip=0; + } + print_dsn_recip(recip, action); +} + +static void mimedigest1(int, char **); +static char mimebuf[BUFSIZ]; + +static void mimedigest(int argc, char **argv) +{ +char *p; +struct filelist { struct filelist *next; char *fn; } *first=0, *last=0; +unsigned pcnt=0; +char **l; + + if (argc > 0) + { + mimedigest1(argc, argv); + return; + } + + while (fgets(mimebuf, sizeof(mimebuf), stdin)) + { + struct filelist *q; + + if ((p=strchr(mimebuf, '\n')) != 0) *p=0; + q=malloc(sizeof(struct filelist)); + if (!q || !(q->fn=strdup(mimebuf))) + { + perror("malloc"); + exit(1); + } + + if (last) last->next=q; + else first=q; + last=q; + q->next=0; + ++pcnt; + } + if (pcnt == 0) return; + + if ( (l=malloc(sizeof (char *) * pcnt)) == 0) + { + perror("malloc"); + } + pcnt=0; + + for (last=first; last; last=last->next) + l[pcnt++]=last->fn; + + mimedigest1(pcnt, l); +} + +static void mimedigest1(int argc, char **argv) +{ +time_t t; +char boundarybuf[200]; +unsigned boundarycnt=0; +int i; +FILE *fp; + + time (&t); + + /* Search for a suitable boundary */ + + do + { + int l; + + sprintf(boundarybuf, "reformime_%lu_%u", + (unsigned long)t, ++boundarycnt); + + l=strlen(boundarybuf); + + for (i=0; i + + + reformime - MIME utility + + + + + + +

reformime - MIME utility

+ +

SYNOPSIS

+reformime [options] ... + +

DESCRIPTION

+ +

reformime is a tool for manipulating MIME messages and +attachments.

+ +

reformime expects to see an RFC 2045, message on +standard input.

+ +

If no options are given, reformime prints the MIME structure of the +message. The output consists of so-called "MIME reference tags", one per line. +For example, you might see the following output:

+
 
+    1
+    1.1
+    1.2
+This tells you that the message contains two different MIME sections. The +first line of the MIME structure output will always contain "1", which refers +to the entire message, which happens to be a multipart/mixed +message. "1.1" refers to the first section of the multiparty message, which +happens to be a text/plain section. "1.2" refers to the second +section of the message, which happens to be an +application/octet-stream section. This is a typical situation. + +

If the message is not a MIME message, or it does not contain any +attachments, you will see a rather boring

+
 
+    1
+If, instead the first part of the message was itself a +multipart/alternative section, you might see the following +instead: +
 
+    1
+    1.1
+    1.1.1
+    1.1.2
+    1.2
+ +

Arbitrarily complex MIME constructs are possible.

+ +

OPTIONS

+
    +
  • -d - parse a delivery status notification MIME message (RFC + 1894). reformime expects to see on standard input a MIME message that + consists of a delivery status notification, as defined by RFC 1894. + reformime reads the message and prints on standard output a list of + addresses and their corresponding delivery status, as specified in the + delivery status notification. Each line printed by reformime consists of a + delivery status, a space, and the address reformime will terminate with a + 0 exit status. reformime produces no output and terminates with an exit + status of 1 if the standard input does not contain a delivery status + notification.
    +
    +
  • +
  • -D - like the -d option, except that it lists + the "original" recipient address, if provided. See RFC 1894 for more + information.
    +
    +
  • +
  • -e - extract the contents of the indicated MIME section, + and display it on standard output. The -s option is required when -e is + specified. If the indicated section uses either the base64 or + quoted-printable encoding method, reformime automatically + decodes it. In this case you're better off redirecting the standard output + into a file.
    +
    +
  • +
  • -x - extract the contents of the indicated MIME section to + a file.
    +
    +
  • +
  • -X - pipe the contents of the indicated MIME section to a + program.
    +
    +
  • +
  • -i - display MIME information for each section. + reformime will display the contents of the Content-Type: + header, any encoding used, and the character set. reformime + will also display at which byte offset in the message each section starts + and ends (and where the actual contents of the section start, skipping all + the headers).
    +
    +
  • +
  • -s section - display MIME information for this section + only. section is a MIME specification tag. The -s option is required if -e + is also specified, and is optional with -i.
    +
    +
  • +
  • -r - rewrite message, adding or standardizing RFC 2045 MIME + headers.
    +
    +
  • +
  • -r7 - also convert MIME sections with 8bit encoding to + quoted-printable encoding.
    +
    +
  • +
  • -r8 - also convert MIME sections with quoted-printable + encoding to 8bit encoding, where possible.
    +
    +
  • +
  • -m file1 file2 ... - create a MIME message + digest.
  • +
+ +

Extracting RFC 2045 MIME section(s) to file(s)

+ +

The -x and -X options extract a specific MIME section to a file or to a +pipe to an external program. Use the -s option to identify the MIME section +to extract. If the -s option is not specified, every MIME section in the +message is extracted, one at a time. quoted-printable and base64 encoding are +automatically decoded.

+
    +
  • -x - interactive extraction. reformime prints + the MIME content type of each section. Answer with 'y' or 'Y' to extract + the MIME section. Specify the filename at the next prompt. + reformime will prompt with a default filename. reformime + tries to choose the default filename based on the MIME headers, if + possible. If not, the default filename will be + attachment1.dat (if the -s option is not specified, the next + filename will be attachment2.dat, and so on).
    +
    +
  • +
  • -xPREFIX - automatic extraction. reformime will + automatically extract one or more MIME sections, and save them to a file. + The filename will be formed by taking PREFIX, and appending the default + filename to it. Note that there may not be a space between "-x" and + "PREFIX". For example: "reformime -xfiles-" - this will save MIME sections + as files-attachment1.dat, then + files-attachment2.dat, etc. reformime will try + to append the filename specified in the MIME headers for each section. + reformime will replace all suspect characters with the underbar, + when using the filename specified in the MIME headers.
    +
    +
  • +
  • -X prog arg1 arg2 ... - the -X option must be the last + option to reformime. reformime will run an + external program specified by "prog", and pipe the contents of the MIME + section to the program. reformime will set the environment variable + CONTENT_TYPE to the MIME content type. The environmetn + variable FILENAME will be set to the default filename of + reformime's liking. If the -s option is not specified, the program will be + executed one time for every MIME section in the message.
  • +
+ +

NOTE: reformime will extract every MIME section in the message +unless the -s option is specified. Yes, even the text/plain MIME +part that usually precedes a binary attachment.

+ +

Adding RFC 2045 MIME headers

+ +

The -r option performs the following actions:

+ +

If there is no Mime-Version:, Content-Type:, or +Content-Transfer-Encoding: header, reformime will +add one.

+ +

If the Content-Transfer-Encoding: header contains +8bit or raw, but only seven-bit data is found, +the Content-Transfer-Encoding header is changed to +7bit.

+ +

-r7 does the same thing, but also converts 8bit transfer encoding +containing eight-bit characters to quoted-printable encoding.

+ +

-r8 does the same thing, but also converts quoted-printable encoded +sections to 8bit, except in some situations.

+ +

Creating MIME message digests

+ +

The -m option is followed by a list of files. Each file should +contain a single RFC 822 message. reformime prints, on standard +output, a MIME digest containing the indicated messages.

+ +

If -m is not followed by at least one file, +reformime reads standard input. Each line on standard input must +contain a single filename; blank lines are not allowed.

+ +

BUGS

+ +

-x and -X ignores the Content-Disposition: header.

+ +

FILES

+ +

$HOME/.tmp - directory for temporary files. Automatically +created, if necessary.

+ +

SEE ALSO

+maildrop(1), maildropfilter(1), makemime(1), reformail(1), egrep(1), grep(1), courier(8), sendmail(8), RFC 1894, RFC 2045. + diff --git a/packages/clib/maildrop/rfc2045/rfc2045.c b/packages/clib/maildrop/rfc2045/rfc2045.c new file mode 100644 index 000000000..46ff1c630 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045.c @@ -0,0 +1,1239 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#include +#include "rfc2045.h" +#include "rfc822/rfc822.h" +#include "rfc2045charset.h" + +#ifdef __WINDOWS__ +#define strncasecmp strnicmp +#endif + +static char *rfc2045_defcharset=0; + +extern void rfc2045_enomem(); + +#define MAXLEVELS 20 +#define MAXPARTS 300 + +/* + New RFC2045 structure. +*/ + +struct rfc2045 *rfc2045_alloc() +{ +struct rfc2045 *p=(struct rfc2045 *)malloc(sizeof(struct rfc2045)); + + if (!p) + { + rfc2045_enomem(); + return (0); + } + + /* Initialize everything to nulls, except for one thing */ + + memset(p, '\0', sizeof(*p)); + + p->pindex=1; /* Start with part #1 */ + p->workinheader=1; + /* Most of the time, we're about to read a header */ + + return (p); +} + +const char *rfc2045_getattr(const struct rfc2045attr *p, const char *name) +{ + while (p) + { + if (p->name && strcmp(p->name, name) == 0) + return (p->value); + p=p->next; + } + return (0); +} + +void rfc2045_setattr(struct rfc2045attr **p, const char *name, const char *val) +{ +char *v; + + while (*p) + { + if (strcmp( (*p)->name, name) == 0) break; + p=&(*p)->next; + } + if (val == 0) + { + struct rfc2045attr *q= *p; + + if (q) + { + *p=q->next; + if (q->name) free(q->name); + if (q->value) free(q->value); + free(q); + } + return; + } + + v=strdup(val); + if (!v) + { + rfc2045_enomem(); + return; + } + + if (!*p) + { + if (((*p)=(struct rfc2045attr *)malloc(sizeof(**p))) == 0) + { + free(v); + rfc2045_enomem(); + return; + } + memset( (*p), 0, sizeof(**p)); + if ( ((*p)->name=strdup(name)) == 0) + { + free( *p ); + *p=0; + free(v); + rfc2045_enomem(); + return; + } + } + if ( (*p)->value ) free ( (*p)->value ); + (*p)->value=v; +} + +/* static const char cb_name[]="boundary"; */ + +/* #define ContentBoundary(p) (rfc2045_getattr( (p)->content_type_attr, cb_name)) */ + +#define ContentBoundary(p) ( (p)->boundary ) + +/* + Unallocate the RFC2045 structure. Recursively unallocate + all sub-structures. Unallocate all associated buffers. +*/ + +static void rfc2045_freeattr(struct rfc2045attr *p) +{ + while (p) + { + struct rfc2045attr *q=p->next; + + if (p->name) free(p->name); + if (p->value) free(p->value); + free(p); + p=q; + } +} + +void rfc2045_free(struct rfc2045 *p) +{ +struct rfc2045 *q, *r; + + for (q=p->firstpart; q; ) + { + r=q->next; + rfc2045_free(q); + q=r; + } + rfc2045_freeattr(p->content_type_attr); + rfc2045_freeattr(p->content_disposition_attr); + + if (p->content_md5) free(p->content_md5); + if (p->content_base) free(p->content_base); + if (p->content_location) free(p->content_location); + if (p->content_language) free(p->content_language); + if (p->content_id) free(p->content_id); + if (p->content_description) free(p->content_description); + if (p->content_transfer_encoding) free(p->content_transfer_encoding); + if (p->boundary) free(p->boundary); + if (p->content_type) free(p->content_type); + if (p->mime_version) free(p->mime_version); + if (p->workbuf) free(p->workbuf); + if (p->content_disposition) free(p->content_disposition); + if (p->rw_transfer_encoding) free(p->rw_transfer_encoding); + free(p); +} + +/* + Generic dynamic buffer append. +*/ + +void rfc2045_add_buf( + char **bufptr, /* Buffer */ + size_t *bufsize, /* Buffer's maximum size */ + size_t *buflen, /* Buffer's current size */ + + const char *p, size_t len) /* Append this data */ +{ + if (len + *buflen > *bufsize) + { + size_t newsize=len+*buflen+256; + char *p= *bufptr ? (char *)realloc(*bufptr, newsize): + (char *)malloc(newsize); + + if (!p) + { + rfc2045_enomem(); + return; + } + *bufptr=p; + *bufsize=newsize; + } + + memcpy(*bufptr + *buflen, p, len); + *buflen += len; +} + +/* Append to the work buffer */ + +void rfc2045_add_workbuf(struct rfc2045 *h, const char *p, size_t len) +{ + rfc2045_add_buf( &h->workbuf, &h->workbufsize, &h->workbuflen, p, len); +} + +/* Append one character to the work buffer */ + +void rfc2045_add_workbufch(struct rfc2045 *h, int c) +{ +char cc= (char)c; + + rfc2045_add_workbuf(h, &cc, 1); +} + +/* + Generic function to duplicate contents of a string. + The destination string may already be previously allocated, + so unallocate it. +*/ + +static void set_string(char **p, + const char *q) +{ + if (*p) free(*p); + + *p=0; + if (!q) return; + + if ((*p=(char *)malloc(strlen(q)+1)) == 0) + { + rfc2045_enomem(); + return; + } + + strcpy(*p, q); +} + +/* Update byte counts for this structure, and all the superstructures */ + +static void update_counts(struct rfc2045 *p, size_t newcnt, size_t newendcnt, + unsigned nlines) +{ + while (p) + { + p->endpos = newcnt; + p->endbody = newendcnt; + p->nlines += nlines; + if (!p->workinheader) + p->nbodylines += nlines; + p=p->parent; + } +} + +/* + Main entry point for RFC2045 parsing. External data is fed + by repetitively calling rfc2045_parse(). + + rfc2045_parse() breaks up input into lines, and calls doline() + to process each line. +*/ + +static void doline(struct rfc2045 *); + +void rfc2045_parse(struct rfc2045 *h, const char *buf, size_t s) +{ +size_t l; + + while (s) + { + for (l=0; lworkbuflen=0; + } + else + rfc2045_add_workbuf(h, buf, l); + buf += l; + s -= l; + } + + /* + ** Our buffer's getting pretty big. Let's see if we can + ** partially handle it. + */ + + if (h->workbuflen > 512) + { + struct rfc2045 *p; + size_t l, i; + + for (p=h; p->lastpart && !p->lastpart->workclosed; + p=p->lastpart) + ; + + /* If p->workinheader, we've got a mother of all headers + ** here. Well, that's just too bad, we'll end up garbling + ** it. + */ + + l=h->workbuflen; + + /* We do need to make sure that the final \r\n gets + ** stripped off, so don't gobble up everything if + ** the last character we see is a \r + */ + + if (h->workbuf[l-1] == '\r') + --l; + + /* If we'll be rewriting, make sure rwprep knows about + ** stuff that was skipped just now. */ + + if (h->rfc2045acptr && !p->workinheader && + (!p->lastpart || !p->lastpart->workclosed)) + (*h->rfc2045acptr->section_contents)(h->workbuf, l); + + update_counts(p, p->endpos+l, p->endpos+l, 0); + p->informdata=1; + for (i=0; lworkbuflen; l++) + h->workbuf[i++]=h->workbuf[l]; + h->workbuflen=i; + } +} + +/* + Append a new RFC2045 subpart. Adds new RFC2045 structure to the + end of the list of existing RFC2045 substructures. +*/ + +static struct rfc2045 *append_part_noinherit(struct rfc2045 *p, size_t startpos){ +struct rfc2045 *newp; + + newp=rfc2045_alloc(); + if (p->lastpart) + { + p->lastpart->next=newp; + newp->pindex=p->lastpart->pindex+1; + } + else + { + p->firstpart=newp; + newp->pindex=0; + } + p->lastpart=newp; + newp->parent=p; + + /* Initialize source pointers */ + newp->startpos=newp->endpos=newp->startbody=newp->endbody=startpos; + + while (p->parent) + p=p->parent; + ++p->numparts; + + return (newp); +} + +static struct rfc2045 *append_part(struct rfc2045 *p, size_t startpos) +{ +struct rfc2045 *newp=append_part_noinherit(p, startpos); + + /* Substructures inherit content transfer encoding and character set */ + + set_string(&newp->content_transfer_encoding, + p->content_transfer_encoding); + rfc2045_setattr(&newp->content_type_attr, "charset", + rfc2045_getattr(p->content_type_attr, "charset")); + return (newp); +} + +/* + doline() processes next line in the RFC2045 message. + + Drills down the list of all the multipart messages currently open, + and checks if the line is a boundary line for the given multipart. + In theory the boundary line, if there is one, should be the boundary + line only for the inner multipart only, but, this takes into account + broken MIME messages. +*/ + +static void do_header(struct rfc2045 *); + +static void doline(struct rfc2045 *p) +{ +size_t cnt=p->workbuflen; +char *c=p->workbuf; +size_t n=cnt-1; /* Strip \n (we always get at least a \n here) */ +struct rfc2045 *newp; +struct rfc2045ac *rwp=p->rfc2045acptr; +unsigned num_levels=0; + +size_t k; +int bit8=0; + + if (p->numparts > MAXPARTS) + { + p->rfcviolation |= RFC2045_ERR2COMPLEX; + return; + } + + for (k=0; klastpart && + !newp->lastpart->workclosed; newp=newp->lastpart, + ++num_levels) + { + if (ContentBoundary(newp) == 0 || newp->workinheader) + continue; + + if (newp->lastpart->informdata) + { + p=newp->lastpart; + p->informdata=0; + break; + } + } + + /* Drill down until we match a boundary, or until we've reached + the last RFC2045 section that has been opened. + */ + + while (p->lastpart) + { + size_t l; + const char *cb; + + if (p->lastpart->workclosed) + { + update_counts(p, p->endpos+cnt, p->endpos+cnt, 1); + return; + } + /* Leftover trash -- workclosed is set when the final + ** terminating boundary has been seen */ + + /* content_boundary may be set before the entire header + ** has been seen, so continue drilling down in that case + */ + + cb=ContentBoundary(p); + + if (cb == 0 || p->workinheader) + { + p=p->lastpart; + ++num_levels; + continue; + } + + l=strlen(cb); + + if (c[0] == '-' && c[1] == '-' && n >= 2+l && + strncasecmp(cb, c+2, l) == 0) + { + + if (rwp && (!p->lastpart || !p->lastpart->isdummy)) + (*rwp->end_section)(); + + /* Ok, we've found a boundary */ + + if (n >= 4+l && strncmp(c+2+l, "--", 2) == 0) + { + /* Last boundary */ + + p->lastpart->workclosed=1; + update_counts(p, p->endpos+cnt, p->endpos+cnt, + 1); + return; + } + + /* Create new RFC2045 section */ + + newp=append_part(p, p->endpos+cnt); + update_counts(p, p->endpos+cnt, p->endpos+n, 1); + + /* The new RFC2045 section is MIME compliant */ + + if ((newp->mime_version=strdup(p->mime_version)) == 0) + rfc2045_enomem(); + return; + } + p=p->lastpart; + ++num_levels; + } + + /* Ok, we've found the RFC2045 section that we're working with. + ** No what? + */ + + if (! p->workinheader) + { + /* Processing body, just update the counts. */ + + size_t cnt_update=cnt; + + if (bit8 && !p->content_8bit && + (p->rfcviolation & RFC2045_ERR8BITCONTENT) == 0) + { + struct rfc2045 *q; + + for (q=p; q; q=q->parent) + q->rfcviolation |= RFC2045_ERR8BITCONTENT; + } + + /* + ** In multiparts, the final newline in a part belongs to the + ** boundary, otherwise, include it in the text. + */ + if (p->parent && p->parent->content_type && + strncasecmp(p->parent->content_type, + "multipart/", 10) == 0) + cnt_update=n; + + if (!p->lastpart || !p->lastpart->workclosed) + { + if (rwp && !p->isdummy) + (*rwp->section_contents)(c, cnt); + + update_counts(p, p->endpos+cnt, p->endpos+cnt_update, + 1); + } + return; + } + + if (bit8 && (p->rfcviolation & RFC2045_ERR8BITHEADER) == 0) + { + struct rfc2045 *q; + + for (q=p; q; q=q->parent) + q->rfcviolation |= RFC2045_ERR8BITHEADER; + } + + /* In the header */ + + if ( n == 0 ) /* End of header, body begins. Parse header. */ + { + do_header(p); /* Clean up any left over header line */ + p->workinheader=0; + + /* Message body starts right here */ + + p->startbody=p->endpos+cnt; + update_counts(p, p->startbody, p->startbody, 1); + --p->nbodylines; /* Don't count the blank line */ + + /* Discard content type and boundary if I don't understand + ** this MIME flavor. + */ + + if (!RFC2045_ISMIME1(p->mime_version)) + { + set_string(&p->content_type, 0); + + rfc2045_freeattr(p->content_type_attr); + p->content_type_attr=0; + set_string(&p->content_disposition, 0); + rfc2045_freeattr(p->content_disposition_attr); + p->content_disposition_attr=0; + if (p->boundary) + { + free(p->boundary); + p->boundary=0; + } + } + + /* Normally, if we don't have a content_type, default it + ** to text/plain. However, if the multipart type is + ** multipart/digest, it is message/rfc822. + */ + + if (RFC2045_ISMIME1(p->mime_version) && !p->content_type) + { + char *q="text/plain"; + + if (p->parent && p->parent->content_type && + strcmp(p->parent->content_type, + "multipart/digest") == 0) + q="message/rfc822"; + set_string(&p->content_type, q); + } + + /* If this is not a multipart section, we don't want to + ** hear about any boundaries + */ + + if (!p->content_type || + strncmp(p->content_type, "multipart/", 10)) + rfc2045_setattr(&p->content_type_attr, "boundary", 0); + + /* If this section's a message, we will expect to see + ** more RFC2045 stuff, so create a nested RFC2045 structure, + ** and indicate that we expect to see headers. + */ + + if (p->content_type && + strcmp(p->content_type, "message/rfc822") == 0) + { + newp=append_part_noinherit(p, p->startbody); + newp->workinheader=1; + return; + } + + /* + ** If this is a multipart message (boundary defined), + ** create a RFC2045 structure for the pseudo-section + ** that precedes the first boundary line. + */ + + if (ContentBoundary(p)) + { + newp=append_part(p, p->startbody); + newp->workinheader=0; + newp->isdummy=1; + /* It's easier just to create it. */ + return; + } + + if (rwp) + (*rwp->start_section)(p); + return; + } + + /* RFC822 header continues */ + + update_counts(p, p->endpos + cnt, p->endpos+n, 1); + + /* If this header line starts with a space, append one space + ** to the saved contents of the previous line, and append this + ** line to it. + */ + + if (isspace((int)(unsigned char)*c)) + { + rfc2045_add_buf(&p->header, &p->headersize, &p->headerlen, " ", 1); + } + else + { + /* Otherwise the previous header line is complete, so process it */ + + do_header(p); + p->headerlen=0; + } + + /* Save this line in the header buffer, because the next line + ** could be a continuation. + */ + + rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, c, n); +} + +/***********************************************************************/ + +/* +** paste_tokens() - recombine an array of RFC822 tokens back as a string. +** (Comments) are ignored. +*/ + +static char *paste_tokens(struct rfc822t *h, int start, int cnt) +{ +int l; +int i; +char *p; + + /* Calculate string size */ + + l=1; + for (i=0; itokens[start+i].token == '(') + continue; + + if (rfc822_is_atom(h->tokens[start+i].token)) + l += h->tokens[start+i].len; + else + l++; + } + + /* Do it */ + + p=( char *)malloc(l); + if (!p) + { + rfc2045_enomem(); + return (0); + } + l=0; + + for (i=0; itokens[start+i].token == '(') + continue; + + if (rfc822_is_atom(h->tokens[start+i].token)) + { + int l2=h->tokens[start+i].len; + + memcpy(p+l, h->tokens[start+i].ptr, l2); + l += l2; + } + else p[l++]=h->tokens[start+i].token; + } + p[l]=0; + return (p); +} + +/* Various permutations of the above, including forcing the string to +** lowercase +*/ + +static char *lower_paste_tokens(struct rfc822t *h, int start, int cnt) +{ +char *p=paste_tokens(h, start, cnt); +char *q; + + for (q=p; q && *q; q++) + *q=tolower(*q); + return (p); +} + +static char *paste_token(struct rfc822t *h, int i) +{ + if (i >= h->ntokens) return (0); + return (paste_tokens(h, i, 1)); +} + +static char *lower_paste_token(struct rfc822t *h, int i) +{ +char *p=paste_token(h, i); +char *q; + + for (q=p; q && *q; q++) + *q=tolower(*q); + return (p); +} + +/* + do_header() - process completed RFC822 header. +*/ + +static void mime_version(struct rfc2045 *, struct rfc822t *); +static void content_type(struct rfc2045 *, struct rfc822t *); +static void content_transfer_encoding(struct rfc2045 *, struct rfc822t *); +static void content_disposition(struct rfc2045 *, struct rfc822t *); +static void content_id(struct rfc2045 *, struct rfc822t *); +static void content_description(struct rfc2045 *, const char *); +static void content_language(struct rfc2045 *, const char *); +static void content_md5(struct rfc2045 *, const char *); +static void content_base(struct rfc2045 *, struct rfc822t *); +static void content_location(struct rfc2045 *, struct rfc822t *); + +static void do_header(struct rfc2045 *p) +{ +struct rfc822t *header; +char *t; + + if (p->headerlen == 0) return; + rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, "", 1); + /* 0 terminate */ + + /* Parse the header line according to RFC822 */ + + header=rfc822t_alloc(p->header, NULL); + + if (!header) return; /* Broken header */ + + if (header->ntokens < 2 || + header->tokens[0].token || + header->tokens[1].token != ':') + { + rfc822t_free(header); + return; /* Broken header */ + } + + t=lower_paste_token(header, 0); + + if (t == 0) + ; + else if (strcmp(t, "mime-version") == 0) + { + free(t); + mime_version(p, header); + } + else if (strcmp(t, "content-type") == 0) + { + free(t); + content_type(p, header); + } else if (strcmp(t, "content-transfer-encoding") == 0) + { + free(t); + content_transfer_encoding(p, header); + } else if (strcmp(t, "content-disposition") == 0) + { + free(t); + content_disposition(p, header); + } else if (strcmp(t, "content-id") == 0) + { + free(t); + content_id(p, header); + } else if (strcmp(t, "content-description") == 0) + { + free(t); + t=strchr(p->header, ':'); + if (t) ++t; + while (t && isspace((int)(unsigned char)*t)) + ++t; + content_description(p, t); + } else if (strcmp(t, "content-language") == 0) + { + free(t); + t=strchr(p->header, ':'); + if (t) ++t; + while (t && isspace((int)(unsigned char)*t)) + ++t; + content_language(p, t); + } else if (strcmp(t, "content-base") == 0) + { + free(t); + content_base(p, header); + } else if (strcmp(t, "content-location") == 0) + { + free(t); + content_location(p, header); + } else if (strcmp(t, "content-md5") == 0) + { + free(t); + t=strchr(p->header, ':'); + if (t) ++t; + while (t && isspace((int)(unsigned char)*t)) + ++t; + content_md5(p, t); + } + else free(t); + rfc822t_free(header); +} + +/* Mime-Version: and Content-Transfer-Encoding: headers are easy */ + +static void mime_version(struct rfc2045 *p, struct rfc822t *header) +{ +char *vers=paste_tokens(header, 2, header->ntokens-2); + + if (!vers) return; + + if (p->mime_version) free(p->mime_version); + p->mime_version=vers; +} + +static void content_transfer_encoding(struct rfc2045 *r, + struct rfc822t *header) +{ +char *p; + + p=lower_paste_tokens(header, 2, header->ntokens-2); + if (!p) return; + + if (r->content_transfer_encoding) + free(r->content_transfer_encoding); + r->content_transfer_encoding=p; + + if (strcmp(p, "8bit") == 0) + r->content_8bit=1; +} + +/* Dig into the content_type header */ + +static void parse_content_header(struct rfc2045 *r, struct rfc822t *header, + void (*init_token)(struct rfc2045 *, char *), + void (*init_parameter)(struct rfc2045 *, const char *, + struct rfc822t *, int, int)) +{ +int start; +int i, j; +char *p; + + /* Look for the 1st ; */ + + for (start=2; start < header->ntokens; start++) + if (header->tokens[start].token == ';') + break; + + /* Everything up to the 1st ; is the content type */ + + p=lower_paste_tokens(header, 2, start-2); + if (!p) return; + + (*init_token)(r, p); + if (start < header->ntokens) start++; + + /* Handle the remainder of the Content-Type: header */ + + while (start < header->ntokens) + { + /* Look for next ; */ + + for (i=start; intokens; i++) + if (header->tokens[i].token == ';') + break; + j=start; + if (j < i) + { + ++j; + + /* We only understand = */ + + while (j < i && header->tokens[j].token == '(') + ++j; + if (j < i && header->tokens[j].token == '=') + { + ++j; + p=lower_paste_token(header, start); + if (!p) return; + (*init_parameter)(r, p, header, j, i-j); + free(p); + } + } + if ( intokens ) ++i; /* Skip over ; */ + start=i; + } +} + +/* Dig into the content_type header */ + +static void save_content_type(struct rfc2045 *, char *); +static void save_content_type_parameter( struct rfc2045 *, const char *, + struct rfc822t *, int, int); + +static void content_type(struct rfc2045 *r, struct rfc822t *header) +{ + parse_content_header(r, header, &save_content_type, + &save_content_type_parameter); +} + +static void save_content_type(struct rfc2045 *r, char *content_type) +{ + if (r->content_type) free(r->content_type); + r->content_type=content_type; +} + +static void save_content_type_parameter( + struct rfc2045 *r, const char *name, + struct rfc822t *header, int start, int len) +{ +char *p; + + p=strcmp(name, "charset") == 0 ? + lower_paste_tokens(header, start, len): + paste_tokens(header, start, len); + if (!p) return; + + rfc2045_setattr(&r->content_type_attr, name, p); + free(p); + + if (strcmp(name, "boundary") == 0) + { + if (r->boundary) + free(r->boundary); + p=lower_paste_tokens(header, start, len); + r->boundary=p; + } +} + +/* Dig into content-disposition */ + +static void save_content_disposition(struct rfc2045 *, char *); +static void save_content_disposition_parameter( struct rfc2045 *, const char *, + struct rfc822t *, int, int); + +static void content_disposition(struct rfc2045 *r, struct rfc822t *header) +{ + parse_content_header(r, header, &save_content_disposition, + &save_content_disposition_parameter); +} + +static void save_content_disposition(struct rfc2045 *r, + char *content_disposition) +{ + if (r->content_disposition) free(r->content_disposition); + r->content_disposition=content_disposition; +} + +static void save_content_disposition_parameter( + struct rfc2045 *r, const char *name, + struct rfc822t *header, int start, int len) +{ +char *p; + + p=paste_tokens(header, start, len); + if (!p) return; + + rfc2045_setattr(&r->content_disposition_attr, name, p); + free(p); +} + +char *rfc2045_related_start(const struct rfc2045 *p) +{ +const char *cb=rfc2045_getattr( p->content_type_attr, "start"); +struct rfc822t *t; +struct rfc822a *a; +int i; + + if (!cb || !*cb) return (0); + + t=rfc822t_alloc(cb, 0); + if (!t) + { + rfc2045_enomem(); + return(0); + } + + a=rfc822a_alloc(t); + if (!a) + { + rfc822t_free(t); + rfc2045_enomem(); + return (0); + } + for (i=0; inaddrs; i++) + if (a->addrs[i].tokens) + { + char *s=rfc822_getaddr(a, i); + + rfc822a_free(a); + rfc822t_free(t); + if (!s) + rfc2045_enomem(); + return (s); + } + + rfc822a_free(a); + rfc822t_free(t); + return (0); +} + +static void content_id(struct rfc2045 *p, struct rfc822t *t) +{ +struct rfc822a *a=rfc822a_alloc(t); +int i; + + if (!a) + { + rfc2045_enomem(); + return; + } + + for (i=0; inaddrs; i++) + if (a->addrs[i].tokens) + { + char *s=rfc822_getaddr(a, i); + + if (!s) + { + rfc822a_free(a); + rfc2045_enomem(); + return; + } + if (p->content_id) + free(p->content_id); + p->content_id=s; + break; + } + + rfc822a_free(a); +} + +static void content_description(struct rfc2045 *p, const char *s) +{ + if (s && *s) + set_string(&p->content_description, s); +} + +static void content_language(struct rfc2045 *p, const char *s) +{ + if (s && *s) + set_string(&p->content_language, s); +} + +static void content_md5(struct rfc2045 *p, const char *s) +{ + if (s && *s) + set_string(&p->content_md5, s); +} + +static void content_base(struct rfc2045 *p, struct rfc822t *t) +{ +char *s; +int i; + + for (i=0; intokens; i++) + if (t->tokens[i].token == '"') + t->tokens[i].token=0; + + s=paste_tokens(t, 2, t->ntokens-2); + set_string(&p->content_base, s); +} + +static void content_location(struct rfc2045 *p, struct rfc822t *t) +{ +char *s; +int i; + + for (i=0; intokens; i++) + if (t->tokens[i].token == '"') + t->tokens[i].token=0; + + s=paste_tokens(t, 2, t->ntokens-2); + set_string(&p->content_location, s); +} + +/* -------------------- */ + +#define GETINFO(s, def) ( (s) && (*s) ? (s):def) + +void rfc2045_mimeinfo(const struct rfc2045 *p, + const char **content_type_s, + const char **content_transfer_encoding_s, + const char **charset_s) +{ +const char *c; + + *content_type_s=GETINFO(p->content_type, "text/plain"); + *content_transfer_encoding_s=GETINFO(p->content_transfer_encoding, + "8bit"); + + c=rfc2045_getattr(p->content_type_attr, "charset"); + if (!c) c=rfc2045_getdefaultcharset(); + + *charset_s=c; +} + +const char *rfc2045_getdefaultcharset() +{ +const char *p=rfc2045_defcharset; + + if (!p) p=RFC2045CHARSET; + return (p); +} + +void rfc2045_setdefaultcharset(const char *charset) +{ +char *p=strdup(charset); + + if (!p) + { + rfc2045_enomem(); + return; + } + + if (rfc2045_defcharset) free(rfc2045_defcharset); + rfc2045_defcharset=p; +} + +const char *rfc2045_boundary(const struct rfc2045 *p) +{ +const char *cb=rfc2045_getattr( p->content_type_attr, "boundary"); + + if (!cb) cb=""; + return (cb); +} + +void rfc2045_dispositioninfo(const struct rfc2045 *p, + const char **disposition_s, + const char **disposition_name_s, + const char **disposition_filename_s) +{ + *disposition_s=p->content_disposition; + *disposition_name_s=rfc2045_getattr(p->content_disposition_attr, + "name"); + *disposition_filename_s=rfc2045_getattr(p->content_disposition_attr, + "filename"); +} + +const char *rfc2045_contentname(const struct rfc2045 *p) +{ +const char *q=rfc2045_getattr(p->content_type_attr, "name"); + + if (!q) q=""; + return (q); +} + +const char *rfc2045_content_id(const struct rfc2045 *p) +{ + return (p->content_id ? p->content_id:""); +} + +const char *rfc2045_content_description(const struct rfc2045 *p) +{ + return (p->content_description ? p->content_description:""); +} + +const char *rfc2045_content_language(const struct rfc2045 *p) +{ + return (p->content_language ? p->content_language:""); +} + +const char *rfc2045_content_md5(const struct rfc2045 *p) +{ + return (p->content_md5 ? p->content_md5:""); +} + +void rfc2045_mimepos(const struct rfc2045 *p, + off_t *start_pos, off_t *end_pos, off_t *start_body, + off_t *nlines, off_t *nbodylines) +{ + *start_pos=p->startpos; + *end_pos=p->endpos; + + *nlines=p->nlines; + *nbodylines=p->nbodylines; + if (p->parent) /* MIME parts do not have the trailing CRLF */ + { + *end_pos=p->endbody; + if (*nlines) --*nlines; + if (*nbodylines) --*nbodylines; + } + *start_body=p->startbody; +} + +unsigned rfc2045_mimepartcount(const struct rfc2045 *p) +{ +const struct rfc2045 *q; +unsigned n=0; + + for (q=p->firstpart; q; q=q->next) ++n; + return (n); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045.h b/packages/clib/maildrop/rfc2045/rfc2045.h new file mode 100644 index 000000000..0839fb7d1 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045.h @@ -0,0 +1,188 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#ifndef rfc2045_h +#define rfc2045_h + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RFC2045_ISMIME1(p) ((p) && atoi(p) == 1) +#define RFC2045_ISMIME1DEF(p) (!(p) || atoi(p) == 1) + +struct rfc2045 { + struct rfc2045 *parent; + unsigned pindex; + struct rfc2045 *next; + + off_t startpos, /* At which offset in msg this section starts */ + endpos, /* Where it ends */ + startbody, /* Where the body of the msg starts */ + endbody; /* endpos - trailing CRLF terminator */ + off_t nlines; /* Number of lines in message */ + off_t nbodylines; /* Number of lines only in the body */ + char *mime_version; + char *content_type; + struct rfc2045attr *content_type_attr; /* Content-Type: attributes */ + + char *content_disposition; + char *boundary; + struct rfc2045attr *content_disposition_attr; + char *content_transfer_encoding; + int content_8bit; /* + ** Set if content_transfer_encoding is + ** 8bit + */ + char *content_id; + char *content_description; + char *content_language; + char *content_md5; + char *content_base; + char *content_location; + struct rfc2045ac *rfc2045acptr; + int has8bitchars; /* For rewriting */ + int haslongline; /* For rewriting */ + unsigned rfcviolation; /* Boo-boos */ + +#define RFC2045_ERR8BITHEADER 1 /* 8 bit characters in headers */ +#define RFC2045_ERR8BITCONTENT 2 /* 8 bit contents, but no 8bit + content-transfer-encoding */ +#define RFC2045_ERR2COMPLEX 4 /* Too many nested contents */ + + unsigned numparts; /* # of parts allocated */ + + char *rw_transfer_encoding; /* For rewriting */ + +#define RFC2045_RW_7BIT 1 +#define RFC2045_RW_8BIT 2 + + /* Subsections */ + + struct rfc2045 *firstpart, *lastpart; + + /* Working area */ + + char *workbuf; + size_t workbufsize; + size_t workbuflen; + int workinheader; + int workclosed; + int isdummy; + int informdata; /* In a middle of a long form-data part */ + char *header; + size_t headersize; + size_t headerlen; + + int (*decode_func)(struct rfc2045 *, const char *, size_t); + void *misc_decode_ptr; + int (*udecode_func)(const char *, size_t, void *); +} ; + +struct rfc2045attr { + struct rfc2045attr *next; + char *name; + char *value; + } ; + +struct rfc2045 *rfc2045_alloc(); +void rfc2045_parse(struct rfc2045 *, const char *, size_t); +void rfc2045_free(struct rfc2045 *); +const char *rfc2045_contentname(const struct rfc2045 *); + +void rfc2045_mimeinfo(const struct rfc2045 *, + const char **, + const char **, + const char **); + +const char *rfc2045_boundary(const struct rfc2045 *); +char *rfc2045_related_start(const struct rfc2045 *); +const char *rfc2045_content_id(const struct rfc2045 *); +const char *rfc2045_content_description(const struct rfc2045 *); +const char *rfc2045_content_language(const struct rfc2045 *); +const char *rfc2045_content_md5(const struct rfc2045 *); + +void rfc2045_dispositioninfo(const struct rfc2045 *, + const char **, + const char **, + const char **); + +void rfc2045_mimepos(const struct rfc2045 *, off_t *, off_t *, off_t *, + off_t *, off_t *); +unsigned rfc2045_mimepartcount(const struct rfc2045 *); + +void rfc2045_xdump(struct rfc2045 *); + +struct rfc2045id { + struct rfc2045id *next; + int idnum; +} ; + +void rfc2045_decode(struct rfc2045 *, + void (*)(struct rfc2045 *, struct rfc2045id *, void *), + void *); + +struct rfc2045 *rfc2045_find(struct rfc2045 *, const char *); + + +void rfc2045_cdecode_start(struct rfc2045 *, + int (*)(const char *, size_t, void *), void *); +int rfc2045_cdecode(struct rfc2045 *, const char *, size_t); +int rfc2045_cdecode_end(struct rfc2045 *); + +void rfc2045_base64encode_start( void (*)(const char *, size_t)); +void rfc2045_base64encode(const char *, size_t); +void rfc2045_base64encode_end(); + +const char *rfc2045_getdefaultcharset(); +void rfc2045_setdefaultcharset(const char *); +struct rfc2045 *rfc2045_fromfd(int); +#define rfc2045_fromfp(f) (rfc2045_fromfd(fileno((f)))) + +extern void rfc2045_error(const char *); + + +struct rfc2045ac { + void (*start_section)(struct rfc2045 *); + void (*section_contents)(const char *, size_t); + void (*end_section)(); + } ; + +struct rfc2045 *rfc2045_alloc_ac(); +int rfc2045_ac_check(struct rfc2045 *, int); +int rfc2045_rewrite(struct rfc2045 *, int, int, const char *); +int rfc2045_rewrite_func(struct rfc2045 *p, int, + int (*)(const char *, int, void *), void *, + const char *); + +/* Internal functions */ + +int rfc2045_try_boundary(struct rfc2045 *, int, const char *); +char *rfc2045_mk_boundary(struct rfc2045 *, int); +const char *rfc2045_getattr(const struct rfc2045attr *, const char *); +void rfc2045_setattr(struct rfc2045attr **, const char *, const char *); + +/* MIME content base/location */ + +char *rfc2045_content_base(struct rfc2045 *p); + /* This joins Content-Base: and Content-Location:, as best as I + ** can figure it out. + */ + +char *rfc2045_append_url(const char *, const char *); + /* Do this with two arbitrary URLs */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packages/clib/maildrop/rfc2045/rfc2045.html b/packages/clib/maildrop/rfc2045/rfc2045.html new file mode 100644 index 000000000..c25cec006 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045.html @@ -0,0 +1,323 @@ + + + + + rfc2045 - RFC 2045 (MIME) parsing library + + + + + + + +

rfc2045 - RFC 2045 (MIME) parsing library

+ +

SYNOPSIS

+ +

#include <rfc2045.h>

+ +

cc ... -lrfc2045 -lrfc822

+ +

DESCRIPTION

+ +

The rfc2045 library is used to parse and work with MIME-formatted messages. +The rfc2045 library is used to:

+ +

1) Parse the structure of a MIME formatted message

+ +

2) Examine the contents of each MIME section

+ +

3) Optionally rewrite and reformat the message.

+ +

Creating an rfc2045 structure

+
#include <rfc2045.h>
+
+struct rfc2045 *ptr=rfc2045_alloc();
+void rfc2045_parse(struct rfc2045 *ptr, const char *txt, size_t cnt);
+
+struct rfc2045 *ptr=rfc2045_fromfd(int fd);
+struct rfc2045 *ptr=rfc2045_fromfp(FILE *fp);
+
+void rfc2045_free(struct rfc2045 *ptr);
+
+void rfc2045_error(const char *errmsg)
+{
+        perror(errmsg);
+        exit(0);
+}
+ +

The rfc2045 structure is created from an existing message. The +function rfc2045_alloc() allocates the structure, then rfc2045_parse() is +called to initialize the structure based on the contents of the message. +txt points to the contents of the message, and cnt contains the +number of bytes in the message.

+ +

Large messages can be parsed by calling rfc2045_parse() multiple number of +times, each time passing a portion of the overall message. There is no need to +call a separate function after the entire message has been parsed -- the +rfc2045 structure is created dynamically, on the fly.

+ +

rfc2045_alloc() returns NULL if there was insufficient memory to allocate +the structure. The rfc2045_parse() also allocates memory, internally, however +no error indication is return in the event of a memory allocation failure. +Instead, the function rfc2045_error() is called, with errmsg set to +"Out of memory". rfc2045_error() is also called by rfc2045_alloc() also +calls rfc2045_error(), prior to returning a NULL pointer.

+ +

The rfc2045_error() function is not included in the rfc2045 library, it +must be defined by the application to report the error in some appropriate +way. All functions below will use rfc2045_error() to report an error condition +(currently only insufficient memory is reported), in addition to returning any +kind of an error indicator. Some functions do not return an error indicator, +so rfc2045_error() is the only reliable way to detect a failure.

+ +

The rfc2045_fromfd() function initializes an rfc2045 structure from +a file descriptor. It is equivalent to calling rfc2045_alloc(), then reading +the contents of the given file descriptor, and calling rfc2045_parse(). The +rfc2045_fromfp() function initializes an rfc2045 structure from a +FILE.

+ +

After the rfc2045 structure is initialized, the functions described +below may be used to access and work with the contents of the structure. When +the rfc2045 structure is no longer needed, the function rfc2045_free() +deallocates and destroys the structure.

+ +

Structure of a MIME message

+
struct rfc2045 {
+
+        struct rfc2045 *parent;
+
+        struct rfc2045 *firstpart;
+        struct rfc2045 *next;
+        int             isdummy;
+        int             rfcviolation;
+} ;
+ +

The rfc2045 has many fields, only some are publicly documented. A +MIME message is represented by a recursive tree of linked rfc2045 +structures. Each instance of the rfc2045 structure represents a single +MIME section of a MIME message.

+ +

The top-level structure representing the entire message is created by the +rfc2045_alloc() function. The remaining structures are created dynamically by +rfc2045_parse(). Any rfc2045 structure, except ones whose +isdummy flag is set, may be used as an argument to any function +described in the following chapters.

+ +

The rfcviolation field in the top-level rfc2045 is set to +indicate any errors encountered while parsing the MIME message. +rfcviolation is a bitmask of the following flags:

+
    +
  • RFC2045_ERR8BITHEADER - illegal 8-bit characters in MIME + headers.
    +
    +
  • +
  • RFC2045_ERR8BITCONTENT - illegal 8-bit contents of a MIME + section that has a 7bit transfer encoding.
    +
    +
  • +
  • RFC2045_ERR2COMPLEX - the message has too many MIME + sections, this is a potential denial-of-service attack.
  • +
+ +

In each rfc2045 structure representing a multipart MIME section (or +one containing message/rfc822 content), the firstpart pointer points to +the first MIME section in the multipart MIME section (or the included +"message/rfc822" MIME section). If there are more than one MIME sections in a +multipart MIME section firstpart->next gets you the second MIME +section, firstpart->next->next gets you the third MIME section, and so +on. parent points to the parent MIME section, which is NULL for the +top-level MIME section.

+ +

Not all MIME sections are created equal. In a multipart MIME section, +there is an initial, unused, "filler" section before the first MIME delimiter +(see RFC 2045 for more information). This filler section typically contains a +terse message saying that this is a MIME-formatted message, or something +similar of that kind. This is not considered to be a "real" MIME section, and +all MIME-aware software must ignore those. These filler sections are +designated by setting the "isdummy" flag to non-zero. All rfc2045 +structures that have "isdummy" set must be completely ignored, and skipped +over, when traversing the rfc2045 tree.

+ +

Basic MIME information

+
const char *content_type, *content_transfer_encoding,
+           *content_character_set;
+
+void rfc2045_mimeinfo(const struct rfc2045 *ptr,
+        &content_type, &content_transfer_encoding,
+        &content_character_set);
+
+off_t start_pos, end_pos, start_body, nlines, nbodylines;
+
+void rfc2045_mimepos(const struct rfc2045 *ptr,
+        &start_pos, &end_pos, &start_body, &nlines,
+        &nbodylines);
+ +

The rfc2045_mimeinfo() function returns the content type, encoding method, +and the character set of a given MIME section. Where a MIME section does not +specify any property, rfc2045_mimeinfo() automatically supplies a default +value. The character set is only meaningful for MIME sections containing a +text content type, however it is still defaulted for other sections. It is +not permissible to supply a NULL pointer for any argument to +rfc2045_mimeinfo().

+ +

The rfc2045_mimepos() function is used to locate the position of the given +MIME section in the original message. It is not permissible to supply a NULL +pointer for any argument to rfc2045_mimepos(). All arguments must be +used.

+ +

start_pos and end_pos point to the starting and the ending +offset, from the beginning of the message, of this MIME section. nlines +is initialized to the number of lines of text in this MIME section. The +starting offset points to the start of MIME headers in this section. +start_body is initialized to point to the starting offset of the actual +contents of this MIME section, and nbodylines is set to the number of +lines of actual content in this MIME section.

+
const char *id=rfc2045_content_id(
+                       const struct rfc2045 *ptr);
+
+const char *desc=rfc2045_content_description(
+                       const struct rfc2045 *ptr);
+
+const char *lang=rfc2045_content_language(
+                       const struct rfc2045 *ptr);
+
+const char *md5=rfc2045_content_md5(
+                       const struct rfc2045 *ptr);
+ +

These functions return the contents of the corresponding MIME headers. If +these headers do not exist, these functions return an empty string, "", NOT a +null pointer.

+
char *id=rfc2045_related_start(const struct rfc2045 *ptr);
+ +

This function returns the start parameter of the Content-Type: +header, which is used by multipart/related content. This function returns a +dynamically-allocated buffer, which must be free(3)-ed after use (a null +pointer is returned if there was insufficient memory for the buffer, and +rfc2045_error() is called).

+
const char *disposition, *name, *filename;
+
+void rfc2045_dispositioninfo(const struct rfc2045 *ptr,
+        &disposition, &name, &filename);
+ +

rfc2045_dispositioninfo() returns the disposition specifications of a MIME +section. For MIME sections that do not specify the type of disposition +(inline or attachment), the name or the filename of the attachment, the +corresponding pointer is initialized to NULL.

+
char *url=rfc2045_content_base(struct rfc2045 *ptr);
+
+char *url=rfc2045_append_url(const char *base, const char *url);
+ +

These functions are used to work with multipart/related MIME messages. The +rfc2045_content_base() returns the contents of either the Content-Base: or the +Content-Location: header. If both are present, they are logically combined. +The rfc2045_append_url() function combines two URLs, base and +url, and returns the absolute URL that results from the +combination.

+ +

Both functions return a pointer to a dynamically-allocated buffer that must +be free(3)-ed after it is no longer needed. Both functions return NULL if +there was no sufficient memory to allocate the buffer. rfc2045_content_base() +returns an empty string in the event that there are no Content-Base: or +Content-Location: headers. Either argument to rfc2045_append_url() may be a +NULL, or an empty string.

+ +

Decoding a MIME section

+
void rfc2045_cdecode_start(struct rfc2045 *ptr,
+        int (*callback_func)(const char *, size_t, void *),
+        void *callback_arg);
+
+int rfc2045_cdecode(struct rfc2045 *ptr, const char *stuff,
+        size_t nstuff);
+
+int rfc2045_cdecode_end(struct rfc2045 *ptr);
+ +

These functions are used to return the raw contents of the given MIME +section, transparently decoding quoted-printable or base64-encoded content. +Because the rfc2045 library does not require the message to be read from a +file (it can be stored in a memory buffer), the application is responsible for +reading the contents of the message and calling rfc2045_cdecode().

+ +

The rfc2045_cdecode_start() function is used to begin the process of +decoding the given MIME section. After calling rfc2045_cdecode_start(), the +application must the repeatedly call rfc2045_cdecode() with the contents of +the MIME message between the offsets given by the start_body and +end_pos return values from rfc2045_mimepos() function. The +rfc2045_cdecode() function can be called repeatedly, if necessary, for +successive portions of the MIME section. After the last MIME section, the +rfc2045_cdecode_end() function is called to finish decoding the MIME +section.

+ +

rfc2045_cdecode() and rfc2045_cdecode_end() repeatedly call the +callback_func() function, with the decoded contents of the MIME section. The +first argument to callback_func() is a pointer to a portion of the decoded +content, the second argument is the number of bytes in this portion. The +third argument is callback_arg.

+ +

callback_func() is required to return zero, to continue decoding. If +callback_func() returns non-zero, the decoding immediately stops and +rfc2045_cdecode() or rfc2045_cdecode_end() will terminate with callback_func's +return code.

+ +

Rewriting MIME messages

+ +

The rfc2045 library contains functions that can be used to rewrite a MIME +message in order to convert 8-bit data to 7-bit encoding method, or to convert +7-bit encoded data to full 8-bit data, if possible.

+
struct rfc2045 *ptr=rfc2045_alloc_ac();
+int necessary=rfc2045_ac_check(struct rfc2045 *ptr, int mode);
+
+int error=rfc2045_rewrite(struct rfc2045 *ptr,
+                int fdin,
+                int fdout,
+                const char *appname);
+
+int rfc2045_rewrite_func(struct rfc2045 *p, int fdin,
+        int (*funcout)(const char *, int, void *), void *funcout_arg,
+        const char *appname);
+ +

When rewriting will be used, the rfc2045_alloc_ac() function must be used +to create the initial rfc2045 structure. This function allocates some +additional structures that are used in rewriting. The rfc2045_parse() function +is used to parse the message, as usual. The rfc2045_free() function will also +be used normally to destroy the rfc2045 structure, when all is said and +done.

+ +

The rfc2045_ac_check() function must be called to determine whether +rewriting is necessary. mode must be set to one of the following +values:

+
    +
  • RFC2045_RW_7BIT - we want to generate 7-bit content. If the + original message contains any 8-bit content it will be converted to 7-bit + content using quoted-printable encoding.
  • +
  • RFC2045_RW_8BIT - we want to generate 8-bit content. If the + original message contains any 7-bit quoted-printable content it should be + rewritten as 8-bit content.
  • +
+ +

The rfc2045_ac_check() function returns non-zero if there's any content in +the MIME message that should be converted, OR if there are any missing MIME +headers. rfc2045_ac_check() returns zero if there's no need to rewrite the +message. However it might still be worthwhile to rewrite the message anyway. +There are some instances where it is desirable to provide defaults for some +missing MIME headers, but they are too trivial to require the message to be +rewritten. One such case would be a missing Content-Transfer-Encoding: header +for a multipart section.

+ +

Either the rfc2045_rewrite() or the rfc2045_rewrite_func() function is used +to rewrite the message. The only difference is that rfc2045_rewrite() writes +the new message to a given file descriptor, fdout, while +rfc2045_rewrite_func() repeatedly calls the funcout function. Both +function read the original message from fdin. funcout receives +to a portion of the MIME message, the number of bytes in the specified +portion, and funcout_arg. When either function rewrites a MIME section, +an informational header gets appended, noting that the message was converted +by appname.

+ +

SEE ALSO

+rfc822(3), reformime(1), reformail(1). + diff --git a/packages/clib/maildrop/rfc2045/rfc2045_base64encode.c b/packages/clib/maildrop/rfc2045/rfc2045_base64encode.c new file mode 100644 index 000000000..f39244325 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045_base64encode.c @@ -0,0 +1,76 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#include "rfc2045.h" + +static unsigned char base64buf[57]; + /* When encoded this becomes 76 characters */ +static int base64cnt; + +static void (*output_func)(const char *, size_t); + +void rfc2045_base64encode_start( void (*func)(const char *, size_t)) +{ + output_func=func; + base64cnt=0; +} + +void rfc2045_base64encode(const char *buf, size_t n) +{ + while (n) + { + size_t i; + + if (base64cnt == sizeof(base64buf)) + { + rfc2045_base64encode_end(); + base64cnt=0; + } + i=n; + if (i > sizeof(base64buf) - base64cnt) + i=sizeof(base64buf) - base64cnt; + memcpy(base64buf + base64cnt, buf, i); + base64cnt += i; + buf += i; + n -= i; + } +} + +static const char base64tab[]= +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +void rfc2045_base64encode_end() +{ +int a=0,b=0,c=0; +int i, j; +int d, e, f, g; +char output_buf[ sizeof(base64buf) / 3 * 4+1]; + + if (base64cnt == 0) return; + + for (j=i=0; i> 2 ]; + e=base64tab[ ((a & 3 ) << 4) | (b >> 4)]; + f=base64tab[ ((b & 15) << 2) | (c >> 6)]; + g=base64tab[ c & 63 ]; + if (i + 1 >= base64cnt) f='='; + if (i + 2 >= base64cnt) g='='; + output_buf[j++]=d; + output_buf[j++]=e; + output_buf[j++]=f; + output_buf[j++]=g; + } + + output_buf[j++]='\n'; + (*output_func)(output_buf, j); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045_fromfd.c b/packages/clib/maildrop/rfc2045/rfc2045_fromfd.c new file mode 100644 index 000000000..38ea86a3a --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045_fromfd.c @@ -0,0 +1,46 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "rfc2045.h" +#if HAVE_UNISTD_H +#include +#endif +#ifdef __WINDOWS__ +#include +#define read _read +#define lseek _lseek +#endif + +/* Convert a message to the RFC2045 structure */ + +struct rfc2045 *rfc2045_fromfd(int fd) +{ +struct rfc2045 *rfc; +char buf[BUFSIZ]; +int n; +off_t orig_pos; + + if ((orig_pos=lseek(fd, 0L, SEEK_CUR)) == (off_t)-1) return (NULL); + if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) return (NULL); + if ((rfc=rfc2045_alloc()) == 0) return (NULL); + + while ((n=read(fd, buf, sizeof(buf))) > 0) + rfc2045_parse(rfc, buf, n); + if (lseek(fd, orig_pos, SEEK_SET) == (off_t)-1) + { + rfc2045_free(rfc); + rfc=0; + } + return (rfc); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045acchk.c b/packages/clib/maildrop/rfc2045/rfc2045acchk.c new file mode 100644 index 000000000..36ab1c700 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045acchk.c @@ -0,0 +1,146 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include "rfc2045.h" +#include +#if HAVE_STRINGS_H +#include +#endif +#include +#include +#ifdef __WINDOWS__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +/* $Id$ */ + +extern void rfc2045_enomem(); + +int rfc2045_ac_check(struct rfc2045 *p, int rwmode) +{ +int flag=0; /* Flag - rewriting suggested */ +struct rfc2045 *c; +int hasnon7bit=p->has8bitchars; + /* hasnon7bit: 8bit chars in this section or subsections */ +const char *te; +int is8bitte; + + for (c=p->firstpart; c; c=c->next) + if (!c->isdummy) + { + if (rfc2045_ac_check(c, rwmode)) flag=1; + if (strcmp(c->content_transfer_encoding, "7bit") && + strcmp(c->content_transfer_encoding, "quoted-printable")) + hasnon7bit=1; + if (c->has8bitchars) + p->has8bitchars=1; + } + + if (RFC2045_ISMIME1DEF(p->mime_version) && !p->content_type) + { + if ((p->content_type=strdup("text/plain")) == 0) + rfc2045_enomem(); + if (p->mime_version) + { + flag=1; + } + } + + if (RFC2045_ISMIME1DEF(p->mime_version) + && !rfc2045_getattr(p->content_type_attr, "charset") + && strncasecmp(p->content_type, "text/", 5) == 0) + { + rfc2045_setattr(&p->content_type_attr, "charset", + rfc2045_getdefaultcharset()); + + if (p->mime_version + + && p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */ + + ) + { + flag=1; + } + } + + if (RFC2045_ISMIME1DEF(p->mime_version) + && !p->content_transfer_encoding) + { + if ((p->content_transfer_encoding=strdup( + hasnon7bit ? "8bit":"7bit")) == 0) + rfc2045_enomem(); + if (p->mime_version + + && p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */ + ) + { + flag=1; + } + } + +#if 0 + if (RFC2045_ISMIME1DEF(p->mime_version) + && strncmp(p->content_type, "text/", 5) == 0 && !hasnon7bit + && strcmp(p->content_transfer_encoding, "7bit")) + { + if (p->mime_version) + { + flag=1; + } + } +#endif + + if (RFC2045_ISMIME1DEF(p->mime_version)) + { + /* Check for conversions */ + + te=p->content_transfer_encoding; + is8bitte=strcasecmp(te, "base64") && + strcasecmp(te, "quoted-printable") && + strcasecmp(te, "7bit"); /* 8 bit contents */ + + if (is8bitte && !p->has8bitchars && !p->haslongline) + { + if (p->rw_transfer_encoding) + free(p->rw_transfer_encoding); + if ((p->rw_transfer_encoding=strdup("7bit")) == 0) + rfc2045_enomem(); + flag=1; + is8bitte=0; + } + + if (rwmode == RFC2045_RW_7BIT && (is8bitte || p->haslongline)) + { + if (p->rw_transfer_encoding) + free(p->rw_transfer_encoding); + if ((p->rw_transfer_encoding=strdup("quoted-printable")) + == 0) + rfc2045_enomem(); + flag=1; + } + else if (rwmode == RFC2045_RW_8BIT && + strcasecmp(te, "quoted-printable") == 0 && + !p->haslongline) + { + if (p->rw_transfer_encoding) + free(p->rw_transfer_encoding); + if ((p->rw_transfer_encoding=strdup(hasnon7bit + ? "8bit":"7bit")) == 0) + rfc2045_enomem(); + flag=1; + } + } + + if (!p->mime_version) + { + if ((p->mime_version=strdup("1.0")) == 0) + rfc2045_enomem(); + } + return (flag); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045acprep.c b/packages/clib/maildrop/rfc2045/rfc2045acprep.c new file mode 100644 index 000000000..84dfc07dc --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045acprep.c @@ -0,0 +1,107 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#include "rfc2045.h" +#include +#include + +/* $Id$ */ + +static void start_rwprep(struct rfc2045 *); +static void do_rwprep(const char *, size_t); +static void end_rwprep(); + +static struct rfc2045ac rfc2045acprep={ + &start_rwprep, + &do_rwprep, + &end_rwprep}; + +static struct rfc2045 *currwp; +static int curlinepos=0; + +typedef enum { + raw, + quotedprint, + qpseeneq, + qpseeneqh, + base64} state_t; + +static state_t curstate; +static int statechar; + +#define h2nyb(c) ( (c) >= 'a' && (c) <= 'f' ? (c)-('a'-10): \ + (c) >= 'A' && (c) <= 'F' ? (c)-('A'-10): (c)-'0') + +struct rfc2045 *rfc2045_alloc_ac() +{ +struct rfc2045 *p=rfc2045_alloc(); + + if (p) p->rfc2045acptr= &rfc2045acprep; + currwp=0; + return (p); +} + + +static void start_rwprep(struct rfc2045 *p) +{ + currwp=p; + curlinepos=0; + curstate=raw; + if (p->content_transfer_encoding) + { + if (strcmp(p->content_transfer_encoding, + "quoted-printable") == 0) + curstate=quotedprint; + else if (strcmp(p->content_transfer_encoding, "base64") == 0) + curstate=base64; + } +} + +static void do_rwprep(const char * p, size_t n) +{ + if (!currwp) return; + for ( ; n; --n, ++p) + switch (curstate) { + case quotedprint: + if (*p == '=') + { + curstate=qpseeneq; + continue; + } + /* FALLTHRU */ + case raw: + if (*p == '\r' || *p == '\n') + curlinepos=0; + else if (++curlinepos > 500) + currwp->haslongline=1; + if ((unsigned char)*p >= 127) + currwp->has8bitchars=1; + break; + case qpseeneq: + if (*p == '\n') + { + curstate=quotedprint; + continue; + } + if (isspace((int)(unsigned char)*p)) continue; /* Ignore WSP */ + statechar=*p; + curstate=qpseeneqh; + continue; + case qpseeneqh: + curstate=quotedprint; + if ( (unsigned char) + ( (h2nyb(statechar) << 4) + h2nyb(*p) ) >= 127 + ) currwp->has8bitchars=1; + if (++curlinepos > 500) + currwp->haslongline=1; + continue; + case base64: + break; + } +} + +static void end_rwprep() +{ +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045appendurl.c b/packages/clib/maildrop/rfc2045/rfc2045appendurl.c new file mode 100644 index 000000000..a1d17e25b --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045appendurl.c @@ -0,0 +1,131 @@ +/* +** Copyright 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#include +#include "rfc2045.h" + +extern void rfc2045_enomem(); + +/* +** --------------------------------------------------------------------- +** Attempt to parse Content-Base: and Content-Location:, and return the +** "base" of all the relative URLs in the section. +** --------------------------------------------------------------------- +*/ + +static void get_method_path(const char *p, + const char **method, + unsigned *methodl, + const char **path) +{ +unsigned i; + + for (i=0; p && p[i]; i++) + { + if (p[i] == ':') + { + *method=p; + *methodl= ++i; + *path=p+i; + return; + } + + if (!isalpha( (int)(unsigned char)p[i])) + break; + } + + *method=0; + *methodl=0; + *path=p; +} + +char *rfc2045_append_url(const char *base, const char *loc) +{ +const char *base_method; +unsigned base_method_l; +const char *base_path; + +const char *loc_method; +unsigned loc_method_l; +const char *loc_path; +char *buf, *q; + + get_method_path(base, &base_method, &base_method_l, &base_path); + get_method_path(loc, &loc_method, &loc_method_l, &loc_path); + + if (loc_method_l) + { + buf=malloc(strlen(loc)+1); + if (!buf) + rfc2045_enomem(); + else + strcpy(buf, loc); + return (buf); + } + + loc_method=base_method; + loc_method_l=base_method_l; + + if (!base_path) base_path=""; + if (!loc_path) loc_path=""; + + buf=malloc(loc_method_l + strlen(base_path)+strlen(loc_path) + 3); + + if (!buf) + { + rfc2045_enomem(); + return (0); + } + + if (loc_method_l) + memcpy(buf, loc_method, loc_method_l); + buf[loc_method_l]=0; + + q=buf + loc_method_l; + + strcat(strcpy(q, base_path), "/"); + + if ( loc_path[0] == '/') + { + char *r; + + if (loc_path[1] == '/') + /* Location is absolute */ + { + *q=0; + } + + /* Relative to top of base */ + + else if ( q[0] == '/' && q[1] == '/' && + (r=strchr(q+2, '/')) != 0) + { + *r=0; + } + else + *q=0; /* No sys in base, just start with / */ + } + + strcat(q, loc_path); + + return (buf); +} + +char *rfc2045_content_base(struct rfc2045 *p) +{ + return (rfc2045_append_url(p->content_base, p->content_location)); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045cdecode.c b/packages/clib/maildrop/rfc2045/rfc2045cdecode.c new file mode 100644 index 000000000..3026e7f3b --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045cdecode.c @@ -0,0 +1,201 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#include "rfc2045.h" +#include +#include + +/* $Id$ */ + +extern void rfc2045_add_buf( char **, size_t *, size_t *, + const char *, size_t); +extern void rfc2045_add_workbuf(struct rfc2045 *, const char *, size_t); +extern void rfc2045_add_workbufch(struct rfc2045 *, int); + +static int decode_raw(struct rfc2045 *p, const char *s, size_t l) +{ + if (s && l) return ((*p->udecode_func)(s,l,p->misc_decode_ptr)); + return (0); +} + +static const char xdigit[]="0123456789ABCDEF"; + +static int do_decode_qp(struct rfc2045 *p) +{ +char *a, *b, *c, *end; +int d; + + end=p->workbuf + p->workbuflen; + for (a=b=p->workbuf; a < end; ) + { + if (*a != '=') + { + *b++ = *a++; + continue; + } + ++a; + if (!*a || a >= end || isspace((int)(unsigned char)*a)) + break; + + if ((c=strchr(xdigit, *a)) == 0) continue; + d= (c-xdigit)*16; + ++a; + if (!*a || a >= end) + break; + if ((c=strchr(xdigit, *a)) == 0) continue; + d += c-xdigit; + ++a; + *b++=d; + } + p->workbuflen= b-p->workbuf; + d=(*p->udecode_func)(p->workbuf, p->workbuflen, p->misc_decode_ptr); + p->workbuflen=0; + return (d); +} + +static unsigned char decode64tab[256]; +static int decode64tab_init=0; + +/* When we have enough base64-encoded data in the buffer, decode it. */ + +static int do_decode_base64(struct rfc2045 *p) +{ +size_t i, j; +char a,b,c; +size_t k; +int rc; + + if (!decode64tab_init) + { + for (i=0; i<256; i++) decode64tab[i]=100; + for (i=0; i<64; i++) + decode64tab[ (int) + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]) ]=i; + decode64tab[ (int)'=' ] = 99; + } + + /* Remove everything except base64encoded data */ + + for (i=j=0; iworkbuflen; i++) + if (decode64tab[(int)(unsigned char)p->workbuf[i]] < 100) + p->workbuf[j++]=p->workbuf[i]; + + + p->workbuflen=j; + + /* Decode the data, in 4-byte pieces */ + + i=j / 4; + i=i*4; + k=0; + for (j=0; jworkbuf[j]]; + int x=decode64tab[(int)(unsigned char)p->workbuf[j+1]]; + int y=decode64tab[(int)(unsigned char)p->workbuf[j+2]]; + int z=decode64tab[(int)(unsigned char)p->workbuf[j+3]]; + + a= (w << 2) | (x >> 4); + b= (x << 4) | (y >> 2); + c= (y << 6) | z; + p->workbuf[k++]=a; + if ( p->workbuf[j+2] != '=') + p->workbuf[k++]=b; + if ( p->workbuf[j+3] != '=') + p->workbuf[k++]=c; + } + rc=(*p->udecode_func)(p->workbuf, k, p->misc_decode_ptr); + + /* Anything left? Move it to the start of the buffer */ + + k=0; + while (j < p->workbuflen) + p->workbuf[k++]=p->workbuf[j++]; + p->workbuflen=k; + return (0); +} + +static int decode_qp(struct rfc2045 *p, const char *s, size_t l) +{ +size_t start,i; +int rc; + + if (!s) + return (do_decode_qp(p)); + + for (start=0; startworkbuflen > 1024) + { + char buf[10]; + int i; + + for (i=p->workbuflen - 5; iworkbuflen; i++) + if (p->workbuf[i] == '=') break; + if (i < p->workbuflen) + { + int j=p->workbuflen-i; + + memcpy(buf, p->workbuf+i, j); + buf[j]=0; + p->workbuflen=i; + } + else buf[0]=0; + if ((rc=do_decode_qp(p)) != 0) return (rc); + rfc2045_add_workbuf(p, buf, strlen(buf)); + } + start=i; + } + return (0); +} + +static int decode_base64(struct rfc2045 *p, const char *s, size_t l) +{ + if (!s) + return (do_decode_base64(p)); + + rfc2045_add_workbuf(p, s, l); + if (p->workbuflen > 256) + return (do_decode_base64(p)); + return (0); +} + +void rfc2045_cdecode_start(struct rfc2045 *p, + int (*u)(const char *, size_t, void *), void *miscptr) +{ + p->misc_decode_ptr=miscptr; + p->udecode_func=u; + p->decode_func= &decode_raw; + p->workbuflen=0; + if (p->content_transfer_encoding) + { + if (strcmp(p->content_transfer_encoding, + "quoted-printable") == 0) + p->decode_func= &decode_qp; + else if (strcmp(p->content_transfer_encoding, "base64") == 0) + p->decode_func= &decode_base64; + } +} + +int rfc2045_cdecode_end(struct rfc2045 *p) +{ + return ((*p->decode_func)(p, NULL, 0)); +} + +int rfc2045_cdecode(struct rfc2045 *p, const char *s, size_t l) +{ + if (s && l) return ((*p->decode_func)(p, s, l)); + return (0); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045charset.h b/packages/clib/maildrop/rfc2045/rfc2045charset.h new file mode 100644 index 000000000..44dc3a73c --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045charset.h @@ -0,0 +1,10 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* $Id$ */ + +#define RFC2045CHARSET "us-ascii" + +#define RFC2045MIMEMSG "This is a MIME-formatted message. If you see this text it means that your\nE-mail software does not support MIME-formatted messages.\n" diff --git a/packages/clib/maildrop/rfc2045/rfc2045charset.h.in b/packages/clib/maildrop/rfc2045/rfc2045charset.h.in new file mode 100644 index 000000000..a843f2892 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045charset.h.in @@ -0,0 +1,10 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* $Id$ */ + +#define RFC2045CHARSET "@RFC2045CHARSET@" + +#define RFC2045MIMEMSG "This is a MIME-formatted message. If you see this text it means that your\nE-mail software does not support MIME-formatted messages.\n" diff --git a/packages/clib/maildrop/rfc2045/rfc2045decode.c b/packages/clib/maildrop/rfc2045/rfc2045decode.c new file mode 100644 index 000000000..f71bb2c74 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045decode.c @@ -0,0 +1,41 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#include "rfc2045.h" + +static void decode(struct rfc2045id *topid, + struct rfc2045id **childidptr, + struct rfc2045 *r, + void (*func)(struct rfc2045 *, struct rfc2045id *, void *), + void *ptr) +{ +struct rfc2045id nextid; + + *childidptr=0; + (*func)(r, topid, ptr); + *childidptr=&nextid; + nextid.idnum=1; + if (r->content_type && strncmp(r->content_type, "multipart/", 10) == 0) + nextid.idnum=0; + for (r=r->firstpart; r; r=r->next) + { + if (nextid.idnum) + decode(topid, &nextid.next, r, func, ptr); + ++nextid.idnum; + } +} + +void rfc2045_decode(struct rfc2045 *p, + void (*func)(struct rfc2045 *, struct rfc2045id *, void *), + void *ptr) +{ +struct rfc2045id topid; + + topid.idnum=1; + decode(&topid, &topid.next, p, func, ptr); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045enomem.c b/packages/clib/maildrop/rfc2045/rfc2045enomem.c new file mode 100644 index 000000000..4f37795bd --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045enomem.c @@ -0,0 +1,9 @@ +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include "rfc2045.h" + +void rfc2045_enomem() +{ + rfc2045_error("Out of memory."); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045find.c b/packages/clib/maildrop/rfc2045/rfc2045find.c new file mode 100644 index 000000000..bd60d00ea --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045find.c @@ -0,0 +1,50 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#include "rfc2045.h" +#include + +struct rfc2045findstruct { + + const char *partnum; + struct rfc2045 *ptr; + } ; + +static void do_decode(struct rfc2045 *p, struct rfc2045id *id, void *ptr) +{ +struct rfc2045findstruct *fs=(struct rfc2045findstruct *)ptr; +const char *partnum=fs->partnum; +unsigned n; + + while (id) + { + if (!isdigit((int)(unsigned char)*partnum)) return; + n=0; + while (isdigit((int)(unsigned char)*partnum)) + n=n*10 + *partnum++ - '0'; + if (*partnum) + { + if (*partnum != '.') return; + ++partnum; + } + if (n != (unsigned)id->idnum) return; + id=id->next; + } + if ( *partnum == '\0') fs->ptr=p; +} + + +struct rfc2045 *rfc2045_find(struct rfc2045 *p, const char *str) +{ +struct rfc2045findstruct fs; + + fs.partnum=str; + fs.ptr=0; + rfc2045_decode(p, &do_decode, &fs); + return (fs.ptr); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045mkboundary.c b/packages/clib/maildrop/rfc2045/rfc2045mkboundary.c new file mode 100644 index 000000000..427d6419b --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045mkboundary.c @@ -0,0 +1,82 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include "rfc2045.h" +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#ifdef __WINDOWS__ +#define NUMBUFSIZE 60 +#define HAS_GETHOSTNAME 1 +#include +#else +#define NUMBUFSIZE 60 +#endif + +/* $Id$ */ + +#if HAS_GETHOSTNAME + +#else + +extern int gethostname(char *, size_t); +#endif + +extern void rfc2045_enomem(); + +char *rfc2045_mk_boundary(struct rfc2045 *s, int fd) +{ +char pidbuf[NUMBUFSIZE]; +char timebuf[NUMBUFSIZE]; +char cntbuf[60]; +int cnt=0; +time_t mytime; +#ifndef __WINDOWS__ +char hostnamebuf[256]; +pid_t mypid; +#endif +char *p; +int rc; + + time(&mytime); + +#ifdef __WINDOWS__ + sprintf(pidbuf, "%ld", GetCurrentThreadId()); + sprintf(timebuf, "%ld", (long)mytime); +#else + hostnamebuf[sizeof(hostnamebuf)-1]=0; + if (gethostname(hostnamebuf, sizeof(hostnamebuf)-1)) + hostnamebuf[0]=0; + mypid=getpid(); + sprintf(pidbuf, "%d", mypid); + sprintf(timebuf, "%ld", mytime); +#endif + + for (;;) + { + sprintf(cntbuf, "%d", ++cnt); + p=malloc(strlen(pidbuf)+strlen(timebuf)+ + strlen(cntbuf)+10); + if (!p) + { + rfc2045_enomem(); + return (NULL); + } + + sprintf(p, "=_%s-%s-%s", pidbuf, timebuf, cntbuf); + if ((rc=rfc2045_try_boundary(s, fd, p)) == 0) + break; + free(p); + if (rc < 0) + return (NULL); + } + return (p); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045rewrite.c b/packages/clib/maildrop/rfc2045/rfc2045rewrite.c new file mode 100644 index 000000000..680df62b5 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045rewrite.c @@ -0,0 +1,471 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include "rfc2045.h" +#include "rfc2045charset.h" +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#ifdef __WINDOWS__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#if (_MSC_VER < 1300) +#define write _write +#endif +#include +#endif + +/* $Id$ */ + +static char *rw_boundary_root; +static int rw_boundary_cnt; +static const char *rw_appname; + +static FILE *fdin; +static int fdout; +static int (*fdout_func)(const char *, int, void *); +static void *fdout_arg; + +static char fdout_buf[512]; +static char *fdout_ptr; +static size_t fdout_left; + +/* Quoted printable encoding */ +static void qpe_start(); +static int qpe_do(const char *, size_t, void *); +static void qpe_end(); +static int conv_err; + +static int fdout_flush() +{ +int n=fdout_ptr-fdout_buf; +int i=0; +char *p=fdout_buf; + + while (n) + { + i=fdout_func ? (*fdout_func)(p, n, fdout_arg): + write(fdout, p, n); + if (i <= 0) return (-1); + p += i; + n -= i; + } + fdout_ptr=fdout_buf; + fdout_left=sizeof(fdout_buf); + return (0); +} + +static int fdout_add(const char *p, size_t cnt) +{ + while (cnt) + { + if (cnt < fdout_left) + { + memcpy(fdout_ptr, p, cnt); + fdout_ptr += cnt; + fdout_left -= cnt; + return (0); + } + if (fdout_left == 0) + { + if (fdout_flush()) return (-1); + continue; + } + memcpy(fdout_ptr, p, fdout_left); + p += fdout_left; + cnt -= fdout_left; + fdout_ptr += fdout_left; + fdout_left=0; + } + return (0); +} + +static int do_8bit(const char *p, size_t cnt, void *ptr) +{ + if (fdout_add(p, cnt)) + conv_err=1; + return (0); +} + +static int fdout_autoconverted(const char *oldte, const char *newte) +{ + if (fdout_add("X-Mime-Autoconverted: from ", 27) || + fdout_add(oldte, strlen(oldte)) || + fdout_add(" to ", 4) || + fdout_add(newte, strlen(newte)) || + (rw_appname && (fdout_add(" by ", 4) || + fdout_add(rw_appname, strlen(rw_appname)))) || + fdout_add("\n", 1)) return (-1); + return (0); +} + +static int fdout_value(const char *); + +static int fdout_attr(const struct rfc2045attr *a) +{ + if (fdout_add(a->name, strlen(a->name))) return (-1); + if (a->value && (fdout_add("=", 1) || fdout_value(a->value))) + return (-1); + return (0); +} + +static int fdout_value(const char *v) +{ +size_t i,j; + + for (i=0; v[i]; i++) + { + if ( !isalnum((int)(unsigned char)v[i]) && v[i] != '-') + { + if (fdout_add("\"", 1)) return (-1); + for (j=i=0; v[i]; i++) + if (v[i] == '\\' || v[i] == '"') + { + if (fdout_add(v+j, i-j) || + fdout_add("\\", 1)) + return (-1); + j=i; + } + if (fdout_add(v+j, i-j) || fdout_add("\"", 1)) + return (-1); + return (0); + } + } + return (fdout_add(v, i)); +} + +#define TE(p) ((p)->rw_transfer_encoding ? \ + (p)->rw_transfer_encoding: (p)->content_transfer_encoding) + +static int rwmime(struct rfc2045 *p) +{ +static char mimever[]="Mime-Version: 1.0\n"; +const char *te; +struct rfc2045attr *a; + + if (!p->parent) + if (fdout_add(mimever, sizeof(mimever)-1)) return (-1); + + if (p->content_type) + { + if (fdout_add("Content-Type: ", 14) || + fdout_add(p->content_type, strlen(p->content_type))) + return (-1); + + for (a=p->content_type_attr; a; a=a->next) + { + if (!a->name || strcmp(a->name, "boundary") == 0) + continue; + if ( fdout_add("; ", 2) || + fdout_attr(a)) return (-1); + } + } + + if (p->firstpart + && p->firstpart->next /* ADDED 8/30/99, see below */) + { + char buf[80]; + + ++rw_boundary_cnt; + sprintf(buf, "-%d", rw_boundary_cnt); + if ( fdout_add("; boundary=\"", 12) || + fdout_add(rw_boundary_root, strlen(rw_boundary_root)) || + fdout_add(buf, strlen(buf)) || + fdout_add("\"", 1)) return (-1); + } + if (fdout_add("\n", 1)) return (-1); + + /* Show content transfer encoding for top section, or if it's + ** different than the parent. + */ + te=TE(p); + if (te && (!p->parent || strcmp(te, TE(p->parent)))) + { + if (fdout_add("Content-Transfer-Encoding: ", 27) || + fdout_add(te, strlen(te)) || + fdout_add("\n", 1)) return (-1); + } + return (0); +} + +static int dorw(struct rfc2045 *p) +{ +/* WTF STATIC??? */ int seen_mime=0; +char buf[256]; +int c; +int bcnt; + + if (fseek(fdin, p->startpos, SEEK_SET) == -1) return (-1); + if (p->parent) + { + seen_mime=1; + if (rwmime(p)) return (-1); + } + while (fgets(buf, sizeof(buf), fdin)) + { + if (buf[0] == '\n') break; + + if (RFC2045_ISMIME1DEF(p->mime_version) && + strncasecmp(buf, "mime-version:", 13) == 0 && + !seen_mime) + { + seen_mime=1; + rwmime(p); + if (strchr(buf, '\n') == NULL) + while ((c=getc(fdin)) >= 0 && c != '\n') + ; + while ((c=getc(fdin)) >= 0 && c != '\n' && isspace(c)) + while ((c=getc(fdin)) >= 0 && c != '\n') + ; + if (c >= 0) ungetc(c, fdin); + continue; + } + + if (!RFC2045_ISMIME1DEF(p->mime_version) || ( + strncasecmp(buf, "mime-version:", 13) && + strncasecmp(buf, "content-type:", 13) && + strncasecmp(buf, "content-transfer-encoding:", 26)) + ) + { + do + { + do + { + if (fdout_add(buf, strlen(buf))) + return (-1); + } while (strchr(buf, '\n') == NULL && + fgets(buf, sizeof(buf), fdin)); + + c=getc(fdin); + if (c >= 0) ungetc(c, fdin); + } while (c >= 0 && c != '\n' && isspace(c) && + fgets(buf, sizeof(buf), fdin)); + } + else + while ( (c=getc(fdin)) >= 0 && + (ungetc(c, fdin), c) != '\n' && isspace(c)) + { + while (fgets(buf, sizeof(buf), fdin) && + strchr(buf, '\n') == NULL) + ; + } + } + if (RFC2045_ISMIME1DEF(p->mime_version)) + { + if (!seen_mime) + if (rwmime(p)) return (-1); + + if (!p->firstpart && p->rw_transfer_encoding) + if (fdout_autoconverted(p->content_transfer_encoding, + p->rw_transfer_encoding)) return (-1); + } + + if (fdout_add("\n", 1)) return (-1); + if (fseek(fdin, p->startbody, SEEK_SET) == -1) return (-1); + + /* For non-multipart section, just print the body */ + + if (!p->firstpart) + { + off_t ps=p->startbody; + int convmode=0; + + if (p->rw_transfer_encoding) + { + if ( strcasecmp(p->rw_transfer_encoding, + "quoted-printable") == 0) + convmode=RFC2045_RW_7BIT; + else + convmode=RFC2045_RW_8BIT; + } + + conv_err=0; + if (convmode == RFC2045_RW_7BIT) + { + qpe_start(); + rfc2045_cdecode_start(p, &qpe_do, 0); + } + + if (convmode == RFC2045_RW_8BIT) + { + rfc2045_cdecode_start(p, &do_8bit, 0); + } + + while (ps < p->endbody) + { + int n; + + if (p->endbody - ps > sizeof(buf)) + n=sizeof(buf); + else n=p->endbody-ps; + n=fread(buf, 1, n, fdin); + if (n <= 0) return (-1); + if (convmode) + rfc2045_cdecode(p, buf, n); + else if (fdout_add(buf, n)) conv_err=1; + ps += n; + if (conv_err) break; + } + if (convmode == RFC2045_RW_7BIT) + { + rfc2045_cdecode_end(p); + qpe_end(); + } + if (convmode == RFC2045_RW_8BIT) + { + rfc2045_cdecode_end(p); + } + if (conv_err) return (-1); + return (0); + } + + bcnt=rw_boundary_cnt; + + /* Sam 8/30/99 fix - handle message/rfc822: + + --boundary + Content-Type: message/rfc822 + + --><-- we're here, DON'T add RFC2045MIMEMSG and rest of crap here + */ + if (p->firstpart->next == 0) + { + int rc; + + p->firstpart->parent=0; + rc=dorw(p->firstpart); + p->firstpart->parent=p; + return (rc); + } + + if (fdout_add(RFC2045MIMEMSG, sizeof(RFC2045MIMEMSG)-1)) + return (-1); + for (p=p->firstpart; p; p=p->next) + { + if (p->isdummy) continue; + sprintf(buf, "\n--%s-%d\n", rw_boundary_root, bcnt); + if (fdout_add(buf, strlen(buf))) return (-1); + if (dorw(p) != 0) return(-1); + } + sprintf(buf, "\n--%s-%d--\n", rw_boundary_root, bcnt); + if (fdout_add(buf, strlen(buf))) return (-1); + return (0); +} + +static int rfc2045_rewrite_common(struct rfc2045 *, int, const char *); + +int rfc2045_rewrite(struct rfc2045 *p, int fdin_arg, int fdout_arg, + const char *appname) +{ + fdout=fdout_arg; + fdout_func=0; + return (rfc2045_rewrite_common(p, fdin_arg, appname)); +} + +int rfc2045_rewrite_func(struct rfc2045 *p, int fdin_arg, + int (*funcarg)(const char *, int, void *), void *funcargarg, + const char *appname) +{ + fdout= -1; + fdout_func=funcarg; + fdout_arg=funcargarg; + return (rfc2045_rewrite_common(p, fdin_arg, appname)); +} + +static int rfc2045_rewrite_common(struct rfc2045 *p, + int fdin_arg, const char *appname) +{ +int rc; +int fd=dup(fdin_arg); + + if (fd < 0) return (-1); + rw_appname=appname; + fdin=fdopen(fd, "r"); + if (!fdin) + { + close(fd); + return (-1); + } + + fdout_ptr=fdout_buf; + fdout_left=sizeof(fdout_buf); + + rw_boundary_root=rfc2045_mk_boundary(p, fd); + if (rw_boundary_root == 0) + rc= -1; + else + { + rw_boundary_cnt=1; + rc=dorw(p); + free(rw_boundary_root); + } + if (rc == 0 && fdout_ptr > fdout_buf) + rc=fdout_flush(); + fclose(fdin); + return (rc); +} + +static int qpe_pos; + +static void qpe_start() +{ + qpe_pos=0; +} + +static int qpe_do(const char *p, size_t i, void *ptr) +{ +size_t j,k; + + if (conv_err) return (0); + for (j=k=0; j= 72) + { + if (fdout_add(p+k, j-k) || + fdout_add("=\n", 2)) conv_err=1; + k=j; + qpe_pos=0; + } + + if (p[j] < 32 || p[j] >= 127 || p[j] == '=') + { + char buf[3]; + static char xdigit[16]="0123456789ABCDEF"; + unsigned n= (unsigned char)p[j]; + + buf[0]='='; + buf[1]=xdigit[ n / 16]; + buf[2]=xdigit[ n % 16]; + if (fdout_add(p+k, j-k) || + fdout_add(buf, 3)) conv_err=1; + qpe_pos += 2; + k=j+1; + } + ++qpe_pos; + } + if (fdout_add(p+k, j-k)) conv_err=1; + return (0); +} + +static void qpe_end() +{ +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045tryboundary.c b/packages/clib/maildrop/rfc2045/rfc2045tryboundary.c new file mode 100644 index 000000000..babb1d3d3 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045tryboundary.c @@ -0,0 +1,125 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include "rfc2045.h" +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#ifdef __WINDOWS__ +#define strncasecmp strnicmp +#include +#define read _read +#define lseek _lseek +#endif + + +/* $Id$ */ + +extern void rfc2045_add_buf( char **, size_t *, size_t *, + const char *, size_t); + +static const char *boundary_chk_val; +static size_t boundary_chk_val_len; +static char *boundary_chk_buf; +static size_t boundary_chk_bufsize, boundary_chk_buflen; +static int boundary_chk_flag; + +static void boundary_chk_add(const char *p, size_t l) +{ + if (boundary_chk_buflen < boundary_chk_val_len+20) + rfc2045_add_buf( &boundary_chk_buf, + &boundary_chk_bufsize, + &boundary_chk_buflen, p, l); +} + +static int boundary_chk(const char *p, size_t l, void *ptr) +{ +static size_t i, j; + + for (j=i=0; i= boundary_chk_val_len+2 && + boundary_chk_buf[0] == '-' && + boundary_chk_buf[1] == '-' && + strncasecmp(boundary_chk_val, + boundary_chk_buf+2, + boundary_chk_val_len) == 0) + boundary_chk_flag=1; + + boundary_chk_buflen=0; + j=i+1; + } + } + boundary_chk_add(p+j, l-j); + return (0); +} + +static int try_boundary(struct rfc2045 *p, int fd) +{ +int rc; +char buf[512]; +int n, cnt; +off_t ps; + + if (p->firstpart) + { + for (p=p->firstpart; p; p=p->next) + if ((rc=try_boundary(p, fd)) != 0) + return (rc); + return (0); + } + + if (p->content_transfer_encoding && + strcmp(p->content_transfer_encoding, "base64") == 0) + return (0); + + boundary_chk_flag=0; + boundary_chk_buflen=0; + + if (lseek(fd, p->startbody, SEEK_SET) == -1) return (-1); + rfc2045_cdecode_start(p, boundary_chk, 0); + + ps=p->startbody; + while (ps < p->endbody) + { + if (p->endbody - ps < sizeof(buf)) + cnt=p->endbody-ps; + else cnt=sizeof(buf); + n=read(fd, buf, cnt); + if (n <= 0) return (-1); + rfc2045_cdecode(p, buf, n); + ps += n; + if (boundary_chk_flag) break; + } + rfc2045_cdecode_end(p); + if (boundary_chk_buflen) + boundary_chk("\n", 1, 0); /* Flush out partial line */ + return (boundary_chk_flag); +} + +int rfc2045_try_boundary(struct rfc2045 *p, int fd, const char *boundary) +{ +int n; + + boundary_chk_val_len=strlen(boundary_chk_val=boundary); + boundary_chk_buf=0; + boundary_chk_bufsize=0; + n=try_boundary(p, fd); + if (boundary_chk_buf) free(boundary_chk_buf); + return (n); +} diff --git a/packages/clib/maildrop/rfc2045/rfc2045xdump.c b/packages/clib/maildrop/rfc2045/rfc2045xdump.c new file mode 100644 index 000000000..5161039d8 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/rfc2045xdump.c @@ -0,0 +1,48 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +/* +** $Id$ +*/ +#include +#include "rfc2045.h" + +#define DUMP(s,n) if ( (s) ) { printf("%*s%s: %s\n", level*4, "", n, (s)); } + +/* Extended RFC2045 dump */ + +static void dodump(struct rfc2045 *p, int level) +{ + if (!p->isdummy) + { + printf("%*sMessage start %ld, end %ld, startbody %ld, endbody %ld.\n", level*4, + "", (long)p->startpos, (long)p->endpos, + (long)p->startbody, (long)p->endbody); + DUMP(p->mime_version, "Mime-Version") + DUMP(p->content_type, "Content-Type") + DUMP(rfc2045_getattr(p->content_type_attr, "charset"), + "Charset") + DUMP(p->content_transfer_encoding, "Transfer Encoding") + DUMP(rfc2045_getattr(p->content_type_attr, "boundary"), + "Boundary") + DUMP(p->content_disposition, "Content Disposition") + DUMP(rfc2045_getattr(p->content_disposition_attr, "name"), + "Disposition Name") + DUMP(rfc2045_getattr(p->content_disposition_attr, "filename"), + "Disposition Filename") + } + + for (p=p->firstpart; p; p=p->next) + { + printf("%*s{\n", level*4, ""); + dodump(p, level+1); + printf("%*s}\n", level*4, ""); + } +} + +void rfc2045_xdump(struct rfc2045 *p) +{ + dodump(p, 0); +} diff --git a/packages/clib/maildrop/rfc2045/stamp-h.in b/packages/clib/maildrop/rfc2045/stamp-h.in new file mode 100644 index 000000000..e69de29bb diff --git a/packages/clib/maildrop/rfc2045/stamp-h1 b/packages/clib/maildrop/rfc2045/stamp-h1 new file mode 100644 index 000000000..4547fe1b5 --- /dev/null +++ b/packages/clib/maildrop/rfc2045/stamp-h1 @@ -0,0 +1 @@ +timestamp for config.h diff --git a/packages/clib/maildrop/rfc822/ChangeLog b/packages/clib/maildrop/rfc822/ChangeLog new file mode 100644 index 000000000..eaed857bd --- /dev/null +++ b/packages/clib/maildrop/rfc822/ChangeLog @@ -0,0 +1,33 @@ +[Aug 18 2009] + + * CLEANUP: Bug#413: Complete 'make distclean'. Feliks Kluzniak + +[Mar 19 2009] + + * CLEANUP: Removed all trailing whitespace from all source-files. + This avoids many GIT (merge) warnings. + +[Sep 11 2008] + + * PORT: Add AC_PREREQ to configure.h for systems that auto-select autoconf + versions. After tip by Ulrich Neumerkel. + +[Aug 11 2008] + + * INSTALL: Remove all configure files from the git repository + + +Mon Apr 5 00:58:37 EDT 1999 + +* Yes, I've decided to start a Change Log. librfc822 now has a life of its +own, so it might as well have it. + +* Courier needs tokens in a link list, not an array. Rewrote most token +handling code. + +* Fixed some issues with handling of () comments. + +* Changed *pr* functions to pass along a caller-provided void, also for + courier. librfc822 should now be threadable (like, who cares...) + +* Added a testsuite diff --git a/packages/clib/maildrop/rfc822/Makefile b/packages/clib/maildrop/rfc822/Makefile new file mode 100644 index 000000000..73682dd6e --- /dev/null +++ b/packages/clib/maildrop/rfc822/Makefile @@ -0,0 +1,35 @@ +################################################################ +# Makefile for librfc822.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=../../../swipl-ld.sh +CFLAGS=-fPIC -Wall -DHAVE_CONFIG_H +LIBS= +AR=ar +RANLIB=ranlib + +OBJ= rfc822.o rfc822_getaddr.o rfc822_getaddrs.o \ + rfc822_mkdate.o rfc822_parsedt.o rfc2047u.o \ + rfc2047.o imapsubj.o imaprefs.o + +all: librfc822.a + +librfc822.a: $(OBJ) + rm -f librfc822.a + $(AR) r librfc822.a $(OBJ) + $(RANLIB) librfc822.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc822.a + rm -rf autom4te.cache + rm -f stamp-h1 diff --git a/packages/clib/maildrop/rfc822/Makefile.in b/packages/clib/maildrop/rfc822/Makefile.in new file mode 100644 index 000000000..a0998876f --- /dev/null +++ b/packages/clib/maildrop/rfc822/Makefile.in @@ -0,0 +1,45 @@ +################################################################ +# Makefile for librfc822.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ + +ifeq (@PROLOG_SYSTEM@,yap) + +srcdir=@srcdir@ + +SHLIB_CFLAGS=@SHLIB_CFLAGS@ + +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $< -o $@ +endif + +OBJ= rfc822.o rfc822_getaddr.o rfc822_getaddrs.o \ + rfc822_mkdate.o rfc822_parsedt.o rfc2047u.o \ + rfc2047.o imapsubj.o imaprefs.o + +all: librfc822.a + +librfc822.a: $(OBJ) + rm -f librfc822.a + $(AR) r librfc822.a $(OBJ) + $(RANLIB) librfc822.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc822.a + rm -rf autom4te.cache + rm -f stamp-h1 diff --git a/packages/clib/maildrop/rfc822/Makefile.in~ b/packages/clib/maildrop/rfc822/Makefile.in~ new file mode 100644 index 000000000..4d4c3a21b --- /dev/null +++ b/packages/clib/maildrop/rfc822/Makefile.in~ @@ -0,0 +1,40 @@ +################################################################ +# Makefile for librfc822.a +# +# Author: Jan Wielemaker (wielemak@science.uva.nl) +################################################################ + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ + +ifeq (@PROLOG_SYSTEM@,yap) +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $< -o $@ +endif + +OBJ= rfc822.o rfc822_getaddr.o rfc822_getaddrs.o \ + rfc822_mkdate.o rfc822_parsedt.o rfc2047u.o \ + rfc2047.o imapsubj.o imaprefs.o + +all: librfc822.a + +librfc822.a: $(OBJ) + rm -f librfc822.a + $(AR) r librfc822.a $(OBJ) + $(RANLIB) librfc822.a + + +################################################################ +# Clean +################################################################ + +clean: + rm -f $(OBJ) *~ *.o *% a.out core config.log + +distclean: clean + rm -f Makefile config.status config.h librfc822.a + rm -rf autom4te.cache + rm -f stamp-h1 diff --git a/packages/clib/maildrop/rfc822/Makefile.mak b/packages/clib/maildrop/rfc822/Makefile.mak new file mode 100644 index 000000000..14b2579e9 --- /dev/null +++ b/packages/clib/maildrop/rfc822/Makefile.mak @@ -0,0 +1,32 @@ +# Destinations. Please edit +prefix=c:\Documents and Settings\jan +LIBDIR=$(prefix)\lib64 +INCDIR=$(prefix)\include + +CC=cl.exe +AR=lib.exe +CFLAGS=/MD /W3 /O2 /EHsc /DNDEBUG /D__WINDOWS__ /I.. /nologo /c + +OUT=rfc822.lib + +OBJ= rfc822.obj rfc822_getaddr.obj rfc822_getaddrs.obj \ + rfc822_mkdate.obj rfc822_parsedt.obj rfc2047u.obj \ + rfc2047.obj imapsubj.obj imaprefs.obj + +.c.obj: + @$(CC) $(CFLAGS) /Fo$@ $< + +$(OUT): $(OBJ) + del $@ + $(AR) /out:$@ /nologo $(OBJ) + +install: $(OUT) + copy $(OUT) "$(LIBDIR)" + copy rfc822.h "$(INCDIR)" + +clean:: + del *~ *.obj + +distclean: clean + del $(OUT) + diff --git a/packages/clib/maildrop/rfc822/aclocal.m4 b/packages/clib/maildrop/rfc822/aclocal.m4 new file mode 100644 index 000000000..5f6395127 --- /dev/null +++ b/packages/clib/maildrop/rfc822/aclocal.m4 @@ -0,0 +1,1044 @@ +# generated automatically by aclocal 1.9.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.1])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 6 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# serial 7 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 7 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/packages/clib/maildrop/rfc822/config.h b/packages/clib/maildrop/rfc822/config.h new file mode 100644 index 000000000..9e0d4236b --- /dev/null +++ b/packages/clib/maildrop/rfc822/config.h @@ -0,0 +1,109 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Whether we have libunicode.a */ +/* #undef HAVE_LIBUNICODE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strncasecmp' function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Whether daylight savings time offset is set via the altzone variable */ +/* #undef USE_TIME_ALTZONE */ + +/* Whether daylight savings time offset is set via the tm_isdst member */ +#define USE_TIME_DAYLIGHT 1 + +/* Whether time offset is specified via the tm_gmtoff member */ +/* #undef USE_TIME_GMTOFF */ + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/packages/clib/maildrop/rfc822/config.h.in b/packages/clib/maildrop/rfc822/config.h.in new file mode 100644 index 000000000..6b746cb3f --- /dev/null +++ b/packages/clib/maildrop/rfc822/config.h.in @@ -0,0 +1,108 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Whether we have libunicode.a */ +#undef HAVE_LIBUNICODE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Whether daylight savings time offset is set via the altzone variable */ +#undef USE_TIME_ALTZONE + +/* Whether daylight savings time offset is set via the tm_isdst member */ +#undef USE_TIME_DAYLIGHT + +/* Whether time offset is specified via the tm_gmtoff member */ +#undef USE_TIME_GMTOFF + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/packages/clib/maildrop/rfc822/config.log b/packages/clib/maildrop/rfc822/config.log new file mode 100644 index 000000000..5f9f76039 --- /dev/null +++ b/packages/clib/maildrop/rfc822/config.log @@ -0,0 +1,643 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = xato +uname -m = x86_64 +uname -r = 2.6.32-22-generic +uname -s = Linux +uname -v = #33-Ubuntu SMP Wed Apr 28 13:28:05 UTC 2010 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/vsc/Yap/Prologs/pl-devel/bin +PATH: /home/vsc/bin +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /sbin +PATH: /bin +PATH: /usr/games +PATH: /home/vsc/lgtsvn/xml +PATH: /home/vsc/lgtsvn/scripts +PATH: /home/vsc/lgtsvn/integration + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2158: checking for gcc +configure:2185: result: ../../../swipl-ld.sh +configure:2414: checking for C compiler version +configure:2423: ../../../swipl-ld.sh --version >&5 +gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 +Copyright (C) 2009 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2434: $? = 0 +configure:2423: ../../../swipl-ld.sh -v >&5 +Using built-in specs. +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) +configure:2434: $? = 0 +configure:2423: ../../../swipl-ld.sh -V >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2434: $? = 1 +configure:2423: ../../../swipl-ld.sh -qversion >&5 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 0 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 1 has invalid symbol index 12 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 2 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 3 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 4 has invalid symbol index 11 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 5 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 6 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 7 has invalid symbol index 13 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 8 has invalid symbol index 2 +/usr/bin/ld: /usr/lib/debug/usr/lib/crt1.o(.debug_info): relocation 9 has invalid symbol index 2 +... rest of stderr output deleted ... +configure:2434: $? = 1 +configure:2454: checking whether the C compiler works +configure:2476: ../../../swipl-ld.sh -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2480: $? = 0 +configure:2529: result: yes +configure:2532: checking for C compiler default output file name +configure:2534: result: a.out +configure:2540: checking for suffix of executables +configure:2547: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2551: $? = 0 +configure:2573: result: +configure:2595: checking whether we are cross compiling +configure:2603: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:2607: $? = 0 +configure:2614: ./conftest +configure:2618: $? = 0 +configure:2633: result: no +configure:2638: checking for suffix of object files +configure:2660: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2664: $? = 0 +configure:2685: result: o +configure:2689: checking whether we are using the GNU C compiler +configure:2708: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2708: $? = 0 +configure:2717: result: yes +configure:2726: checking whether ../../../swipl-ld.sh accepts -g +configure:2746: ../../../swipl-ld.sh -c -g conftest.c >&5 +configure:2746: $? = 0 +configure:2787: result: yes +configure:2804: checking for ../../../swipl-ld.sh option to accept ISO C89 +configure:2868: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:2868: $? = 0 +configure:2881: result: none needed +configure:2903: checking for ar +configure:2919: found /usr/bin/ar +configure:2931: result: ar +configure:2982: checking for ranlib +configure:2998: found /usr/bin/ranlib +configure:3009: result: ranlib +configure:3038: checking how to run the C preprocessor +configure:3069: ../../../swipl-ld.sh -E conftest.c +configure:3069: $? = 0 +configure:3083: ../../../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3083: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3108: result: ../../../swipl-ld.sh -E +configure:3128: ../../../swipl-ld.sh -E conftest.c +configure:3128: $? = 0 +configure:3142: ../../../swipl-ld.sh -E conftest.c +conftest.c:9:28: error: ac_nonexistent.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3142: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include +configure:3171: checking for grep that handles long lines and -e +configure:3229: result: /bin/grep +configure:3234: checking for egrep +configure:3296: result: /bin/grep -E +configure:3301: checking for ANSI C header files +configure:3321: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3321: $? = 0 +configure:3394: ../../../swipl-ld.sh -o conftest -fPIC conftest.c >&5 +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.01 sec, 37,800 bytes +% halt +configure:3394: $? = 0 +configure:3394: ./conftest +configure:3394: $? = 0 +configure:3405: result: yes +configure:3418: checking for sys/types.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for sys/stat.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for stdlib.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for string.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for memory.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for strings.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for inttypes.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for stdint.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3418: checking for unistd.h +configure:3418: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3418: $? = 0 +configure:3418: result: yes +configure:3432: checking minix/config.h usability +configure:3432: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +conftest.c:52:26: error: minix/config.h: No such file or directory +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3432: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:3432: result: no +configure:3432: checking minix/config.h presence +configure:3432: ../../../swipl-ld.sh -E conftest.c +conftest.c:19:26: error: minix/config.h: No such file or directory +gcc -E returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3432: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:3432: result: no +configure:3432: checking for minix/config.h +configure:3432: result: no +configure:3453: checking whether it is safe to define __EXTENSIONS__ +configure:3471: ../../../swipl-ld.sh -c -fPIC conftest.c >&5 +configure:3471: $? = 0 +configure:3478: result: yes +configure:3499: checking for ANSI C header files +configure:3603: result: yes +configure:3612: checking for an ANSI C-conforming const +configure:3677: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:54: warning: 't' is used uninitialized in this function +conftest.c:70: warning: 'b' may be used uninitialized in this function +configure:3677: $? = 0 +configure:3684: result: yes +configure:3692: checking for size_t +configure:3692: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3692: $? = 0 +configure:3692: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:61: error: expected expression before ')' token +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3692: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((size_t))) +| return 0; +| ; +| return 0; +| } +configure:3692: result: yes +configure:3703: checking whether struct tm is in sys/time.h or time.h +configure:3723: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +configure:3723: $? = 0 +configure:3730: result: time.h +configure:3743: checking for strcasecmp +configure:3743: ../../../swipl-ld.sh -o conftest -fPIC -Wall conftest.c >&5 +conftest.c:48: warning: conflicting types for built-in function 'strcasecmp' +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3743: $? = 0 +configure:3743: result: yes +configure:3743: checking for strncasecmp +configure:3743: ../../../swipl-ld.sh -o conftest -fPIC -Wall conftest.c >&5 +conftest.c:49: warning: conflicting types for built-in function 'strncasecmp' +% /home/vsc/Yap/Prologs/pl-devel/library/listing compiled into prolog_listing 0.00 sec, 37,800 bytes +% halt +configure:3743: $? = 0 +configure:3743: result: yes +configure:3754: checking how to calculate alternate timezone +configure:3780: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:34: warning: 'main' is normally a non-static function +conftest.c: In function 'main': +conftest.c:36: error: 'altzone' undeclared (first use in this function) +conftest.c:36: error: (Each undeclared identifier is reported only once +conftest.c:36: error: for each function it appears in.) +conftest.c:37: warning: unused variable 'offset' +conftest.c:36: warning: unused variable 't' +gcc returned code 256 +*** /home/vsc/Yap/Prologs/pl-devel/src/../src/swipl-ld exit status 1 +configure:3780: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define __EXTENSIONS__ 1 +| #define _ALL_SOURCE 1 +| #define _GNU_SOURCE 1 +| #define _POSIX_PTHREAD_SEMANTICS 1 +| #define _TANDEM_SOURCE 1 +| #define STDC_HEADERS 1 +| #define HAVE_STRCASECMP 1 +| #define HAVE_STRNCASECMP 1 +| /* end confdefs.h. */ +| +| #include +| +| int +| main () +| { +| +| int main() +| { +| time_t t=altzone; +| int offset = -timezone; +| +| return (0); +| } +| +| ; +| return 0; +| } +configure:3804: ../../../swipl-ld.sh -c -fPIC -Wall conftest.c >&5 +conftest.c: In function 'main': +conftest.c:34: warning: 'main' is normally a non-static function +conftest.c: In function 'main': +conftest.c:37: warning: unused variable 'offset' +conftest.c:36: warning: unused variable 'n' +configure:3804: $? = 0 +configure:3844: result: daylight +configure:3988: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on xato + +config.status:811: creating Makefile +config.status:811: creating config.h +config.status:972: config.h is unchanged + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_env_CC_set=set +ac_cv_env_CC_value=../../../swipl-ld.sh +ac_cv_env_CFLAGS_set=set +ac_cv_env_CFLAGS_value=-fPIC +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set=set +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_strcasecmp=yes +ac_cv_func_strncasecmp=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_minix_config_h=no +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_unistd_h=yes +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_GREP=/bin/grep +ac_cv_prog_AR=ar +ac_cv_prog_CPP='../../../swipl-ld.sh -E' +ac_cv_prog_ac_ct_CC=../../../swipl-ld.sh +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_safe_to_define___extensions__=yes +ac_cv_struct_tm=time.h +ac_cv_type_size_t=yes +librfc822_cv_SYS_TIMEZONE=daylight + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +AR='ar' +CC='../../../swipl-ld.sh' +CFLAGS='-fPIC -Wall' +CPP='../../../swipl-ld.sh -E' +CPPFLAGS='' +DEFS='-DHAVE_CONFIG_H' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +EXEEXT='' +GREP='/bin/grep' +LDFLAGS='' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +OBJEXT='o' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_URL='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +RANLIB='ranlib' +SHELL='/bin/bash' +ac_ct_CC='../../../swipl-ld.sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_URL "" +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define __EXTENSIONS__ 1 +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +#define _POSIX_PTHREAD_SEMANTICS 1 +#define _TANDEM_SOURCE 1 +#define STDC_HEADERS 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define USE_TIME_DAYLIGHT 1 + +configure: exit 0 diff --git a/packages/clib/maildrop/rfc822/configure b/packages/clib/maildrop/rfc822/configure new file mode 100755 index 000000000..0cb088d41 --- /dev/null +++ b/packages/clib/maildrop/rfc822/configure @@ -0,0 +1,5172 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.65. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="rfc822.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +EGREP +GREP +CPP +RANLIB +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AR +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_type + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.65. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = x""yes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +if test "$GCC" = yes ; then + CXXFLAGS="$CXXFLAGS -Wall" + CFLAGS="$CFLAGS -Wall" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = x""yes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if test "${ac_cv_struct_tm+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + + + +for ac_func in strcasecmp strncasecmp +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to calculate alternate timezone" >&5 +$as_echo_n "checking how to calculate alternate timezone... " >&6; } +if test "${librfc822_cv_SYS_TIMEZONE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +int main() +{ +time_t t=altzone; +int offset = -timezone; + + return (0); +} + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + librfc822_cv_SYS_TIMEZONE=altzone +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +int main() +{ +int n=daylight; +int offset = -timezone; + + return (0); +} + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + librfc822_cv_SYS_TIMEZONE=daylight +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +extern struct tm dummy; + +int +main () +{ + +int main() +{ +long n=dummy.tm_gmtoff; + + return (0); +} + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + librfc822_cv_SYS_TIMEZONE=tm_gmtoff +else + librfc822_cv_SYS_TIMEZONE=unknown + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $librfc822_cv_SYS_TIMEZONE" >&5 +$as_echo "$librfc822_cv_SYS_TIMEZONE" >&6; } + +case $librfc822_cv_SYS_TIMEZONE in +tm_gmtoff) + +cat >>confdefs.h <<_ACEOF +#define USE_TIME_GMTOFF 1 +_ACEOF + + ;; +altzone) + +cat >>confdefs.h <<_ACEOF +#define USE_TIME_ALTZONE 1 +_ACEOF + + ;; +daylight) + +cat >>confdefs.h <<_ACEOF +#define USE_TIME_DAYLIGHT 1 +_ACEOF + + ;; +*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot figure out how to calculate the alternate timezone" >&5 +$as_echo "$as_me: WARNING: Cannot figure out how to calculate the alternate timezone" >&2;} + ;; +esac + +if test -d ../unicode +then + +cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUNICODE 1 +_ACEOF + +fi + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.65. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.65, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + "$ac_file" | "$ac_file":* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for "$ac_file"" >`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/packages/clib/maildrop/rfc822/configure.in b/packages/clib/maildrop/rfc822/configure.in new file mode 100644 index 000000000..fcd85f885 --- /dev/null +++ b/packages/clib/maildrop/rfc822/configure.in @@ -0,0 +1,105 @@ +dnl Process this file with autoconf to produce a configure script. +dnl $Id$ +dnl +dnl Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +dnl distribution information. + +AC_INIT(rfc822.c) +AC_PREREQ([2.50]) +AC_CONFIG_HEADER(config.h) +AC_SUBST(AR) + +dnl Checks for programs. +AC_PROG_CC +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB + +AC_USE_SYSTEM_EXTENSIONS + +if test "$GCC" = yes ; then + CXXFLAGS="$CXXFLAGS -Wall" + CFLAGS="$CFLAGS -Wall" +fi + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_STRUCT_TM + +dnl Checks for library functions. + +AC_CHECK_FUNCS(strcasecmp strncasecmp) + +AC_CACHE_CHECK([how to calculate alternate timezone],librfc822_cv_SYS_TIMEZONE, + +AC_TRY_COMPILE([ +#include +],[ +int main() +{ +time_t t=altzone; +int offset = -timezone; + + return (0); +} +], librfc822_cv_SYS_TIMEZONE=altzone, + + AC_TRY_COMPILE([ +#include +],[ +int main() +{ +int n=daylight; +int offset = -timezone; + + return (0); +} + ], librfc822_cv_SYS_TIMEZONE=daylight, + + AC_TRY_COMPILE([ +#include + +extern struct tm dummy; +],[ +int main() +{ +long n=dummy.tm_gmtoff; + + return (0); +} + ] ,librfc822_cv_SYS_TIMEZONE=tm_gmtoff, + librfc822_cv_SYS_TIMEZONE=unknown + ) + ) + ) +) + +case $librfc822_cv_SYS_TIMEZONE in +tm_gmtoff) + AC_DEFINE_UNQUOTED(USE_TIME_GMTOFF,1, + [Whether time offset is specified via the tm_gmtoff member]) + ;; +altzone) + AC_DEFINE_UNQUOTED(USE_TIME_ALTZONE,1, + [Whether daylight savings time offset is set via the altzone variable]) + ;; +daylight) + AC_DEFINE_UNQUOTED(USE_TIME_DAYLIGHT,1, + [Whether daylight savings time offset is set via the tm_isdst member]) + ;; +*) + AC_MSG_WARN(Cannot figure out how to calculate the alternate timezone, will use GMT) + ;; +esac + +if test -d ../unicode +then + AC_DEFINE_UNQUOTED(HAVE_LIBUNICODE,1,[Whether we have libunicode.a]) +fi + +AC_OUTPUT(Makefile) diff --git a/packages/clib/maildrop/rfc822/imaprefs.c b/packages/clib/maildrop/rfc822/imaprefs.c new file mode 100644 index 000000000..101d9c6d0 --- /dev/null +++ b/packages/clib/maildrop/rfc822/imaprefs.c @@ -0,0 +1,921 @@ +/* +** Copyright 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ + +#ifndef __WINDOWS__ +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "rfc822.h" +#include "imaprefs.h" + +static void swapmsgdata(struct imap_refmsg *a, struct imap_refmsg *b) +{ + char *cp; + char c; + time_t t; + unsigned long ul; + +#define swap(a,b,tmp) (tmp)=(a); (a)=(b); (b)=(tmp); + + swap(a->msgid, b->msgid, cp); + swap(a->isdummy, b->isdummy, c); + swap(a->flag2, b->flag2, c); + + swap(a->timestamp, b->timestamp, t); + swap(a->seqnum, b->seqnum, ul); + +#undef swap +} + +struct imap_refmsgtable *rfc822_threadalloc() +{ +struct imap_refmsgtable *p; + + p=(struct imap_refmsgtable *)malloc(sizeof(struct imap_refmsgtable)); + if (p) + memset(p, 0, sizeof(*p)); + return (p); +} + +void rfc822_threadfree(struct imap_refmsgtable *p) +{ +int i; +struct imap_refmsghash *h; +struct imap_subjlookup *s; +struct imap_refmsg *m; + + for (i=0; ihashtable)/sizeof(p->hashtable[0]); i++) + while ((h=p->hashtable[i]) != 0) + { + p->hashtable[i]=h->nexthash; + free(h); + } + + for (i=0; isubjtable)/sizeof(p->subjtable[0]); i++) + while ((s=p->subjtable[i]) != 0) + { + p->subjtable[i]=s->nextsubj; + free(s->subj); + free(s); + } + + while ((m=p->firstmsg) != 0) + { + p->firstmsg=m->next; + if (m->subj) + free(m->subj); + free(m); + } + free(p); +} + +static int hashmsgid(const char *msgid) +{ +unsigned long hashno=0; + + while (*msgid) + { + unsigned long n= (hashno << 1); + +#define HMIDS (((struct imap_refmsgtable *)0)->hashtable) +#define HHMIDSS ( sizeof(HMIDS) / sizeof( HMIDS[0] )) + + if (hashno & HHMIDSS ) + n ^= 1; + + hashno= n ^ (unsigned char)*msgid++; + } + + return (hashno % HHMIDSS); +} + +struct imap_refmsg *rfc822_threadallocmsg(struct imap_refmsgtable *mt, + const char *msgid) +{ +int n=hashmsgid(msgid); +struct imap_refmsg *msgp= (struct imap_refmsg *) + malloc(sizeof(struct imap_refmsg)+1+strlen(msgid)); +struct imap_refmsghash *h, **hp; + + if (!msgp) return (0); + memset(msgp, 0, sizeof(*msgp)); + strcpy ((msgp->msgid=(char *)(msgp+1)), msgid); + + h=(struct imap_refmsghash *)malloc(sizeof(struct imap_refmsghash)); + if (!h) + { + free(msgp); + return (0); + } + + for (hp= &mt->hashtable[n]; *hp; hp= & (*hp)->nexthash) + { + if (strcmp( (*hp)->msg->msgid, msgp->msgid) > 0) + break; + } + + h->nexthash= *hp; + *hp=h; + h->msg=msgp; + + msgp->last=mt->lastmsg; + + if (mt->lastmsg) + mt->lastmsg->next=msgp; + else + mt->firstmsg=msgp; + + mt->lastmsg=msgp; + return (msgp); +} + +struct imap_refmsg *rfc822_threadsearchmsg(struct imap_refmsgtable *mt, + const char *msgid) +{ +int n=hashmsgid(msgid); +struct imap_refmsghash *h; + + for (h= mt->hashtable[n]; h; h= h->nexthash) + { + int rc=strcmp(h->msg->msgid, msgid); + + if (rc == 0) return (h->msg); + if (rc > 0) + break; + } + return (0); +} + +static int findsubj(struct imap_refmsgtable *mt, const char *s, int *isrefwd, + int create, struct imap_subjlookup **ptr) +{ + char *ss=rfc822_coresubj(s, isrefwd); + int n; + struct imap_subjlookup **h; + struct imap_subjlookup *newsubj; + + if (!ss) return (-1); + n=hashmsgid(ss); + + for (h= &mt->subjtable[n]; *h; h= &(*h)->nextsubj) + { + int rc=strcmp((*h)->subj, ss); + + if (rc == 0) + { + free(ss); + *ptr= *h; + return (0); + } + if (rc > 0) + break; + } + if (!create) + { + free(ss); + *ptr=0; + return (0); + } + + newsubj=malloc(sizeof(struct imap_subjlookup)); + if (!newsubj) + { + free(ss); + return (-1); + } + memset(newsubj, 0, sizeof(*newsubj)); + newsubj->subj=ss; + newsubj->nextsubj= *h; + newsubj->msgisrefwd= *isrefwd; + *h=newsubj; + *ptr=newsubj; + return (0); +} + +static void linkparent(struct imap_refmsg *msg, struct imap_refmsg *lastmsg) +{ + msg->parent=lastmsg; + msg->prevsib=lastmsg->lastchild; + if (msg->prevsib) + msg->prevsib->nextsib=msg; + else + lastmsg->firstchild=msg; + + lastmsg->lastchild=msg; + msg->nextsib=0; +} + + +static void breakparent(struct imap_refmsg *m) +{ + if (!m->parent) return; + + if (m->prevsib) m->prevsib->nextsib=m->nextsib; + else m->parent->firstchild=m->nextsib; + + if (m->nextsib) m->nextsib->prevsib=m->prevsib; + else m->parent->lastchild=m->prevsib; + m->parent=0; +} + +static struct imap_refmsg *dorefcreate(struct imap_refmsgtable *mt, + const char *newmsgid, + struct rfc822a *a) + /* a - references header */ +{ +struct imap_refmsg *lastmsg=0, *m; +struct imap_refmsg *msg; +int n; + +/* + (A) Using the Message-IDs in the message's references, link + the corresponding messages together as parent/child. Make + the first reference the parent of the second (and the second + a child of the first), the second the parent of the third + (and the third a child of the second), etc. The following + rules govern the creation of these links: + + If no reference message can be found with a given + Message-ID, create a dummy message with this ID. Use + this dummy message for all subsequent references to this + ID. +*/ + + for (n=0; nnaddrs; n++) + { + char *msgid=rfc822_getaddr(a, n); + + msg=*msgid ? rfc822_threadsearchmsg(mt, msgid ? msgid:""):0; + if (!msg) + { + msg=rfc822_threadallocmsg(mt, msgid ? msgid:""); + if (!msg) + { + if (msgid) + free(msgid); + + return (0); + } + msg->isdummy=1; + } + + if (msgid) + free(msgid); + +/* + If a reference message already has a parent, don't change + the existing link. +*/ + + if (lastmsg == 0 || msg->parent) + { + lastmsg=msg; + continue; + } + +/* + Do not create a parent/child link if creating that link + would introduce a loop. For example, before making + message A the parent of B, make sure that A is not a + descendent of B. + +*/ + + for (m=lastmsg; m; m=m->parent) + if (strcmp(m->msgid, msg->msgid) == 0) + break; + if (m) + { + lastmsg=msg; + continue; + } + + linkparent(msg, lastmsg); + + lastmsg=msg; + } + +/* + (B) Create a parent/child link between the last reference + (or NIL if there are no references) and the current message. + If the current message has a parent already, break the + current parent/child link before creating the new one. Note + that if this message has no references, that it will now + have no parent. + + NOTE: The parent/child links MUST be kept consistent with + one another at ALL times. + +*/ + + msg=*newmsgid ? rfc822_threadsearchmsg(mt, newmsgid):0; + + /* + If a message does not contain a Message-ID header line, + or the Message-ID header line does not contain a valid + Message ID, then assign a unique Message ID to this + message. + + Implementation note: empty msgid, plus dupe check below, + implements that. + */ + + if (msg && msg->isdummy) + { + msg->isdummy=0; + if (msg->parent) + breakparent(msg); + } + else + { +#if 1 + /* + ** If two or more messages have the same Message ID, assign + ** a unique Message ID to each of the duplicates. + ** + ** Implementation note: just unlink the existing message from + ** it's parents/children. + */ + if (msg) + { + while (msg->firstchild) + breakparent(msg->firstchild); + breakparent(msg); + newmsgid=""; + + /* Create new entry with an empty msgid, if any more + ** msgids come, they'll hit the dupe check again. + */ + + } +#endif + msg=rfc822_threadallocmsg(mt, newmsgid); + if (!msg) return (0); + } + + if (lastmsg) + { + for (m=lastmsg; m; m=m->parent) + if (strcmp(m->msgid, msg->msgid) == 0) + break; + if (!m) + linkparent(msg, lastmsg); + } + return (msg); +} + +struct imap_refmsg *rfc822_threadmsg(struct imap_refmsgtable *mt, + const char *msgidhdr, + const char *refhdr, + const char *subjheader, + const char *dateheader, + unsigned long seqnum) +{ + struct rfc822t *t; + struct rfc822a *a; + struct imap_refmsg *m; + + char *msgid_s; + + t=rfc822t_alloc(msgidhdr ? msgidhdr:"", 0); + if (!t) + return (0); + a=rfc822a_alloc(t); + if (!a) + { + rfc822t_free(t); + return (0); + } + + msgid_s=a->naddrs > 0 ? rfc822_getaddr(a, 0):strdup(""); + + rfc822a_free(a); + rfc822t_free(t); + + if (!msgid_s) + return (0); + + t=rfc822t_alloc(refhdr ? refhdr:"", 0); + if (!t) + { + free(msgid_s); + return (0); + } + + a=rfc822a_alloc(t); + if (!a) + { + rfc822t_free(t); + free(msgid_s); + return (0); + } + + m=dorefcreate(mt, msgid_s, a); + + rfc822a_free(a); + rfc822t_free(t); + free(msgid_s); + + if (!m) + return (0); + + if (subjheader && (m->subj=strdup(subjheader)) == 0) + return (0); /* Cleanup in rfc822_threadfree() */ + + m->timestamp=dateheader ? rfc822_parsedt(dateheader):0; + + m->seqnum=seqnum; + + return (m); +} + +/* + (2) Gather together all of the messages that have no parents + and make them all children (siblings of one another) of a dummy + parent (the "root"). These messages constitute first messages + of the threads created thus far. + +*/ + +struct imap_refmsg *rfc822_threadgetroot(struct imap_refmsgtable *mt) +{ + struct imap_refmsg *root, *m; + + if (mt->rootptr) + return (mt->rootptr); + + root=rfc822_threadallocmsg(mt, "(root)"); + + if (!root) return (0); + + root->parent=root; /* Temporary */ + root->isdummy=1; + + for (m=mt->firstmsg; m; m=m->next) + if (!m->parent) + { + if (m->isdummy && m->firstchild == 0) + continue; /* Can happen in reference creation */ + + linkparent(m, root); + } + root->parent=NULL; + return (mt->rootptr=root); +} + +/* +** +** (3) Prune dummy messages from the thread tree. Traverse each +** thread under the root, and for each message: +*/ + +void rfc822_threadprune(struct imap_refmsgtable *mt) +{ + struct imap_refmsg *msg; + + for (msg=mt->firstmsg; msg; msg=msg->next) + { + struct imap_refmsg *saveparent, *m; + + if (!msg->parent) + continue; // The root, need it later. + + if (!msg->isdummy) + continue; + + /* + ** + ** If it is a dummy message with NO children, delete it. + */ + + if (msg->firstchild == 0) + { + breakparent(msg); + /* + ** Don't free the node, it'll be done on msgtable + ** purge. + */ + continue; + } + + /* + ** If it is a dummy message with children, delete it, but + ** promote its children to the current level. In other words, + ** splice them in with the dummy's siblings. + ** + ** Do not promote the children if doing so would make them + ** children of the root, unless there is only one child. + */ + + if (msg->firstchild->nextsib && + msg->parent->parent) + continue; + + saveparent=msg->parent; + breakparent(msg); + + while ((m=msg->firstchild) != 0) + { + breakparent(m); + linkparent(m, saveparent); + } + } +} + +/* +** (4) Gather together messages under the root that have the same +** extracted subject text. +** +** (A) Create a table for associating extracted subjects with +** messages. +** +** (B) Populate the subject table with one message per +** extracted subject. For each message under the root: +*/ + +int rfc822_threadsortsubj(struct imap_refmsgtable *mt, + struct imap_refmsg *root) +{ + struct imap_refmsg *toproot, *p; + + for (toproot=root->firstchild; toproot; toproot=toproot->nextsib) + { + const char *subj; + struct imap_subjlookup *subjtop; + int isrefwd; + + /* + ** (i) Find the subject of this thread by extracting the + ** base subject from the current message, or its first child + ** if the current message is a dummy. + */ + + p=toproot; + if (p->isdummy) + p=p->firstchild; + + subj=p->subj ? p->subj:""; + + + /* + ** (ii) If the extracted subject is empty, skip this + ** message. + */ + + if (*subj == 0) + continue; + + /* + ** (iii) Lookup the message associated with this extracted + ** subject in the table. + */ + + if (findsubj(mt, subj, &isrefwd, 1, &subjtop)) + return (-1); + + /* + ** + ** (iv) If there is no message in the table with this + ** subject, add the current message and the extracted + ** subject to the subject table. + */ + + if (subjtop->msg == 0) + { + subjtop->msg=toproot; + subjtop->msgisrefwd=isrefwd; + continue; + } + + /* + ** Otherwise, replace the message in the table with the + ** current message if the message in the table is not a + ** dummy AND either of the following criteria are true: + */ + + if (!subjtop->msg->isdummy) + { + /* + ** The current message is a dummy + ** + */ + + if (toproot->isdummy) + { + subjtop->msg=toproot; + subjtop->msgisrefwd=isrefwd; + continue; + } + + /* + ** The message in the table is a reply or forward (its + ** original subject contains a subj-refwd part and/or a + ** "(fwd)" subj-trailer) and the current message is + not. + */ + + if (subjtop->msgisrefwd && !isrefwd) + { + subjtop->msg=toproot; + subjtop->msgisrefwd=isrefwd; + } + } + } + return (0); +} + +/* +** (C) Merge threads with the same subject. For each message +** under the root: +*/ + +int rfc822_threadmergesubj(struct imap_refmsgtable *mt, + struct imap_refmsg *root) +{ + struct imap_refmsg *toproot, *p, *q, *nextroot; + char *str; + + for (toproot=root->firstchild; toproot; toproot=nextroot) + { + const char *subj; + struct imap_subjlookup *subjtop; + int isrefwd; + + nextroot=toproot->nextsib; + + /* + ** (i) Find the subject of this thread as in step 4.B.i + ** above. + */ + + p=toproot; + if (p->isdummy) + p=p->firstchild; + + subj=p->subj ? p->subj:""; + + /* + ** (ii) If the extracted subject is empty, skip this + ** message. + */ + + if (*subj == 0) + continue; + + /* + ** (iii) Lookup the message associated with this extracted + ** subject in the table. + */ + + if (findsubj(mt, subj, &isrefwd, 0, &subjtop) || subjtop == 0) + return (-1); + + /* + ** (iv) If the message in the table is the current message, + ** skip it. + */ + + /* NOTE - ptr comparison IS NOT LEGAL */ + + subjtop->msg->flag2=1; + if (toproot->flag2) + { + toproot->flag2=0; + continue; + } + subjtop->msg->flag2=0; + + /* + ** Otherwise, merge the current message with the one in the + ** table using the following rules: + ** + ** If both messages are dummies, append the current + ** message's children to the children of the message in + ** the table (the children of both messages become + ** siblings), and then delete the current message. + */ + + if (subjtop->msg->isdummy && toproot->isdummy) + { + while ((p=toproot->firstchild) != 0) + { + breakparent(p); + linkparent(p, subjtop->msg); + } + breakparent(toproot); + continue; + } + + /* + ** If the message in the table is a dummy and the current + ** message is not, make the current message a child of + ** the message in the table (a sibling of it's children). + */ + + if (subjtop->msg->isdummy) + { + breakparent(toproot); + linkparent(toproot, subjtop->msg); + continue; + } + + /* + ** If the current message is a reply or forward and the + ** message in the table is not, make the current message + ** a child of the message in the table (a sibling of it's + ** children). + */ + + if (isrefwd) + { + p=subjtop->msg; + if (p->isdummy) + p=p->firstchild; + + subj=p->subj ? p->subj:""; + + str=rfc822_coresubj(subj, &isrefwd); + + if (!str) + return (-1); + free(str); /* Don't really care */ + + if (!isrefwd) + { + breakparent(toproot); + linkparent(toproot, subjtop->msg); + continue; + } + } + + /* + ** Otherwise, create a new dummy container and make both + ** messages children of the dummy, and replace the + ** message in the table with the dummy message. + */ + + /* What we do is create a new message, then move the + ** contents of subjtop->msg (including its children) + ** to the new message, then make the new message a child + ** of subjtop->msg, and mark subjtop->msg as a dummy msg. + */ + + q=rfc822_threadallocmsg(mt, "(dummy)"); + if (!q) + return (-1); + + q->isdummy=1; + + swapmsgdata(q, subjtop->msg); + + while ((p=subjtop->msg->firstchild) != 0) + { + breakparent(p); + linkparent(p, q); + } + linkparent(q, subjtop->msg); + + breakparent(toproot); + linkparent(toproot, subjtop->msg); + } + return (0); +} + +/* +** (5) Traverse the messages under the root and sort each set of +** siblings by date. Traverse the messages in such a way that the +** "youngest" set of siblings are sorted first, and the "oldest" +** set of siblings are sorted last (grandchildren are sorted +** before children, etc). In the case of an exact match on date, +** use the order in which the messages appear in the mailbox (that +** is, by sequence number) to determine the order. In the case of +** a dummy message (which can only occur with top-level siblings), +** use its first child for sorting. +*/ + +static int cmp_msgs(const void *a, const void *b) +{ + struct imap_refmsg *ma=*(struct imap_refmsg **)a; + struct imap_refmsg *mb=*(struct imap_refmsg **)b; + time_t ta, tb; + unsigned long na, nb; + + while (ma && ma->isdummy) + ma=ma->firstchild; + + while (mb && mb->isdummy) + mb=mb->firstchild; + + ta=tb=0; + na=nb=0; + if (ma) + { + ta=ma->timestamp; + na=ma->seqnum; + } + if (mb) + { + tb=mb->timestamp; + nb=mb->seqnum; + } + + return (ta < tb ? -1: ta > tb ? 1: + na < nb ? -1: na > nb ? 1:0); +} + +struct imap_threadsortinfo { + struct imap_refmsgtable *mt; + struct imap_refmsg **sort_table; + size_t sort_table_cnt; +} ; + +static int dothreadsort(struct imap_threadsortinfo *, + struct imap_refmsg *); + +int rfc822_threadsortbydate(struct imap_refmsgtable *mt) +{ + struct imap_threadsortinfo itsi; + int rc; + + itsi.mt=mt; + itsi.sort_table=0; + itsi.sort_table_cnt=0; + + rc=dothreadsort(&itsi, mt->rootptr); + + if (itsi.sort_table) + free(itsi.sort_table); + return (rc); +} + +static int dothreadsort(struct imap_threadsortinfo *itsi, + struct imap_refmsg *p) +{ + struct imap_refmsg *q; + size_t i, n; + + for (q=p->firstchild; q; q=q->nextsib) + dothreadsort(itsi, q); + + n=0; + for (q=p->firstchild; q; q=q->nextsib) + ++n; + + if (n > itsi->sort_table_cnt) + { + struct imap_refmsg **new_array=(struct imap_refmsg **) + (itsi->sort_table ? + realloc(itsi->sort_table, + sizeof(struct imap_refmsg *)*n) + :malloc(sizeof(struct imap_refmsg *)*n)); + + if (!new_array) + return (-1); + + itsi->sort_table=new_array; + itsi->sort_table_cnt=n; + } + + n=0; + while ((q=p->firstchild) != 0) + { + breakparent(q); + itsi->sort_table[n++]=q; + } + + qsort(itsi->sort_table, n, sizeof(struct imap_refmsg *), cmp_msgs); + + for (i=0; isort_table[i], p); + return (0); +} + +struct imap_refmsg *rfc822_thread(struct imap_refmsgtable *mt) +{ + if (!mt->rootptr) + { + rfc822_threadprune(mt); + if ((mt->rootptr=rfc822_threadgetroot(mt)) == 0) + return (0); + if (rfc822_threadsortsubj(mt, mt->rootptr) || + rfc822_threadmergesubj(mt, mt->rootptr) || + rfc822_threadsortbydate(mt)) + { + mt->rootptr=0; + return (0); + } + } + + return (mt->rootptr); +} diff --git a/packages/clib/maildrop/rfc822/imaprefs.h b/packages/clib/maildrop/rfc822/imaprefs.h new file mode 100644 index 000000000..96a8aac6a --- /dev/null +++ b/packages/clib/maildrop/rfc822/imaprefs.h @@ -0,0 +1,97 @@ +/* +** $Id$ +*/ +#ifndef imaprefs_h +#define imaprefs_h + +/* +** Copyright 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Implement REFERENCES threading. +*/ + +/* The data structures */ + +struct imap_refmsg { + struct imap_refmsg *next, *last; /* Link list of all msgs */ + struct imap_refmsg *parent; /* my parent */ + struct imap_refmsg *firstchild, *lastchild; /* Children link list */ + struct imap_refmsg *prevsib, *nextsib; /* Link list of siblings */ + + char isdummy; /* this is a dummy node (for now) */ + char flag2; /* Additional flag */ + + char *msgid; /* msgid of this message */ + + char *subj; /* dynalloced subject of this msg */ + time_t timestamp; /* Timestamp */ + unsigned long seqnum; /* Sequence number */ +} ; + +struct imap_refmsgtable { + struct imap_refmsg *firstmsg, *lastmsg; /* Link list of all msgs */ + + /* hash table message id lookup */ + + struct imap_refmsghash *hashtable[512]; + + struct imap_subjlookup *subjtable[512]; + + struct imap_refmsg *rootptr; /* The root */ +} ; + +struct imap_refmsgtable *rfc822_threadalloc(void); +void rfc822_threadfree(struct imap_refmsgtable *); +struct imap_refmsg *rfc822_threadmsg(struct imap_refmsgtable *mt, + const char *msgidhdr, + const char *refhdr, + const char *subjheader, + const char *dateheader, + unsigned long seqnum); + +struct imap_refmsg *rfc822_thread(struct imap_refmsgtable *mt); + + /* INTERNAL FUNCTIONS FOLLOW */ + + +struct imap_refmsghash { + struct imap_refmsghash *nexthash; + struct imap_refmsg *msg; +} ; + +struct imap_subjlookup { + struct imap_subjlookup *nextsubj; + char *subj; + struct imap_refmsg *msg; + int msgisrefwd; +} ; + +struct imap_refmsg *rfc822_threadallocmsg(struct imap_refmsgtable *mt, + const char *msgid); +void rfc822_threadprune(struct imap_refmsgtable *mt); +struct imap_refmsg *rfc822_threadgetroot(struct imap_refmsgtable *mt); +struct imap_refmsg *rfc822_threadsearchmsg(struct imap_refmsgtable *mt, + const char *msgid); +int rfc822_threadsortsubj(struct imap_refmsgtable *mt, + struct imap_refmsg *root); +int rfc822_threadmergesubj(struct imap_refmsgtable *mt, + struct imap_refmsg *root); +int rfc822_threadsortbydate(struct imap_refmsgtable *mt); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packages/clib/maildrop/rfc822/imapsubj.c b/packages/clib/maildrop/rfc822/imapsubj.c new file mode 100644 index 000000000..ae02f269c --- /dev/null +++ b/packages/clib/maildrop/rfc822/imapsubj.c @@ -0,0 +1,254 @@ +/* +** Copyright 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ +#include +#include +#include +#include +#include "rfc822.h" +#ifndef __WINDOWS__ +#include "config.h" +#endif + +#if HAVE_STRCASECMP + +#else +#define strcasecmp stricmp +#endif + +#if HAVE_STRNCASECMP + +#else +#define strncasecmp strnicmp +#endif + + +/* Remove artifacts from the subject header */ + +static void stripsubj(char *s, int *hasrefwd) +{ + char *p; + char *q; + + for (p=q=s; *p; p++) + { + if (!isspace((int)(unsigned char)*p)) + { + *q++=*p; + continue; + } + while (p[1] && isspace((int)(unsigned char)p[1])) + { + ++p; + } + *q++=' '; + } + *q=0; + + for (;;) + { + /* + ** + ** (2) Remove all trailing text of the subject that matches + ** the subj-trailer ABNF, repeat until no more matches are + ** possible. + ** + ** subj-trailer = "(fwd)" / WSP + */ + + for (p=s; *p; p++) + ; + while (p > s) + { + if ( isspace((int)(unsigned char)p[-1])) + { + --p; + continue; + } + if (p-s >= 5 && strncasecmp(p-5, "(FWD)", 5) == 0) + { + p -= 5; + *hasrefwd=1; + continue; + } + break; + } + *p=0; + + for (p=s; *p; ) + { + int isrefwd=0; + + for (;;) + { + int needcolon=1; + + /* + ** + ** (3) Remove all prefix text of the subject + ** that matches the subj-leader ABNF. + ** + ** subj-leader = (*subj-blob subj-refwd) / WSP + ** + ** subj-blob = "[" *BLOBCHAR "]" *WSP + ** + ** subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":" + ** + ** BLOBCHAR = %x01-5a / %x5c / %x5e-7f + ** ; any CHAR except '[' and ']' + ** + ** THIS IS A BUG: whitespace should also be excluded from BLOBCHAR + */ + + if (isspace((int)(unsigned char)*p)) + { + ++p; + continue; + } + if (strncasecmp(p, "RE", 2) == 0) + { + q=p+2; + isrefwd=1; + } + else if (strncasecmp(p, "FWD", 3) == 0) + { + q=p+3; + isrefwd=1; + } + else if (strncasecmp(p, "FW", 2) == 0) + { + q=p+2; + isrefwd=1; + } + else if (*p == '[') + { + q=p; + needcolon=0; + } + else + break; + + if (*q == '[') + { + ++q; + + while (*q && *q != '[' && *q != ']' + && *q != ' ') + ++q; + + if (*q != ']') break; + ++q; + } + if (needcolon && *q++ != ':') break; + p=q; + } + /* + ** (4) If there is prefix text of the subject that + ** matches the subj-blob ABNF, and removing that + ** prefix leaves a non-empty subj-base, then remove + ** the prefix text. + ** + ** subj-base = NONWSP *([*WSP] NONWSP) + ** ; can be a subj-blob + */ + + + if (*p == '[') + { + for (q=p; *q; q++) + if (*q == '[' || *q == ' ' + || *q == ']') + break; + if (*q == ']') + { + ++q; + while (*q && isspace((int)(unsigned + char)*q)) + ++q; + + if (*q) + { + p=q; + if (isrefwd) + *hasrefwd=1; + continue; + } + } + } + if (isrefwd) + *hasrefwd=1; + + break; + } + /* + ** + ** (6) If the resulting text begins with the subj-fwd-hdr ABNF + ** and ends with the subj-fwd-trl ABNF, remove the + ** subj-fwd-hdr and subj-fwd-trl and repeat from step (2). + ** + ** subj-fwd-hdr = "[fwd:" + ** + ** subj-fwd-trl = "]" + */ + + if (strncasecmp(p, "[FWD:", 5) == 0) + { + q=strrchr(p, ']'); + if (q && q[1] == 0) + { + *q=0; + p += 5; + + q=s; + while ( (*q++ = *p++) != 0) + ; + + *hasrefwd=1; + continue; + } + } + break; + } + + q=s; + while ( (*q++ = *p++) != 0) + ; +} + +char *rfc822_coresubj(const char *s, int *hasrefwd) +{ + char *q=strdup(s), *r; + int dummy; + + if (!hasrefwd) + hasrefwd= &dummy; + + *hasrefwd=0; + if (!q) return (0); + + for (r=q; *r; r++) + if ((*r & 0x80) == 0) /* Just US-ASCII casing, thanks */ + *r=toupper((int)(unsigned char)*r); + stripsubj(q, hasrefwd); + return (q); +} + +char *rfc822_coresubj_nouc(const char *s, int *hasrefwd) +{ + char *q=strdup(s); + int dummy; + + if (!hasrefwd) + hasrefwd= &dummy; + + *hasrefwd=0; + if (!q) return (0); + + stripsubj(q, hasrefwd); + return (q); +} diff --git a/packages/clib/maildrop/rfc822/librfc822.a b/packages/clib/maildrop/rfc822/librfc822.a new file mode 100644 index 0000000000000000000000000000000000000000..504513aa2897794edd1ee51a6881e21a5a216e81 GIT binary patch literal 57790 zcmeHw4Sbzdndh5+&{Dx05H$+IZD}FpqohzEg#rP3;eriBXrv0AG))36v`t9vrL9sa zq|x39)w=T`j?P*~XYKkiTOGv6Af%;3gQ5mxG&<;96?PKSapP>=iL=%0|NorldGEO= z_tF-1cXoEqFE{Ud{^vQ*dCqgbKi}C)nmb$8TsiB4WU*Oz;iU@~E?&6!l8chb8gcUf zCzFdWxy*>gZg%Arm=!2}@H;`}+0m8g=7xh}k-tJG#4JKMUltM4|k z&EB-3J!>h}lv&dWW<|;7ATI;>MC-fmGJcM(tBs{<5%6NdG6mw*o0(e0LPZyZg}k`PPqJNXMLfA`mX;CCDht{#2#_uh(yTy4 zsqm`Y<9g-7WO89m%|h@0C5slpcHu=ec)+Zh^+0ObbyF%TP`x-)5nUM-Y=%Zr!`lk) zb@Eyly*_$f)R@k_lI}iOm(Fb&O6RhJ>0IMLI#=JH?oGj-8a|LZOzH!vaXx?!9N5BgJj%ia8Ux^Z5>7N%Rqo}7p^ZImmYN(<+b+}^W@23e9 zp?#m2K0P&xa`1Rck1*T;)=|_uZA!XjFzqa4I+0IzZyAg-a}eC%fx4O1 zAmVGfw-KT?Pzu0R^m`z6h!2%(TYvT{cuq0c;>wIdVxs<|WnHY2B$qbYT>h%+D_BUVo^fd&{9Hdrlln$MPhy?5(SE zj0STJRf1<*M(;H5cVuh$n(pqe0Jm-Znb}9=K`oZ&4>ga>n3$LVo53Vl7saCqS}x|F z*!CqCU#e519;J7%!O1$zE2%pO_F_^#x(I{f9{#|jw=`o z=M~k=!`)jBN7-hCTqd82^k=K|VRmzV+18)v$^Yxb#IsLJ z^_tt#m&-ninsqm7)?El_m)4?pPrtY>g%nWi5R^x#Jb1l zWMAK%8moZA<*7&S{|2<^UK2ZB0hh`2mnC|hg9H6Q?%h#h+n>S;8Fr_g5ZznGqReps z`bMYs!3l1Z^O~8OVMi|!VhGgRIG%2KA>IA6iuB%}Oh;{98N1ZO<=OP!A5TwLp!Jy2 zjlABQ8oxX>cK<%%pNuIR$9x_YgDM5`*>1AiWfkwPTxB6L6;McOY<}v|k#mj{;i;eQ z@$)h#z>9moJbSzMezn9kbFKvI;wi7ajeTe-ShRMh!Qxc{hd_PF?)8sWjC=*HktGr; zf7AVzs|xbD1nVBZJaf)u@VrvVxFq{!P$CHvJNi-KO!l=T(eoKN97r8xnv5dggHY)~ zsC3JGJj0xl53%m?>dZHsheVIm#Yvvn z_HoHePSL$(l6~~OE}=3`0o}vMTCM=3dmA(ZcpzF+L>yg#+&(5YlCU!O{QSMS0cU3u z3%JmhA(2Za_~^8qtbVAG%%yQ=$ffe5>|5j|b5&>AC&(9=<<5p(#h%3t@E zM^S@(8X1#CL(0g=M=p|+2%oP33POK62hZ%?vjT(+()vr+ zxytFy=uw&^cqnCZWy!v7iS`0{Rr)uhg}hq2wLo4i(^wq3A9)qb3wgCDw;yX;AxVzx z+Vf}QaZB8Num%I2VGMNgNQNP#`!EVSG{!8zSEgXfy;tQ@I##HI;!|T%H;i$Z^CZ%f zp6kKnyBtGwuV<$mO@rjzp%K>EF~d2T)AfC_$B})G63iOG?3t(Lz&`Op83FDGP63w8 zk^Zy1-jS_BpcUDZ;TChb!?-BPY?8e1)Dk2jG^KZ(DIuW}@nh5yJ@0Y3EDp)ZtNoln zyH;*Dfw`)=N?*~BDN^~2J}K(11A@}Uz%q!~IEHM#)Jct)YM&#y+_x}{8$SIv6B8(S zags$GyP|XtN7)CRbhl!ZTV0g+xq6htmH5@W=z!Y|x$obQ8%XD#e;fftPx2qR%d>lb z_3akX{ae9lH?q+#WTQvWtJ}FOm)gE8SHBg~qSayWV|+!Hf=na7c0(dS5z1$x=da0_ zg%0k}HGI|Y)R?%iQe%~psYug3Tq$($xb3rGBq_1&Q^wMq5#dobS;H=P7kj5=7i{(? zqL9S4dz@FMN%#0=8E}{MLH{MubBl9>M2*{#A+?V^@xsVu79K^WD8KgNAe^cbJtHxO z=uM7RZ;E^o(`TMaf)W|Md&@2~DE}e$2HvJ`Yicta;pY*^n1`02ZymOy_5?NrMGua$ zfDOha6Jb!BQZkX72ift(2up_eGR(#-NB5SYNOS`Rn!XG`-*=Au9jpKH2{iI$xEJO` zTsl%IFEA!9QXecGsR1|-M42v))IboaeuUbONcBmi`pQMBkCEzgks=YMI2b7md{~o# zK^!UMX7`SPOZf=F32O6`M(gvD2jgf&5Npq9Gf4L!y-{hhH1pL;vwN@3UPK&u&QURO z)JDRDZ>{#n#Ux@7h{qlm4?%kRvl!WFO%MyY1Y$`=IYwWT^V(z|S2`c4-lS+r6|)Ay z2m=JN#Jx-I&Tt$J2Ml^7rb*ArNK_WttFv^cXhlV4bk@$%89QBH)7758`k!7)ghpk{ zIQ-$qNe@`{m)&3vh-h`dO7jIov`<&Ud9|0 zYO2vIArWg3PL#!iy=iGQzP*jWPwuS;&VE0zuUil07L?kCnKCuys*=l7haY&1oDj&4 z2F}k6yPgCA=$iUsC>B4lx^bG*S8<(YZ$^+OtVy3nv#8#VMQan&BfaJjfjctgF6GHXbL<{C2> z=(_(_Cc@O*Zy8~Zwh>`=Rq=GQ!UZ{8_y>RP!uKMLcDY6~sPxIuEHk5S`UA3orjbeC z*XURxSH8?#x%VfMBhgU+E@cMg=R$jzq(+ zgKo?=)ekV|^sYPz=0h$DWXRDt5fSg;1K&e*YPEB~G!$;R?2BZ^$@K0mFGic*9(#E4 zeb?|^O4*A=@qyZ?I;jt4BlLcRKG3`JMUodnk82e#SewHSLQQPH!?k2i)E5&Uyjkt# zL)Z5Gmx!k}afRu02*)Nml^=N)&Jc@(Wo-)FxY>2=Yz!TA><&o>ztFLh_<7v{$B%Ot zZ$ZrAO8v84mQLQ{Lm0?ii*DrqcxPa*Y zb0!&`myDw8uf6uNWOd`}?1oG>xoE+n1q;t#loi|J`Oa>NIYnP8-g8S-v8l4+)DvdR z+=(n-1^hI1YvTIS)vvF-_We^%#C)Q-)vDVc&Y0}BT;2Wvd_sR6>h>S`40t}QZg2P9 z-qk&ovg}s3Yq7W#`rEH=7xNkL%)g48%)!9@3DN}qWMUienD2IrlVuU(1;Y{_`@6}x zHK^Nzz8l^dhjr?9lkfI!=Wn~ZZ7kvTX?5%7Gmx{t49{pm*XH$^=GAy+I^A=Py>((| z!GcWNrcAT|E4t0mg4JDJ(E>p`+a1D93T@cNuwX-brftFXH#MH$mEnrFqiS1&oeJDj z@Y|atSTG9ASH7uJ%b&c(N3k2E*czP*dx(*wW}YM5jbRwg3HULbnY6$#J!sCtkGPT% z5;GKpYj_yed2k@l*XsWg_+|L4qJ3lGpGZf~gyAoQTZoZ-sM>kzW7&ma{P`NjpS^qr zQG=gvUU{pt&GkXNn>hBo-ot#-lZNLitK*n7C#xFAz5KQ#}6Cb^v>W;%1k20~ohikbZ>9 zfsr=Dy@J1KOMw`t)+U>&5gVgoGapv=)kAX?fKqsU8Jum}$&mB<*E>$qe&MxM@mCa= zwhP$3iq|CY0we7fo;~=L3ipr7;Ew=jxLs5rjI?oh{w03IcLz8(C=mal;?lMO+pG9T zwZR{Qo#xy4m68XW-%8>?EQ7xcoZ;r)h!+@X8}a;S{D{BrO+=&ULHCeCPkcggX%pdA ziL6Py{>_e1+C#jauK0e%r7Z-0k>b~DeQkVno6>@o2%FN{HmrS5TO?bEWLukT|7sG4 zsOkD;H(zu0vZkA_yYAN1@}}iiU$ZRL6g4%qWHxtTYg!XG-J#)ZSrhNXJJvmZ+zZE@ zao$F+W8U_+-fbLP-?qN1EfaAA8pLw@r<$95+wX8Mpd2O8D@tiukY%TM#C1YuZj zvlg&C^eKWcAwI5^oZ-f2yH+hB|0fkU`d_%k*JS}H*W}R;MhdrFHhR;!f zjsG;{BbqgelaEjTCmwz>+>Fn31_ncV7CFODDuZ9>;XePnJ>2L20}uE4|JO43RCESrl!=EZ1#_KQ2;NK{Nf3FPwkk&&X|2-bgHrn+0_a4roZul8m-;fWx zEQU9DIK3MFaS!+TAMkLWf2Gz>A^)pAoL-Ipk3HN^-wUXCBCw0xtMH|ysR$hMye7b(Rr{glJSZ@U_Zk zd4R81d_{oYtN0xOo>hERfNxg3HNdwhz9zsQRD4~4_bA>G;5o%J0lq`=O#!}H^>BZH zZ&7?}fIq1CwgB%@e0zZB6n{9tcPPFyz(1_`9|!msRQ^W-{ELczJix!K_^tr|s^Xsx z@UJPpJHYoU{`mm^TgCST__K;X8sOhlyf46?SNw?p|2xI|1N{4n?+@@FDn1b4KUVy? z0DndC!2lmo{KWwOC&h;X{1=M96yU#9JRjh{QvBrr|Fz=70bZd)l7j(0UGcF1KVI=e z0e+(5;{ncX+%$*XBd$NWVl77NSF3M-pt$uf44)VHckoigN-{v{oA+$U3D=gzl}Ri3ve5E)CRbX7nTROjTbrs+{OzJ2e^$F zb_ckP7xo9ZjTbI(N04|pK+KWO5?oYsDNY&C9Q|2>-I~@^RGnz64s!v=%UOclIM(XM zwx2h-*+|)HoPm%}5x$C1fx)HRiNC_UzL~wUlv+lqpOp zyviEJnWPEk&TG}*#U7pcltUiy!&o^~yIn&xcwR_c_Am!%h8#q}AlhnGIR=&<82vg-AW#{NygK(96(ro2< za3If+{Am3zgkQ>4gP(8A|6Cu$yGAE|Uglvw>Gn_{bu|A*d$amy8|xeM-|vHXH~krW zBVNKZp@IEs0Oc=iBRP;)^-{%}Tr(FEG@G~`Z4&jNLUFsion>wkKIfqhn+jJ>42R{cm z=TKKTuaVSYcxOJYRLp;H4W|^|SO&iXIQjovnMgf|_j}6FZ&v!RYr+`)hsw}@TIv6j zW*Vt4fqkhAy&XxlgQP7{%ZALlwhd8N^L;pT8=s-JL&;_4eB&eA;zeg%3ujdQ6VUDu zwHI!QGu0&zTI*D>1V5+Sv>u@qlF&s z^SRr@efnQ}IO_nD=R{2x^7r{%=ixs6H$9xwfyU>D9`5t8xgYZP>65V2(3^S{`x5zI zz^z2mCExUa+uMMgsQlNMnZ!Yio71ar9${J}N;?ojgm7 z9i&%<4P^eP0bRCA^t5GoG0Jm*o2LDmzvGgvS7eE1kef!-Mq1YS=0J~o(*6s@qDA`b z7zfEoVa5$-Ol5C8$3(NTe=kJ2eR$;4^Y`_p_TvoB;(c2#K<6I&!e;;Ui5)Q~TbU9#Ra$(ppL>2n-C3+edX+(*mgrgcKknCv2 z3S5)+`{z}#))Iq}y2k6f)6K>TQtt$A9pbCBzlYWB!+Zw*cB|Vhf!k@Y?^m}@*3X_l zf&VWbOPn}WBc~6q`V*wwSYjp%D~#3Qv{F4`U-B%)gJ7bD5C9!b82)*{$TK8ATL0{W zQLY;Nd}IFS`XJs(OJmP+V~I>Ckn`_H=EWtj7$(|Zh*c_H2Jb1cDr zkUy4?Itm!qJc*m#`a;Y{#7&=P!cKEOe#Gw=o7PKsU#$2I8eyq-l;(FaCSkten4wR3 zN}Y%IcjH&7nEznCSqkS^pcK9hIQf4}<(ImV3=182cI&&aAw&lU?$OoOQ5YuJc)G6OP?N?GB7$Q_*YL2XkMazb`k4Lj!NtgBD?M<+-`T{;7lIDN2R+jrmWP_aH3q>2KXJ zZK_6XX)imG`QA;_)Wa_BE@k+L5$ZD;*x9!U<3y4=b`oI* zRR8QRa*e~nuc9N&JMbe(4K1FjRe|Pu7+)m~tdyvG6x+4s+M>JGi@i%Wj)#|(MsHCuSjPN5xz!8Iri{P!;kSGAEL(b~u+Q{t2b0JSXF4e7@%Kp_}1<>(R6P8U9=udXR{rvu=kHyOmqR83v7|z2Qb@ z^^4&rIPxf|Ps7c>rMKbM&!`FLjjxpxqd!gQ>H_+t+S37U>DLh8CdY~ZXFEx=O8&b# zpZYQR)&%$>wRZ%#$-ODSm#BSffY+&gdw?%h`_2HjcqSERe)H>R3&(IPZx>v2sV#NL z^GIW^OE0O_1(Ks*?-*kvpr%fqg)tX;@-j_t7v)@nlgu0=O{o~H=$F}PoI|SSwV+kBcB5w-C8wzJuj5oo1coy z2yt-&u42O$7u@UWRtXMBkh!NZh{5D|Nyo)cXXkJUp&T15E&MsAzhA}qG>>})r|K~z zMNkJZ`#ze~>+lK^x_fo5#1wj;sH4QC3I|dz)5%j8gctReQP-?Ku$yoDl2Ng*Xf?Jl(Jt-nne zGbDzi?m7YlaHj--i$aDk--xSEU%vc4rAR{YYX@bhpBhFE&F#evAUO=IF}R;LWoqi> z;tL%bxK^auTDMq@B%PiHpd=)|E&;ua`ovQS9Vg!+jCvQd1sml`7xnjf_`|dT_Q=Hp z;CUiDu8tbVN&e46Yoi>8B(q*bX_fbx@69gpCd-TZ1IH-viP>`yU1h`jcw22txPmB)khR8DTRLT5$PlXmLj)M zHfk24--i2Yaw%TgklKi;oe3ctj=e_*)9u7A3@FCd0u?O zYksMqCFjaD*7ACO=FPqql>%kt3rAo%k9}p7jBA3Da4N2z&EZBLUib6C>J?3YS0()h;q%OT#0QT zBumXpulp5+dg;L}FI|fMt8BLxTO}V`8x!6)T~AxCn+9fcBCP}85CN+FELBs z-&;RiBw2|}HS97~DkLpL0?BeV8cp2T>24_P9-n$2ZtfkPntm`fxb=+p&ls(gw|7)T z^1SHBxXqEx;GLAiLIBP#Uc^? zY;KgUNDao~jVB&j5Ao2KaG{>>f==gnZR8-=M$>?O zwnY=n!_P>51pg26BGHLPD~8`ouefk=}Akvjt3_uR&`BGG_*}j z)ZI2Q!F->Da5d*(PN)`l|6hkb{BrD%TpdMQ(K+Awz9`y-3U|++MN$9ml48B;9PqKu zCpRvSuCHGnrEbM<>GJ4WJg>#G9?yC_8}Mwv^WD+a(KXSv(b6atT^C&+rK207w_^}k zAKipy-Udut-4fl3%?XXsJEPmM8IZ&9=ty(X4EX<>{|7bjJDl5pFV*MG-&etkVkKsj z|IJPB_OTpyFRO2JYbf4p|5i?jm>XVMm#_~+v!DOW4gP5T_r7NEWu5z!xZ)prHbth~ znnC`Jj%=3>_&MK0wW9|jhG|7}7JkH?GKr|+1ToBW?h*e_#&7QBJUqxV^q*J%4FP>J zurGw2;j5UjtN9PZH~Ee5O7$Ox->-B2c{2A*(tGDC=Qu;165px{s&p-|%vUpOTKJ~F zcK~A$HTd~v7ZnaO*FEC@CXPMJtr_fB|FK7XF@J`aTQe9?|GSM)pC-S-cjKj0{CDcY z|0X3QJ0_|5xA=2jGt@o3bm;ufW?DQG%1?Wk_9WlK2~C&|btF6PjS0hN@hBC3QuF`g zaQ96ZzVGJ0lkWGqX29rie~uZcOVx5LYY8m>{#rt<@?gFrUZ?go`aD<>97i$=;;9rSfXx;;$ z6u!L-z7sgt9=@mfPTC`2pHTc4ngRF2PV+hZO7Z_v8QfMU>^oO2?z)=RwRc4u+uHD* zG^}K-=P3g`aJ1pB%$kTR6As~9`<-|4Y8dfZ-BS?Kf36Ilr6hz2>DQIPe_95=Lfa9_!=Ow*-%&i|e-;}X zm=IsCxW(%UM;2}MaPnWG_>*P$q%|Lh@*JoA4Tj4)-sG%Qob+_Vq>q?)dbqFW%>izF zws|;3`!s$uAN6qZH~LR0PK@hshJUsUJxIhb8)?+VuF*xwb~yRbSlKn)=&XG+`~*iH zCG}~z`L7OemJOO3_lUzazI6f4elAVgJ!1N#+8Y9VuG&`wxXH09z}ZiuS>qltf0M5x zz!#}~Q-Ig1eQSVQe%l`4b!y)k;7is1NPt`X`vZKL+6MxhYtb}=?h(i9R<#cW_-$&> z2RPd&nql{d`8270EWlgTJ|5tAsa+W0-SWvjiq9kfV>tV7G?f9~<>1KfCpG%4;>m!1 zqvF*8ZvC&C0JnDA?rAXoTa-^-K>vW^=>UIF@rD5JR(wT(_b9$9z&W=?vnIfE4vsnk zyjSr}0lq`=tpWZa#kU9ehZWx$;D4m}BLV&=ith^Wk0`!7z(1<^o&f)t;(Y=B=Zg0S zIQt(o0|EX?2SYZ!d4A_U^Q!B z?~K=w@lD{8-|k#kqhAa?`ZeT!iwvH1@?M8A%8Y344XtzCzoWV!`BiouPQE<%2>0fC z62119=3xR>yxOjJ0LvG#fAU&whY!>U@j$9{N8UZZq+Ft^V28Fns0--_)r^ zrv_pt()xyN53w2_#QTkEx3C_a@&FRpClu1xu`^O~m4maet<614m8Y9p(R@TK6w7s^Z4Mm38UyX$|B zzBbyaH~dkiIuWc6vqrP*OTzBpDb`=Gw*u?#8SdvXYxFtUU*ZY1F)8SjLF#PM_+!c2Pne?j{A|fz zb>Fw$;#v!2>rd|;o&xRV(|g$ zz2j2|{f4jk;|Lw3{ny})-Ajl~#lFO2sfq2>3%&>Cq&K;iT#xjnltbyuvDp03SFmk^91E+SYq09M8!5kw-wV?{RwKMK5M;Z#AK(i4gv@R#mDZ~g z+Xj&CbVYg%jW!nOxaFcim+|)0M~Zxui~j69(%5H;q# z-B|lYoDK{>hoLp>dO?(Kn);9uBO<68xPeEa>ihd+=MTG1@ExtJOF6J(A#(e*-hN~r z4UR`Yc=SivIS6JTK0_n7Z~6TGrz;kcOjl+36|GqPS7c2@7d7%J>`0=xMk%U70EnJ-xK-ZZgN#3{yUu18k8&{Owk=8?34* zaJs0N6F+yAHx3e4*M2$9XgXZtlfTh*Ec|v{oDhCmY6{E( zO+vP~U`aoTHTfKA-N*4MPj;Dx1mfrB?4xvX#vb`s2Eq!Vz(xDIx@GPAMzEvdHy}hY zPqRZ4bZ{9I`!{1!5G5E;#KEAc8Frp5I{Z?qChvRT0?n99|J3+B?sqf!ViH&Wmy+Kz z5!+I*#&tY$c@L_v@3|^$hb&Z*$d|)oL#IN0!Q>u5a`&T{4|720ZdhC?#q|apklk@2 zr@C4bJ4vHv*CDaySpog_LBD%YoOYu)?Hc(E z2DCOL80EM8SQGW>IAB}D?YB)xC;$ATv6lpu0+rr zmrZ;}he;zBQ;P2OgB9BFLG{eN^$_HglM;`eoOtYobOrtf6JLoEU+JG0C8duwLnIl+ zgEy%@=>l6=E->sv?cVZIl$nW*qa#ndUicvPIQGTyUvx~tXWv>z5npxP>SA3aw!PW) zCj@~)It zxD=PxB7q)a;PhT0THzB#8}|7+xWk27NXOKDSGZz1qmL0oftMbds}GQ@@wcYq=%Ta! z5eZ!4!Usiw9%?o>G_+}qie$=y|I@Im!%$4T0((TrK zSluq>)7jmL~@DCSR5fF1*9eDY}YJ^Vj6usz?u0%FS-k z`2q>dA6_YEgZgXm-I^Uw`+}p)^qW6*+phj@@#R#WpH{a|`aD%<{pu$DZ{w-{UQ#z% zl?&X))$JUgr~0#-9ZLDDVKoAi=Y+iR)UQx3Q#Y=(#BO+{Ue>7FErHuWODUFCT z`5;`w!?3uzMxN#T+ZQOzf6`v`xe!l=uSprZTKL;y#JyAo_QkN%e@%e5Y6Uenz)4GE z&uhGQanOI;t%CEx613dGQA&REzblBC>EGBgUxzxS+d#FWs8;_>Kl(NQEE_cCRtKwf z{ioTH#s4kd29%PWZi8=i6pyHIC&0>6GGX|~0}IohKG&SV|5#BB;va_Zs3!j>-LbC@ zmXd_>mC`Wr$*Xs+oD^_-bF1LfV;_dkhMW~ZEnhM{XqbHdj#_C8fpMmbxY?y01a>uk z{;H&8DqyVh1y{vcO#T2k`6LyWHWL`f*~I_hIK03}n~3Ko{D_~T^+7WoVYcB%{7ss$ z(%u2vsrY$JU>Ir7@caaRq`xP?zo7VMbUB@J(_mOG^oJCeb_&?vD?aT+yue7Cf#*-~ zBmaM7hJ%sz3D05th~FL1|6K7p#id;W_TLqMKesl+NZW$vZ}20Z#}$`$g#<9=Z#%bK z@96A*sa4^bNDs>kM#m?=Bv}fdR|Y??49-48DLz~kRsipP=p0A1VE}%FzE^8Jv9@ z%6XmUt4}JQe^&fIY5vJu0n=4{+}x;dO~s4&o3KfGZ6*?1hRv&^ z*0z@R*0xI)@hjNgd(+wt@a2Hj&0QdfTH5i!^ro)0>pRx9$*qv~-rC;OwqZ^4h8EoJ z=7?e|?~E)snuKi|7-rKNTtDB|+0@z|H8%xL_@=01)#V-%UYGpWAX?Vo{yAYUZ>2A* zDSQ~TrDHR`b(-zy!0zqB2TNtsgNtPFQB(OGDGAr(2Fy$+@5?t49lb?9K;xJjE|=oi z4srKsRrcI)A)ZmFHW+0F2toP4?RWu!Q&))cYp1LE@o{JF)F-nCn>O3|`1r6Eo~hiQSiKEyHNq-pnXhC5fNqv-t} zE_@vM#K!`>R_T8f;3nrZ3IY?$qkPUOgEy4H?Mr`@g)$od2MECMF%Lh({V%in__xc@ z&tl|Z7(8FwXn{Fdae8B)*!a&5=`FGWf^K;J0c0PWh7_pO1O?nI8Vv9`2WyS3KOO|D}ifa<0*) zH`Lol6gNGuN7yuf<dAJ|17d+gT z=SLpyhxDaHILrcXMaG?emu=Tl%YRO2O!2@qaR&X z24AZEV57g^v5yWaPWhAgnVzrFei-o@55LL7eLd$q+@~i`8ivcC85;)}{!MjQp-;n; z+74v`-1@&e1Kh?#pAT>w4-Evk^=DrWa2qF~D=Eh0v2jxP1xgzy)duv|FAl#zY5n4k zfZoPc;TI@vT*XBY8k5KRx#1TmZCsTP=xrQ!IKXXORYk@ge;bD_3UKR3`|UePY#g>O zpto_@_5ip3{@V4;9bMVgciU#!Bkh&F=+c^FzHxg@+dRgvj{orA+bdgxQ7!zFiM_uNS$5quv{X<*RA$t0PxzXqf)^bZTVMX0kJ}2sSnyM1u#U@NiLb3@cqj zi4Sasq@&YzswSS1^%aqKqz>7la6=jM=F#apGgGv&bM#q;@;EcsWQnSr#QoeAIE+xp zeq<|2>4$Skll^e>Fw+X#En+{TH@`|C=D`nS^mKaQV&v_Ko3=Xno>6_dV3TrG~5)~(s37f&- z-BTyZ4|n^Rbac)ipm5wtQ21;sR>)-y*!ZuH`Gd0hy4#k{k8Z&oM7J%)FS;Gi%Z_U0 z^60+C^f7jDY)uKTRruB7N5kE}zT0WAE++=FivK)+wElZpi~1-lcF#~nzA3jBwMILk z1KPLXP=K#9)iZTVa~6KYS@Zhlr662$3&TGT4&?b-{V#-HhR@c*Hx~Yzd=T#%ofs{* z7WL06|J<0;y_kP{UQ>c6Dc|JvPn=Kp-~1U?ZY`=x{dX9lK284yb1pp8Dcx#xOq5na zrXT&9e@j0OF+$zb%XSUFnHJB4^3xvbp5!$;Cbmm4H8uMxrb8gzuo^4Sv&eA8#4zrq#l{c5c|FH~yl_oXI0HbPrY)+T_nI{bYQ>72X zeLmo0W$ODLz0YU55?HvZ=E(ozs!xAOK(A9}(Uppaa<0)r8Or&J;ubE$p!p|{-Vb*Q z8Nl#yB7UZazxHrW#~40MBSL59H^blI;XZv5G&Gb)qayZjPQvo@3UMvaTmEFW>}uATU3vuYPM(#F0`tzN6t8^hloyg&hS^e>9Z(SXG%IIUEuhvk9CpwJsgq`1Gby(uD zx>}spBU$3HhFX$smj|qk6Yg~gM2ibViyaXkN+d|Sx2}PGO2P=Sfm8^EPlkw&pklps zD?rEIAL&*o9iODb4!VXFaaXePsj8%n{kTt1hBMp_IsP~uo}>oi9wyM(V+{xIc6Iv= zz4i8SSqZJ>*>v|_49rg9*aE6JFibueAmEC3NALnRjZaDUP8$>*O7HY8wqZh+{oaYo>1{$BoV!>dr z8#*h~2sU85i0Wgya2^7Ylkpag1;GD2>Zv$Abi@Ls9vJ=r#{TZYe6dPGcK0{OGBaq= zyPm9A2yS3I_V_B0hUq?rGU8rvqo7UmMm8U%SmojmssKuu@dio#WP)b}~HkVf%ih9}& zL1ATbp+IP=v1~ZR6-;nM_`MB$GDd1gNJxT{oFju}DXtvl24_%)H5Q{G zo>I#-4&>_h^PCw(AAr|EFR2PF^x!FXIS6|s)lED!B_E4M8ttq^s)orlJj%*sI8Gj_ zW|H`GjUQ9pkuweYpi-9+I5L%pF*Su5vyHwYH9wBnb#K`p$q_V!5SKNaQy@?G@kyCi zdMXL4Wj!r}oPLRYxr_cOb^dYEhWQ&=hLMm&g$yp=NS+yRmRv)X6OHw!i-)9I(I#sB zJ~s%*l^-d`(!C8y!Ez1N&aJMRIgM8XfDo46#&HB*BX`|{Tx<-_-ktXYbu|#(iaY~z z{^hLT{V_9emI^%P+5~o!8{M@ z4pZr28P*rBy2W1eBYG-Ozs*te=rY<*ziQ$dJkb0zb+wrECCefrKx0wnL{f+rp)rgAWZr2q!0+Covriin|-D1|^ z!agwkAx`bJK)igExnvZ1M`B+^&1Foc-nuH}pX^V~&+T;3w9CoKicp|Ja=637qixgx z)cY>*_^tKG^M*y*TZt|zg)7RZNPSH3p`yeAuzuE*%X0O5AO#L;G5-z5`LDRPux^rl zGJ>OLkfQ`^4HehVt~?cGv2Lwsk#zWgsMJwK+))L%L%W6AO!N^~euZG9r=g8EceO!s zoCK!i14ojaf*~jQdH-i9r=?@T(?W$%Cwcs$c%-)L^Pq%M<*Jc`?v4TEbS7sB@jXV6 zym0;!v)NnvqYO(?f9x?QGo`3_(tufd*eSDPjTgd4UnDoF^qCLK@V#vNuW4|;8ux(1 z3cknrASvy(@Z4INgbGkXna2@^*hjwR^fDZ*SRntp&a&kKIfEn>rPSW!F)sCp@QOe` z#swZ$=_vXTo+S`7+EM~pr_h0=h!q5@XR1xg?bhw1)KMDoL_WaT&fXM$!X!U(vexbJHUtL_xmfqP3f>V34iD1dXH5*CE*+O8_#6a? zAsJTzw>?T_?Wo744~+-iA?#G&4Y`4@A{@vjCz|g19}^R7B;3UuyPS3hz*I6o6_~*y z1F}lK_ck6xH)FKP;dPZx#4H!Vtg0^Ohoxlzu|Q}^oU=#vVyCJUce&^U1rn7XO!CTS>K3zwq}moEm8H!F7LB~6n27NZ51Jhs)f2PE z4Wn!rhnP!yk&up3?qUEYIdz7Esfa330Q(HtuagITHNts>`v;s?OVCWU5iBZZ3s1s! z58^k%eF~D2iEaPcWgL<7x74#JHPxp9Ih~@Km3v@RjR_}kztyBJJH;|@g>arKOyqkUP)HmIDGYM#Vj3o0FoVaGKFiZ z<64w|Y(0D-7=u#K<6#w~4MFzD=rZReSzMXol)<3dp&sN$nV_j6PXyBdXjtD@s53ay zc}$&=Ipv+sgLoh29ZmONXm1b9#vAW#8tkmJx5P)#lk7(eifVNN57uaEiyITv9@x7f z#RHk$ZcNeszTmyCA>wIXm#ul?z>O=1*~~H8!-Y)deVMNoyiLi_tmtZ(O$OR>Ng*jE z--2+$!qr0BmHq)_8B&E6{GNpQlOa|JU?3HrQagUEkFi~%i(U8u5X_`_PA~S2b8~Pp zA%E!!56RpGin@eI1^d~Yqg2O|^CU911bbfJfy}33j-Dq{fyLSXEb(yykZSKwFfDQl zQw3_`)m;*UI8q1-ou<99%)KiyTt9II^6cX?8L(@DL@>=$qvsTe(dv+Y1+oNW#CXBQ z>|%Ut2O;IDt2~v``J9!2T036ceXtS3>a<12XKqMmriGa-FSitfrqw3D~_RRdKx;49g z{pR^cxx#&PYur*|y|wBpNKs2sU>5UV;AU&w7qO%TZXKkD;m(QB?O|dt50vn?+c`xa z;4|R4U){Er@RwINt__9$4y)TAmvE~hFPPnEU_*a)K6hpbw+8h$O3#6uc0TtXOSo-U ze{c8W@CWW(ubt0*6W2S8r@Hm4zv;d|kTH#TmWAea{xg4grQ5i={e|!E_U@^t!OhO+ za%$7}N9(_rJqq7?qr@iur%OYz{Zzb#7#&y4aU?^!R?T%hs*rUQ4RuSywLapyL`6tU zWw<#&@i46OfRpEI^}i5)89uY9Z!CNnWqA&y^$p84u^J!5ds5|}8{p>Op4Y(L-hI-g zW#S*wmfNF{R{wTR+<2S*&0cno0;)zDe~$_Mntw~blYoV~r@u`~&`gVGLiuSAbx(4B z$&IE~6P)Xo3@Z%(cwnW%Uy+0Z%&&p~1FIt{@t<_R&pir^kG~f|+74h;8}TKo6siA# z%~AXls*kN2k#iM4L(7@e-@qYOg~A;V415E56Po1>r#IL zW4uWgYoNY1f29A)pU`z7uY}<`fr!Pzgq_XA#n1q()5+~8`z;T^t=b4l$^XLhkOQDFkqzZ z#dB^M`U}h8b!G7SGC23$my)Ns49;;by>Th~j^7qQH@~ z|9Jf?#s5k7R7u+p{BISXsrggdcHln*UP{ha%HX5QXS%k7($-UicvAxQ%4}@zSl@M5 zYjdVKTGQOM2Jg6=`p&f*T4m$Qy0shb!54ViHe{mJoo&tb-inPeceVh)0axssX@ak= zsI@(_22g8Pd#9YMdi<*Fllol-#a-OnDjJ1au4bIFpJq< zmcKB8gqX47o+R&Rzl^EFL~^M0^WxSb~n>1}UOi1&MZ*yfl#&w02XuYd7y zKVGM6<4gW;@%U7GxXR7fr&= z^mBzrKik7wJlxm+I>kfz@Ac^Cczho8@H0Jphll&&eyI%qr#yN;Uf=a_KfMlmc+v}Z zsicqr$)St-B}_xYT_!Vg3I z9Q;iF(>>g;Prl;e=X&(#Ykz}$I7T);i#>dvhi5(fY!Ck<53ly{PkH!!4^QHqhI-)7 z%o2Sud{FHx0^Iu3nEiy_-} +#include +#include +#include + +#include "rfc822.h" +#include "imaprefs.h" + + +static void test1() +{ +struct imap_refmsgtable *mt=rfc822_threadalloc(); +char buf[20]; +struct imap_refmsg *p; + + strcpy(buf, "a@b"); + p=rfc822_threadallocmsg(mt, buf); + strcpy(buf, "c@d"); + p=rfc822_threadallocmsg(mt, buf); + + printf("%s\n", (rfc822_threadsearchmsg(mt, "a@b") + ? "found":"not found")); + printf("%s\n", (rfc822_threadsearchmsg(mt, "c@d") + ? "found":"not found")); + printf("%s\n", (rfc822_threadsearchmsg(mt, "e@f") + ? "found":"not found")); + + rfc822_threadfree(mt); +} + +static void prtree(struct imap_refmsg *m) +{ + printf("<%s>", m->msgid ? m->msgid:""); + + if (m->isdummy) + { + printf(" (dummy)"); + } + + printf(".parent="); + if (m->parent) + printf("<%s>", m->parent->msgid ? m->parent->msgid:""); + else + printf("ROOT"); + + printf("\n"); + + for (m=m->firstchild; m; m=m->nextsib) + prtree(m); +} + +static void prpc(struct imap_refmsgtable *mt) +{ + struct imap_refmsg *root=rfc822_threadgetroot(mt), *m; + + if (!root) + return; + + for (m=root->firstchild; m; m=m->nextsib) + prtree(m); + + printf("\n\n"); +} + +static void test2() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "<1>", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<2>", + "<1>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<4>", + "<1> <2> <3>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + prpc(mt); + rfc822_threadfree(mt); +} + +static void test3() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "<4>", + "<2> <1> <3>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<3>", + "<1> <2>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<2>", + "<1>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<1>", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + prpc(mt); + rfc822_threadfree(mt); +} + +static void test4() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "<1>", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<2>", "<1>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<4>", "<1> <2> <3>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + prpc(mt); + rfc822_threadprune(mt); + prpc(mt); + rfc822_threadfree(mt); +} + +static void test5() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "<4>", "<1> <2> <3>", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "<3>", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + prpc(mt); + rfc822_threadprune(mt); + prpc(mt); + rfc822_threadfree(mt); +} + +static void prsubj(struct imap_refmsgtable *p) +{ + struct imap_subjlookup *s; + int i; + + for (i=0; isubjtable)/sizeof(p->subjtable[0]); i++) + for (s=p->subjtable[i]; s; s=s->nextsubj) + printf("subject(%s)=<%s>\n", s->subj, + s->msg->msgid ? s->msg->msgid:""); + printf("\n\n"); +} + +static void test6() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 2", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", "", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "Re: subject 4", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 4", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 5", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "re: subject 5", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadprune(mt); + rfc822_threadsortsubj(mt, rfc822_threadgetroot(mt)); + prpc(mt); + prsubj(mt); + rfc822_threadfree(mt); +} + +static void test7() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "", "", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", "", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + rfc822_threadprune(mt); + rfc822_threadsortsubj(mt, rfc822_threadgetroot(mt)); + prpc(mt); + prsubj(mt); + rfc822_threadmergesubj(mt, rfc822_threadgetroot(mt)); + prpc(mt); + rfc822_threadfree(mt); +} + +static void test8() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "", NULL, + "subject 2", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", "", + "subject 1", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "Re: subject 2", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 10", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 10", + "Thu, 29 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadprune(mt); + rfc822_threadsortsubj(mt, rfc822_threadgetroot(mt)); + prpc(mt); + prsubj(mt); + rfc822_threadmergesubj(mt, rfc822_threadgetroot(mt)); + prpc(mt); + rfc822_threadfree(mt); +} + +static void test9() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 20 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 19 Jun 2000 14:41:58 -0700", 2); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 21 Jun 2000 14:41:58 -0700", 3); + + rfc822_threadmsg(mt, "", "", + "subject 2", + "Thu, 21 Jun 2000 14:41:58 -0700", 6); + + rfc822_threadmsg(mt, "", "", + "subject 2", + "Thu, 21 Jun 2000 14:41:58 -0700", 5); + + rfc822_threadmsg(mt, "", "", + "subject 2", + "Thu, 20 Jun 2000 14:41:58 -0700", 4); + + + rfc822_threadprune(mt); + rfc822_threadsortsubj(mt, rfc822_threadgetroot(mt)); + rfc822_threadmergesubj(mt, rfc822_threadgetroot(mt)); + rfc822_threadsortbydate(mt); + prpc(mt); + rfc822_threadfree(mt); +} + +static void test10() +{ + struct imap_refmsgtable *mt=rfc822_threadalloc(); + + rfc822_threadmsg(mt, "", NULL, + "subject 1", + "Thu, 20 Jun 2000 14:41:58 -0700", 1); + + rfc822_threadmsg(mt, "", "", + "subject 2", + "Thu, 21 Jun 2000 14:41:58 -0700", 6); + + rfc822_threadmsg(mt, "", NULL, + "subject 2", + "Thu, 21 Jun 2000 14:41:58 -0700", 5); + + rfc822_threadmsg(mt, "", "", + "subject 2", + "Thu, 21 Jun 2000 14:41:58 -0700", 6); + + rfc822_threadprune(mt); + rfc822_threadsortsubj(mt, rfc822_threadgetroot(mt)); + rfc822_threadmergesubj(mt, rfc822_threadgetroot(mt)); + rfc822_threadsortbydate(mt); + prpc(mt); + rfc822_threadfree(mt); +} + +int main(int argc, char **argv) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + test10(); + return (0); +} diff --git a/packages/clib/maildrop/rfc822/reftest.txt b/packages/clib/maildrop/rfc822/reftest.txt new file mode 100644 index 000000000..5f7a13757 --- /dev/null +++ b/packages/clib/maildrop/rfc822/reftest.txt @@ -0,0 +1,106 @@ +found +found +not found +<1>.parent=<(root)> +<2>.parent=<1> +<3> (dummy).parent=<2> +<4>.parent=<3> + + +<2>.parent=<(root)> +<3>.parent=<2> +<4>.parent=<3> +<1>.parent=<(root)> + + +<1>.parent=<(root)> +<2>.parent=<1> +<3> (dummy).parent=<2> +<4>.parent=<3> + + +<1>.parent=<(root)> +<2>.parent=<1> +<4>.parent=<2> + + +<1> (dummy).parent=<(root)> +<2> (dummy).parent=<1> +<3>.parent=<(root)> +<4>.parent=<3> + + +<3>.parent=<(root)> +<4>.parent=<3> + + +.parent=<(root)> +.parent=<(root)> + (dummy).parent=<(root)> +.parent= +.parent=<(root)> +.parent=<(root)> +.parent=<(root)> +.parent=<(root)> + + +subject(SUBJECT 1)= +subject(SUBJECT 2)= +subject(SUBJECT 5)= +subject(SUBJECT 4)= + + + (dummy).parent=<(root)> +.parent= + (dummy).parent=<(root)> +.parent= + + +subject(SUBJECT 1)= + + + (dummy).parent=<(root)> +.parent= +.parent= + + +.parent=<(root)> +.parent=<(root)> + (dummy).parent=<(root)> +.parent= +.parent=<(root)> +.parent=<(root)> +.parent=<(root)> + + +subject(SUBJECT 10)= +subject(SUBJECT 1)= +subject(SUBJECT 2)= + + +.parent=<(root)> +.parent= + (dummy).parent=<(root)> +.parent= +.parent= +<(dummy)> (dummy).parent=<(root)> +.parent=<(dummy)> +.parent=<(dummy)> + + +<(dummy)> (dummy).parent=<(root)> +.parent=<(dummy)> +.parent= +.parent= +.parent= +.parent=<(dummy)> +.parent=<(dummy)> + + +.parent=<(root)> +<>.parent= +<(dummy)> (dummy).parent=<(root)> +<>.parent=<(dummy)> +.parent=<(dummy)> + + diff --git a/packages/clib/maildrop/rfc822/rfc2047.c b/packages/clib/maildrop/rfc822/rfc2047.c new file mode 100644 index 000000000..3d4016234 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc2047.c @@ -0,0 +1,541 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + + +#include +#include +#include +#include + +#include "rfc822.h" +#include "rfc2047.h" + +static const char rcsid[]="$Id$"; + +static const char xdigit[]="0123456789ABCDEF"; + +static char *rfc2047_search_quote(const char **ptr) +{ +const char *p= *ptr; +char *s; + + while (**ptr && **ptr != '?') + ++ *ptr; + if ((s=malloc( *ptr - p + 1)) == 0) + return (0); + memcpy(s, p, *ptr-p); + s[*ptr - p]=0; + return (s); +} + +static int nyb(int c) +{ +const char *p; + + c=toupper( (int)(unsigned char)c ); + p=strchr(xdigit, c); + return (p ? p-xdigit:0); +} + +static unsigned char decode64tab[256]; +static int decode64tab_init=0; + +static size_t decodebase64(char *ptr, size_t cnt) +{ +size_t i, j; +char a,b,c; +size_t k; + + if (!decode64tab_init) + { + for (i=0; i<256; i++) decode64tab[i]=0; + for (i=0; i<64; i++) + decode64tab[ (int) + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i])]=i; + decode64tab[ (int)'=' ] = 99; + } + + i=cnt / 4; + i=i*4; + k=0; + for (j=0; j> 4); + b= (x << 4) | (y >> 2); + c= (y << 6) | z; + ptr[k++]=a; + if ( ptr[j+2] != '=') + ptr[k++]=b; + if ( ptr[j+3] != '=') + ptr[k++]=c; + } + return (k); +} + +/* +** This is the main rfc2047 decoding function. It receives rfc2047-encoded +** text, and a callback function. The callback function is repeatedly +** called, each time receiving a piece of decoded text. The decoded +** info includes a text fragment - string, string length arg - followed +** by the character set, followed by a context pointer that is received +** from the caller. If the callback function returns non-zero, rfc2047 +** decoding terminates, returning the result code. Otherwise, +** rfc2047_decode returns 0 after a successfull decoding (-1 if malloc +** failed). +*/ + +int rfc2047_decode(const char *text, int (*func)(const char *, int, + const char *, void *), + void *arg) +{ +int rc; +int had_last_word=0; +const char *p; +char *chset; +char *encoding; +char *enctext; + + while (text && *text) + { + if (text[0] != '=' || text[1] != '?') + { + p=text; + while (*text) + { + if (text[0] == '=' && text[1] == '?') + break; + if (!isspace((int)(unsigned char)*text)) + had_last_word=0; + ++text; + } + if (text > p && !had_last_word) + { + rc=(*func)(p, text-p, 0, arg); + if (rc) return (rc); + } + continue; + } + + text += 2; + if ((chset=rfc2047_search_quote( &text )) == 0) + return (-1); + if (*text) ++text; + if ((encoding=rfc2047_search_quote( &text )) == 0) + { + free(chset); + return (-1); + } + if (*text) ++text; + if ((enctext=rfc2047_search_quote( &text )) == 0) + { + free(encoding); + free(chset); + return (-1); + } + if (*text == '?' && text[1] == '=') + text += 2; + if (strcmp(encoding, "Q") == 0 || strcmp(encoding, "q") == 0) + { + char *q, *r; + + for (q=r=enctext; *q; ) + { + int c; + + if (*q == '=' && q[1] && q[2]) + { + *r++ = (char)( + nyb(q[1])*16+nyb(q[2])); + q += 3; + continue; + } + + c=*q++; + if (c == '_') + c=' '; + *r++ = c ; + } + *r=0; + } + else if (strcmp(encoding, "B") == 0 || strcmp(encoding, "b")==0) + { + enctext[decodebase64(enctext, strlen(enctext))]=0; + } + rc=(*func)(enctext, strlen(enctext), chset, arg); + free(enctext); + free(chset); + free(encoding); + if (rc) return (rc); + + had_last_word=1; /* Ignore blanks between enc words */ + } + return (0); +} + +/* +** rfc2047_decode_simple just strips out the rfc2047 decoding, throwing away +** the character set. This is done by calling rfc2047_decode twice, once +** to count the number of characters in the decoded text, the second time to +** actually do it. +*/ + +struct simple_info { + char *string; + int index; + const char *mychset; + } ; + +static int count_simple(const char *txt, int len, const char *chset, + void *arg) +{ +struct simple_info *iarg= (struct simple_info *)arg; + + iarg->index += len; + + return (0); +} + +static int save_simple(const char *txt, int len, const char *chset, + void *arg) +{ +struct simple_info *iarg= (struct simple_info *)arg; + + memcpy(iarg->string+iarg->index, txt, len); + iarg->index += len; + return (0); +} + +char *rfc2047_decode_simple(const char *text) +{ +struct simple_info info; + + info.index=1; + if (rfc2047_decode(text, &count_simple, &info)) + return (0); + + if ((info.string=malloc(info.index)) == 0) return (0); + info.index=0; + if (rfc2047_decode(text, &save_simple, &info)) + { + free(info.string); + return (0); + } + info.string[info.index]=0; + return (info.string); +} + +/* +** rfc2047_decode_enhanced is like simply, but prefixes the character set +** name before the text, in brackets. +*/ + +static int do_enhanced(const char *txt, int len, const char *chset, + void *arg, + int (*func)(const char *, int, const char *, void *) + ) +{ +int rc=0; +struct simple_info *info=(struct simple_info *)arg; + + if (chset && info->mychset && strcmp(chset, info->mychset) == 0) + chset=0; + + if (chset) + { + rc= (*func)(" [", 2, 0, arg); + if (rc == 0) + rc= (*func)(chset, strlen(chset), 0, arg); + if (rc == 0) + rc= (*func)("] ", 2, 0, arg); + } + + if (rc == 0) + rc= (*func)(txt, len, 0, arg); + return (rc); +} + +static int count_enhanced(const char *txt, int len, const char *chset, + void *arg) +{ + return (do_enhanced(txt, len, chset, arg, &count_simple)); +} + +static int save_enhanced(const char *txt, int len, const char *chset, + void *arg) +{ + return (do_enhanced(txt, len, chset, arg, &save_simple)); +} + +char *rfc2047_decode_enhanced(const char *text, const char *mychset) +{ +struct simple_info info; + + info.mychset=mychset; + info.index=1; + if (rfc2047_decode(text, &count_enhanced, &info)) + return (0); + + if ((info.string=malloc(info.index)) == 0) return (0); + info.index=0; + if (rfc2047_decode(text, &save_enhanced, &info)) + { + free(info.string); + return (0); + } + info.string[info.index]=0; + return (info.string); +} + +void rfc2047_print(const struct rfc822a *a, + const char *charset, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *ptr) +{ + rfc822_print_common(a, &rfc2047_decode_enhanced, charset, + print_func, print_separator, ptr); +} + +static char *a_rfc2047_encode_str(const char *str, const char *charset); + +static void rfc2047_encode_header_do(const struct rfc822a *a, + const char *charset, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *ptr) +{ + rfc822_print_common(a, &a_rfc2047_encode_str, charset, + print_func, print_separator, ptr); +} + +/* +** When MIMEifying names from an RFC822 list of addresses, strip quotes +** before MIMEifying them, and add them afterwards. +*/ + +static char *a_rfc2047_encode_str(const char *str, const char *charset) +{ +size_t l=strlen(str); +char *p, *s; + + if (*str != '"' || str[l-1] != '"') + return (rfc2047_encode_str(str, charset)); + + p=malloc(l); + if (!p) return (0); + memcpy(p, str+1, l-2); + p[l-2]=0; + s=rfc2047_encode_str(p, charset); + free(p); + if (!s) return (0); + p=malloc(strlen(s)+3); + if (!p) + { + free(s); + return (0); + } + p[0]='"'; + strcpy(p+1, s); + strcat(p, "\""); + free(s); + return (p); +} + + + + +static void count(char c, void *p); +static void counts(const char *c, void *p); +static void save(char c, void *p); +static void saves(const char *c, void *p); + +char *rfc2047_encode_header(const struct rfc822a *a, + const char *charset) +{ +size_t l; +char *s, *p; + + l=1; + rfc2047_encode_header_do(a, charset, &count, &counts, &l); + if ((s=malloc(l)) == 0) return (0); + p=s; + rfc2047_encode_header_do(a, charset, &save, &saves, &p); + *p=0; + return (s); +} + +static void count(char c, void *p) +{ + ++*(size_t *)p; +} + +static void counts(const char *c, void *p) +{ + while (*c) count(*c++, p); +} + +static void save(char c, void *p) +{ + **(char **)p=c; + ++*(char **)p; +} + +static void saves(const char *c, void *p) +{ + while (*c) save(*c++, p); +} + +int rfc2047_encode_callback(const char *str, const char *charset, + int (*func)(const char *, size_t, void *), void *arg) +{ +int rc; + + while (*str) + { + size_t i, c; + + for (i=0; str[i]; i++) + if ((str[i] & 0x80) || str[i] == '"') + break; + if (str[i] == 0) + return ( i ? (*func)(str, i, arg):0); + + /* Find start of word */ + + while (i) + { + --i; + if (isspace((int)(unsigned char)str[i])) + { + ++i; + break; + } + } + if (i) + { + rc= (*func)(str, i, arg); + if (rc) return (rc); + str += i; + } + + /* + ** Figure out when to stop MIME decoding. Consecutive + ** MIME-encoded words are MIME-encoded together. + */ + + i=0; + + for (;;) + { + for ( ; str[i]; i++) + if (isspace((int)(unsigned char)str[i])) + break; + if (str[i] == 0) + break; + + for (c=i; str[c] && isspace((int)(unsigned char)str[c]); + ++c) + ; + + for (; str[c]; c++) + if (isspace((int)(unsigned char)str[c]) || + (str[c] & 0x80) || str[c] == '"') + break; + + if (str[c] == 0 || isspace((int)(unsigned char)str[c])) + break; + i=c; + } + + /* Output mimeified text, insert spaces at 70+ character + ** boundaries for line wrapping. + */ + + c=0; + while (i) + { + if (c == 0) + { + if ( (rc=(*func)("=?", 2, arg)) != 0 || + (rc=(*func)(charset, strlen(charset), + arg)) != 0 || + (rc=(*func)("?Q?", 3, arg)) != 0) + return (rc); + c += strlen(charset)+5; + } + + if ((*str & 0x80) || *str == '"') + { + char buf[3]; + + buf[0]='='; + buf[1]=xdigit[ ( *str >> 4) & 0x0F ]; + buf[2]=xdigit[ *str & 0x0F ]; + + if ( (rc=(*func)(buf, 3, arg)) != 0) + return (rc); + c += 3; + ++str; + --i; + } + else + { + size_t j; + + for (j=0; j < i && !(str[j] & 0x80) && + str[j] != '"'; j++) + if (j + c >= 70) + break; + if ( (rc=(*func)(str, j, arg)) != 0) + return (rc); + c += j; + str += j; + i -= j; + } + + if (i == 0 || c >= 70) + { + if ( (rc=(*func)("?= ", i ? 3:2, arg)) != 0) + return (rc); + + c=0; + } + } + } + return (0); +} + +static int count_char(const char *c, size_t l, void *p) +{ +size_t *i=(size_t *)p; + + *i += l; + return (0); +} + +static int save_char(const char *c, size_t l, void *p) +{ +char **s=(char **)p; + + memcpy(*s, c, l); + *s += l; + return (0); +} + +char *rfc2047_encode_str(const char *str, const char *charset) +{ +size_t i=1; +char *s, *p; + + (void)rfc2047_encode_callback(str, charset, &count_char, &i); + if ((s=malloc(i)) == 0) return (0); + p=s; + (void)rfc2047_encode_callback(str, charset, &save_char, &p); + *p=0; + return (s); +} diff --git a/packages/clib/maildrop/rfc822/rfc2047.h b/packages/clib/maildrop/rfc822/rfc2047.h new file mode 100644 index 000000000..a3a25c148 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc2047.h @@ -0,0 +1,83 @@ +#ifndef rfc2047_h +#define rfc2047_h + +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +static const char rfc2047_h_rcsid[]="$Id$"; + +extern int rfc2047_decode(const char *text, + int (*func)(const char *, int, const char *, void *), + void *arg); + +extern char *rfc2047_decode_simple(const char *text); + +extern char *rfc2047_decode_enhanced(const char *text, const char *mychset); + +/* +** If libunicode.a is available, like rfc2047_decode_enhanced, but attempt to +** convert to my preferred charset. +*/ + +struct unicode_info; + +extern char *rfc2047_decode_unicode(const char *text, + const struct unicode_info *mychset, + int options); + +#define RFC2047_DECODE_DISCARD 1 + /* options: Discard unknown charsets from decoded string. */ +#define RFC2047_DECODE_ABORT 2 + /* options: Abort if we encounter an unknown charset, errno=EINVAL */ + + + + +/* +** rfc2047_print is like rfc822_print, except that it converts RFC 2047 +** MIME encoding to 8 bit text. +*/ + +struct rfc822a; + +void rfc2047_print(const struct rfc822a *a, + const char *charset, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *); + +/* +** And now, let's encode something with RFC 2047. Encode the following +** string in the indicated character set, into a malloced buffer. Returns 0 +** if malloc failed. +*/ + +char *rfc2047_encode_str(const char *str, const char *charset); + +/* +** If you can live with the encoded text being generated on the fly, use +** rfc2047_encode_callback, which calls a callback function, instead of +** dynamically allocating memory. +*/ + +int rfc2047_encode_callback(const char *str, const char *charset, + int (*func)(const char *, size_t, void *), void *arg); + +/* +** rfc2047_encode_header allocates a buffer, and MIME-encodes an RFC822 header +** +*/ +char *rfc2047_encode_header(const struct rfc822a *a, + const char *charset); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packages/clib/maildrop/rfc822/rfc2047u.c b/packages/clib/maildrop/rfc822/rfc2047u.c new file mode 100644 index 000000000..40e64fde0 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc2047u.c @@ -0,0 +1,109 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + + +#include +#include +#include +#include +#include + +#include "rfc822.h" +#include "rfc2047.h" + +static const char rcsid[]="$Id$"; + +#if HAVE_LIBUNICODE + +#include "../unicode/unicode.h" + +struct decode_unicode_s { + const struct unicode_info *mychset; + int options; + + char *bufptr; + size_t bufsize; +} ; + +static void save_unicode_text(const char *p, int l, struct decode_unicode_s *s) +{ + if (s->bufptr) + memcpy(s->bufptr+s->bufsize, p, l); + + s->bufsize += l; +} + +static int save_unicode(const char *txt, int len, const char *chset, + void *arg) +{ + struct decode_unicode_s *p=(struct decode_unicode_s *)arg; + char *txts=malloc(len+1); + char *s; + + if (!txts) + return (-1); + memcpy(txts, txt, len); + txts[len]=0; + + if (!chset) + chset=unicode_ISO8859_1.chset; + + s=unicode_convert_fromchset(txts, chset, p->mychset); + free(txts); + if (s) + { + save_unicode_text(s, strlen(s), p); + free(s); + return (0); + } + + if (p->options & RFC2047_DECODE_ABORT) + { + errno=EINVAL; + return (-1); + } + + if (p->options & RFC2047_DECODE_DISCARD) + return (0); + + save_unicode_text(" [", 2, p); + save_unicode_text(chset, strlen(chset), p); + save_unicode_text("] ", 2, p); + save_unicode_text(txt, len, p); + return (0); +} + +char *rfc2047_decode_unicode(const char *text, + const struct unicode_info *mychset, + int options) +{ + struct decode_unicode_s s; + char *p=0; + + s.mychset=mychset; + s.options=0; + + s.bufptr=0; + s.bufsize=1; + + + if (rfc2047_decode(text, &save_unicode, &s)) + return (0); + + s.bufptr=p=malloc(s.bufsize); + if (!s.bufptr) + return (0); + + s.bufsize=0; + if (rfc2047_decode(text, &save_unicode, &s)) + { + free(p); + return (0); + } + save_unicode_text("", 1, (void *)&s); + return (p); +} + +#endif diff --git a/packages/clib/maildrop/rfc822/rfc822.c b/packages/clib/maildrop/rfc822/rfc822.c new file mode 100644 index 000000000..0e48186c8 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822.c @@ -0,0 +1,721 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ +#include +#include +#include +#include +#include "rfc822.h" + +static void tokenize(const char *p, struct rfc822token *tokp, int *toklen, + void (*err_func)(const char *, int)) +{ +const char *addr=p; +int i=0; +int inbracket=0; + + *toklen=0; + while (*p) + { + if (isspace((int)(unsigned char)*p)) + { + p++; + i++; + continue; + } + + switch (*p) { + int level; + + case '(': + if (tokp) + { + tokp->token='('; + tokp->ptr=p; + tokp->len=0; + } + level=0; + for (;;) + { + if (!*p) + { + if (err_func) (*err_func)(addr, i); + if (tokp) tokp->token='"'; + ++*toklen; + return; + } + if (*p == '(') + ++level; + if (*p == ')' && --level == 0) + { + p++; + i++; + if (tokp) tokp->len++; + break; + } + if (*p == '\\' && p[1]) + { + p++; + i++; + if (tokp) tokp->len++; + } + + i++; + if (tokp) tokp->len++; + p++; + } + if (tokp) ++tokp; + ++*toklen; + continue; + + case '"': + p++; + i++; + + if (tokp) + { + tokp->token='"'; + tokp->ptr=p; + } + while (*p != '"') + { + if (!*p) + { + if (err_func) (*err_func)(addr, i); + ++*toklen; + return; + } + if (*p == '\\' && p[1]) + { + if (tokp) tokp->len++; + p++; + i++; + } + if (tokp) tokp->len++; + p++; + i++; + } + ++*toklen; + if (tokp) ++tokp; + p++; + i++; + continue; + case '\\': + case ')': + if (err_func) (*err_func)(addr, i); + ++p; + ++i; + continue; + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '.': + case '[': + case ']': + case '%': + case '!': + case '?': + case '=': + case '/': + + if ( (*p == '<' && inbracket) || + (*p == '>' && !inbracket)) + { + if (err_func) (*err_func)(addr, i); + ++p; + ++i; + continue; + } + + if (*p == '<') + inbracket=1; + + if (*p == '>') + inbracket=0; + + if (tokp) + { + tokp->token= *p; + tokp->ptr=p; + tokp->len=1; + ++tokp; + } + ++*toklen; + + if (*p == '<' && p[1] == '>') + /* Fake a null address */ + { + if (tokp) + { + tokp->token=0; + tokp->ptr=""; + tokp->len=0; + ++tokp; + } + ++*toklen; + } + ++p; + ++i; + continue; + default: + + if (tokp) + { + tokp->token=0; + tokp->ptr=p; + tokp->len=0; + } + while (*p && !isspace((int)(unsigned char)*p) && strchr( + "<>@,;:.[]()%!\"\\?=/", *p) == 0) + { + if (tokp) ++tokp->len; + ++p; + ++i; + } + if (i == 0) /* Idiot check */ + { + if (err_func) (*err_func)(addr, i); + if (tokp) + { + tokp->token='"'; + tokp->ptr=p; + tokp->len=1; + ++tokp; + } + ++*toklen; + ++p; + ++i; + continue; + } + if (tokp) ++tokp; + ++*toklen; + } + } +} + +static void parseaddr(struct rfc822token *tokens, int ntokens, + struct rfc822addr *addrs, int *naddrs) +{ +int flag, j, k; +struct rfc822token save_token; + + *naddrs=0; + + while (ntokens) + { + int i; + + /* atoms (token=0) or quoted strings, followed by a : token + is a list name. */ + + for (i=0; itokens=0; + addrs->name=i ? tokens:0; + for (j=1; jname[j-1].next=addrs->name+j; + if (i) + addrs->name[i-1].next=0; + addrs++; + } + ++*naddrs; + tokens += i; + ntokens -= i; + continue; /* Group=phrase ":" */ + } + + /* Spurious commas are skipped, ;s are recorded */ + + if (tokens->token == ',' || tokens->token == ';') + { + if (tokens->token == ';') + { + if (addrs) + { + addrs->tokens=0; + addrs->name=tokens; + addrs->name->next=0; + addrs++; + } + ++*naddrs; + } + ++tokens; + --ntokens; + continue; + } + + /* If we can find a '<' before the next comma or semicolon, + we have new style RFC path address */ + + for (i=0; i'??? + If it consists exclusively of atoms, leave them alone. + Else, make them all a quoted string. */ + + for (j=0; jname= i ? tokens:0; + for (k=1; kname[k-1].next=addrs->name+k; + if (i) + addrs->name[i-1].next=0; + } + } + else /* Intentionally corrupt the original toks */ + { + if (addrs) + { + tokens->len= tokens[i-1].ptr + + tokens[i-1].len + - tokens->ptr; + /* We know that all the ptrs point + to parts of the same string. */ + tokens->token='"'; + /* Quoted string. */ + addrs->name=tokens; + addrs->name->next=0; + } + } + + /* Any comments in the name part are changed to quotes */ + + if (addrs) + { + struct rfc822token *t; + + for (t=addrs->name; t; t=t->next) + if (t->token == '(') + t->token='"'; + } + + /* Now that's done and over with, see what can + be done with the <...> part. */ + + ++i; + tokens += i; + ntokens -= i; + for (i=0; itokens=i ? tokens:0; + for (k=1; ktokens[k-1].next=addrs->tokens+k; + if (i) + addrs->tokens[i-1].next=0; + ++addrs; + } + ++*naddrs; + tokens += i; + ntokens -= i; + if (ntokens) /* Skip the '>' token */ + { + --ntokens; + ++tokens; + } + continue; + } + + /* Ok - old style address. Assume the worst */ + + /* Try to figure out where the address ends. It ends upon: + a comma, semicolon, or two consecutive atoms. */ + + flag=0; + for (i=0; iname=0; + } + + /* Ok, now get rid of embedded comments in the address. + Consider the last comment to be the real name */ + + if (addrs) + { + + save_token.ptr=0; + save_token.len=0; + + for (j=k=0; jname=tokens+i-1; + addrs->name->next=0; + } + addrs->tokens=k ? tokens:NULL; + for (j=1; jtokens[j-1].next=addrs->tokens+j; + if (k) + addrs->tokens[k-1].next=0; + ++addrs; + } + ++*naddrs; + tokens += i; + ntokens -= i; + } +} + +static void print_token(const struct rfc822token *token, + void (*print_func)(char, void *), void *ptr) +{ +const char *p; +int n; + + if (token->token == 0 || token->token == '(') + { + for (n=token->len, p=token->ptr; n; --n, ++p) + (*print_func)(*p, ptr); + return; + } + + if (token->token != '"') + { + (*print_func)(token->token, ptr); + return; + } + + (*print_func)('"', ptr); + n=token->len; + p=token->ptr; + while (n) + { + if (*p == '"' || (*p == '\\' && n == 1)) (*print_func)('\\', ptr); + if (*p == '\\' && n > 1) + { + (*print_func)('\\', ptr); + ++p; + --n; + } + (*print_func)(*p++, ptr); + --n; + } + (*print_func)('"', ptr); +} + +void rfc822tok_print(const struct rfc822token *token, + void (*print_func)(char, void *), void *ptr) +{ +int prev_isatom=0; +int isatom; + + while (token) + { + isatom=rfc822_is_atom(token->token); + if (prev_isatom && isatom) + (*print_func)(' ', ptr); + print_token(token, print_func, ptr); + prev_isatom=isatom; + token=token->next; + } +} + +void rfc822_print(const struct rfc822a *rfcp, void (*print_func)(char, void *), + void (*print_separator)(const char *s, void *), void *ptr) +{ + rfc822_print_common(rfcp, 0, 0, print_func, print_separator, ptr); +} + +void rfc822_print_common(const struct rfc822a *rfcp, + char *(*decode_func)(const char *, const char *), const char *chset, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *ptr) +{ +const struct rfc822addr *addrs=rfcp->addrs; +int naddrs=rfcp->naddrs; + + while (naddrs) + { + if (addrs->tokens == 0) + { + rfc822tok_print(addrs->name, print_func, ptr); + ++addrs; + --naddrs; + if (addrs[-1].name && naddrs) + { + struct rfc822token *t; + + for (t=addrs[-1].name; t && t->next; t=t->next) + ; + + if (t && (t->token == ':' || t->token == ';')) + (*print_separator)(" ", ptr); + } + continue; + } + else if (addrs->name && addrs->name->token == '(') + { /* old style */ + char *p; + + rfc822tok_print(addrs->tokens, print_func, ptr); + (*print_func)(' ', ptr); + + if (decode_func && (p=rfc822_gettok(addrs->name))!=0) + { + char *q= (*decode_func)(p, chset); + char *r; + + for (r=q; r && *r; r++) + (*print_func)( (int)(unsigned char)*r, + ptr); + if (q) free(q); + free(p); + } + else rfc822tok_print(addrs->name, print_func, ptr); + } + else + { + int print_braces=0; + char *p; + + if (addrs->name) + { + if (decode_func && + (p=rfc822_gettok(addrs->name)) != 0) + { + char *q= (*decode_func)(p, chset); + char *r; + + for (r=q; r && *r; r++) + (*print_func)( + (int)(unsigned char)*r, + ptr); + if (q) free(q); + free(p); + } + else rfc822tok_print(addrs->name, + print_func, ptr); + (*print_func)(' ', ptr); + print_braces=1; + } + else + { + struct rfc822token *p; + + for (p=addrs->tokens; p && p->next; p=p->next) + if (rfc822_is_atom(p->token) && + rfc822_is_atom(p->next->token)) + print_braces=1; + } + if (print_braces) + (*print_func)('<', ptr); + rfc822tok_print(addrs->tokens, print_func, ptr); + if (print_braces) + { + (*print_func)('>', ptr); + } + } + ++addrs; + --naddrs; + if (naddrs) + if (addrs->tokens || (addrs->name && + rfc822_is_atom(addrs->name->token))) + (*print_separator)(", ", ptr); + } +} + +void rfc822t_free(struct rfc822t *p) +{ + if (p->tokens) free(p->tokens); + free(p); +} + +void rfc822a_free(struct rfc822a *p) +{ + if (p->addrs) free(p->addrs); + free(p); +} + +void rfc822_deladdr(struct rfc822a *rfcp, int index) +{ +int i; + + if (index < 0 || index >= rfcp->naddrs) return; + + for (i=index+1; inaddrs; i++) + rfcp->addrs[i-1]=rfcp->addrs[i]; + if (--rfcp->naddrs == 0) + { + free(rfcp->addrs); + rfcp->addrs=0; + } +} + +struct rfc822t *rfc822t_alloc(const char *addr, + void (*err_func)(const char *, int)) +{ +struct rfc822t *p=(struct rfc822t *)malloc(sizeof(struct rfc822t)); + + if (!p) return (NULL); + memset(p, 0, sizeof(*p)); + + tokenize(addr, NULL, &p->ntokens, err_func); + p->tokens=p->ntokens ? (struct rfc822token *) + calloc(p->ntokens, sizeof(struct rfc822token)):0; + if (p->ntokens && !p->tokens) + { + rfc822t_free(p); + return (NULL); + } + tokenize(addr, p->tokens, &p->ntokens, NULL); + return (p); +} + +struct rfc822a *rfc822a_alloc(struct rfc822t *t) +{ +struct rfc822a *p=(struct rfc822a *)malloc(sizeof(struct rfc822a)); + + if (!p) return (NULL); + memset(p, 0, sizeof(*p)); + + parseaddr(t->tokens, t->ntokens, NULL, &p->naddrs); + p->addrs=p->naddrs ? (struct rfc822addr *) + calloc(p->naddrs, sizeof(struct rfc822addr)):0; + if (p->naddrs && !p->addrs) + { + rfc822a_free(p); + return (NULL); + } + parseaddr(t->tokens, t->ntokens, p->addrs, &p->naddrs); + return (p); +} + +void rfc822_praddr(const struct rfc822a *rfcp, int index, + void (*print_func)(char, void *), void *ptr) +{ +const struct rfc822addr *addrs; + + if (index < 0 || index >= rfcp->naddrs) return; + + addrs=rfcp->addrs+index; + if (addrs->tokens) + { + rfc822tok_print(addrs->tokens, print_func, ptr); + (*print_func)('\n', ptr); + } +} + +void rfc822_addrlist(const struct rfc822a *rfcp, + void (*print_func)(char, void *), void *ptr) +{ +int i; + + for (i=0; inaddrs; i++) + rfc822_praddr(rfcp, i, print_func, ptr); +} + +void rfc822_prname(const struct rfc822a *rfcp, int index, + void (*print_func)(char, void *), void *ptr) +{ +const struct rfc822addr *addrs; + + if (index < 0 || index >= rfcp->naddrs) return; + + addrs=rfcp->addrs+index; + + if (!addrs->tokens) return; + rfc822_prname_orlist(rfcp, index, print_func, ptr); +} + +void rfc822_prname_orlist(const struct rfc822a *rfcp, int index, + void (*print_func)(char, void *), void *ptr) +{ +const struct rfc822addr *addrs; + + if (index < 0 || index >= rfcp->naddrs) return; + + addrs=rfcp->addrs+index; + + if (addrs->name) + { + struct rfc822token *i; + int n; + int prev_isatom=0; + int isatom=0; + + for (i=addrs->name; i; i=i->next, prev_isatom=isatom) + { + isatom=rfc822_is_atom(i->token); + if (isatom && prev_isatom) + (*print_func)(' ', ptr); + + if (i->token != '(') + { + print_token(i, print_func, ptr); + continue; + } + + for (n=2; nlen; n++) + (*print_func)(i->ptr[n-1], ptr); + } + } else + rfc822tok_print(addrs->tokens, print_func, ptr); + (*print_func)('\n', ptr); +} + +void rfc822_namelist(const struct rfc822a *rfcp, + void (*print_func)(char, void *), void *ptr) +{ +int i; + + for (i=0; inaddrs; i++) + rfc822_prname(rfcp, i, print_func, ptr); +} diff --git a/packages/clib/maildrop/rfc822/rfc822.h b/packages/clib/maildrop/rfc822/rfc822.h new file mode 100644 index 000000000..2d84da786 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822.h @@ -0,0 +1,170 @@ +/* +** $Id$ +*/ +#ifndef rfc822_h +#define rfc822_h + +/* +** Copyright 1998 - 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** The text string we want to parse is first tokenized into an array of +** struct rfc822token records. 'ptr' points into the original text +** string, and 'len' has how many characters from 'ptr' belongs to this +** token. +*/ + +struct rfc822token { + struct rfc822token *next; /* Unused by librfc822, for use by + ** clients */ + int token; +/* + Values for token: + + '(' - comment + '"' - quoted string + '<', '>', '@', ',', ';', ':', '.', '[', ']', '%', '!', '=', '?', '/' - RFC atoms. + 0 - atom +*/ + +#define rfc822_is_atom(p) ( (p) == 0 || (p) == '"' || (p) == '(' ) + + const char *ptr; /* Pointer to value for the token. */ + int len; /* Length of token value */ +} ; + +/* +** After the struct rfc822token array is built, it is used to create +** the rfc822addr array, which is the array of addresses (plus +** syntactical fluff) extracted from those text strings. Each rfc822addr +** record has several possible interpretation: +** +** tokens is NULL - syntactical fluff, look in name/nname for tokens +** representing the syntactical fluff ( which is semicolons +** and list name: +** +** tokens is not NULL - actual address. The tokens representing the actual +** address is in tokens/ntokens. If there are comments in +** the address that are possible "real name" for the address +** they are saved in name/nname (name may be null if there +** is none). +** If nname is 1, and name points to a comment token, +** the address was specified in old-style format. Otherwise +** the address was specified in new-style route-addr format. +** +** The tokens and name pointers are set to point to the original rfc822token +** array. +*/ + +struct rfc822addr { + struct rfc822token *tokens; + struct rfc822token *name; +} ; + +/*************************************************************************** +** +** rfc822 tokens +** +***************************************************************************/ + +struct rfc822t { + struct rfc822token *tokens; + int ntokens; +} ; + +struct rfc822t *rfc822t_alloc(const char *p, + void (*err_func)(const char *, int)); /* Parse addresses */ +void rfc822t_free(struct rfc822t *); /* Free rfc822 structure */ + +void rfc822tok_print(const struct rfc822token *, void (*)(char, void *), void *); + /* Print the tokens */ + +/*************************************************************************** +** +** rfc822 addresses +** +***************************************************************************/ + +struct rfc822a { + struct rfc822addr *addrs; + int naddrs; +} ; + +struct rfc822a *rfc822a_alloc(struct rfc822t *); +void rfc822a_free(struct rfc822a *); /* Free rfc822 structure */ + +void rfc822_deladdr(struct rfc822a *, int); + +/* rfc822_print "unparses" the rfc822 structure. Each rfc822addr is "printed" + (via the attached function). NOTE: instead of separating addresses by + commas, the print_separator function is called. +*/ + +void rfc822_print(const struct rfc822a *a, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *); + +/* rfc822_print_common is an internal function */ + +void rfc822_print_common(const struct rfc822a *a, + char *(*decode_func)(const char *, const char *), + const char *chset, + void (*print_func)(char, void *), + void (*print_separator)(const char *, void *), void *); + +/* Another unparser, except that only the raw addresses are extracted, + and each address is followed by a newline character */ + +void rfc822_addrlist(const struct rfc822a *, void (*print_func)(char, void *), + void *); + +/* Now, just the comments. If comments not given, the address. */ +void rfc822_namelist(const struct rfc822a *, void (*print_func)(char, void *), + void *); + +/* Unparse an individual name/addr from a list of addresses. If the given + index points to some syntactical fluff, this is a noop */ + +void rfc822_prname(const struct rfc822a *, int, void (*)(char, void *), void *); +void rfc822_praddr(const struct rfc822a *, int, void (*)(char, void *), void *); + +/* Like rfc822_prname, except that we'll also print the legacy format +** of a list designation. +*/ + +void rfc822_prname_orlist(const struct rfc822a *, int, + void (*)(char, void *), void *); + +/* Extra functions */ + +char *rfc822_gettok(const struct rfc822token *); +char *rfc822_getaddr(const struct rfc822a *, int); +char *rfc822_getname(const struct rfc822a *, int); +char *rfc822_getname_orlist(const struct rfc822a *, int); +char *rfc822_getaddrs(const struct rfc822a *); +char *rfc822_getaddrs_wrap(const struct rfc822a *, int); + +void rfc822_mkdate_buf(time_t, char *); +const char *rfc822_mkdate(time_t); +time_t rfc822_parsedt(const char *); + +char *rfc822_coresubj(const char *, int *); +char *rfc822_coresubj_nouc(const char *, int *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packages/clib/maildrop/rfc822/rfc822.html b/packages/clib/maildrop/rfc822/rfc822.html new file mode 100644 index 000000000..2d7334b35 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822.html @@ -0,0 +1,391 @@ + + + + + rfc822 - RFC 822 parsing library + + + + + + + +

rfc822 - RFC 822 parsing library

+ +

SYNOPSIS

+ +

#include <rfc822.h>

+ +

#include <rfc2047.h>

+ +

cc ... -lrfc822

+ +

DESCRIPTION

+ +

The rfc822 library provides functions for parsing E-mail headers in the RFC +822 format. This library also includes some functions to help with encoding +and decoding 8-bit text, as defined by RFC 2047.

+ +

The format used by E-mail headers to encode sender and recipient +information is defined by RFC 822. The format allows the actual E-mail +address and the sender/recipient name to be expressed together, for example: +John Smith <jsmith@example.com>

+ +

The main purposes of the rfc822 library is to:

+ +

1) Parse a text string containing a list of RFC 822-formatted address into +its logical components: names and E-mail addresses.

+ +

2) Access those individual components.

+ +

3) Allow some limited modifications of the parsed structure, and then +convert it back into a text string.

+ +

Tokenizing an E-mail header

+
struct rfc822t *tokens=rfc822t_alloc(const char *header,
+                void (*err_func)(const char *, int));
+
+void rfc822t_free(tokens);
+ +

The rfc822t_alloc() function accepts an E-mail header, and parses it +into individual tokens. This function allocates and returns a pointer to a +rfc822t structure, which is later used by the rfc822a_alloc +function to extract individual addresses from these tokens.

+ +

If err_func argument, if not NULL, is a pointer to a callback +function. The function is called in the event that the E-mail header is +corrupted to the point that it cannot even be parsed. This is a rare +instances -- most forms of corruption are still valid at least on the lexical +level. The only time this error is reported is in the event of mismatched +parenthesis, angle brackets, or quotes. The callback function receives the +header pointer, and an index to the syntax error in the header +string.

+ +

The semantics of err_func are subject to change. It is recommended +to leave this argument as NULL in the current version of the library.

+ +

rfc822t_alloc() returns a pointer to a dynamically-allocated rfc822t +structure. A NULL pointer is returned if there's insufficient memory to +allocate this structure. The rfc822t_free() function is used to destroy the +rfc822t structure and to free all the dynamically allocated memory.

+ +

NOTE: Until rfc822t_free() is called, the contents of header MUST +NOT be destroyed or altered in any way. The contents of header are not +modified by rfc822t_alloc(), however the rfc822t structure contains +pointers to portions of the supplied header.

+ +

Extracting E-mail addresses

+
struct rfc822a *addrs=rfc822a_alloc(struct rfc822t *tokens);
+
+void rfc822a_free(addrs);
+ +

The rfc822a_alloc() function returns a dynamically-allocated rfc822a +structure, that contains individual addresses that were logically extracted +from a rfc822t structure. The rfc822a_alloc() function returns NULL if +there was insufficient memory to allocate the rfc822a structure. The +rfc822a_free() function destroys the rfc822a function, and frees all +associated dynamically-allocated memory. The rfc822t structure passed +to rfc822a_alloc() must not be destroyed before rfc822a_free() destroys the +rfc822a structure.

+ +

The rfc822a structure has the following fields:

+
struct rfc822a {
+        struct rfc822addr *addrs;
+        int     naddrs;
+} ;
+ +

The naddrs field gives the number of rfc822addr structures +that are pointed to by addrs, which is an array. Each rfc822addr +structure represents either an address found in the original E-mail header, +or the contents of some legacy "syntactical sugar". For example, the +following is a valid E-mail header:

+
To: recipient-list: tom@example.com, john@example.com;
+ +

Typically, all of this, sans the "To:" part, is tokenized by +rfc822t_alloc(), then parsed by rfc822a_alloc(). The "recipient-list:" and +the trailing semicolon is a legacy mailing list specification that is no +longer in widespread use, but still must be accounted for. The resulting +rfc822a structure will have four rfc822addr structures, one for +"recipient-list:", one for each address, and one for the trailing semicolon. +Each rfc822a structure has the following fields:

+
struct rfc822addr {
+        struct rfc822token *tokens;
+        struct rfc822token *name;
+} ;
+ +

If tokens is a null pointer, this structure represents some +non-address portion of the original header, such as "recipient-list:" or a +semicolon. Otherwise it points to a structure that represents the E-mail +address in tokenized form.

+ +

name either points to the tokenized form of a non-address portion of +the original header, or to a tokenized form of the recipient's name. +name will be NULL if the recipient name was not provided. For the +following address: Tom Jones <tjones@example.com> The +tokens field will point to the tokenized form of "tjones@example.com", +and name points to the tokenized form of "Tom Jones".

+ +

Each rfc822token structure contains the following fields:

+
struct rfc822token {
+        struct rfc822token *next;
+        int token;
+        const char *ptr;
+        int len;
+} ;
+ +

The next pointer builds a linked list of all tokens in this name or +address. The possible values for the token field are:

+
    +
  • 0x00 - this is a simple atom - a sequence of non-special characters that + is delimited by whitespace or special characters (see below).
    +
    +
  • +
  • 0x22 - the value of the ascii quote - this is a quoted string.
    +
    +
  • +
  • '(' - this is an old style comment. A deprecated form of E-mail + addressing uses, as an example, "john@example.com (John Smith)" instead of + "John Smith <john@example.com>". This old-style notation defined + parenthesized content as arbitrary comments. The rfc822token with + token set to '(' is created for the contents of the entire + comment.
    +
    +
  • +
  • '<', '>', '@', and many others - the remaining possible values of + token include all the characters in RFC 822 headers that have + special significance.
  • +
+ +

When a rfc822token structure does not represent a special character, +the ptr field points to a text string giving its contents. The contents +are NOT null-terminated, the len field contains the number of +characters included. The macro rfc822_is_atom(token) indicates whether +ptr and len are used for the given token. Currently +rfc822_is_atom() returns true if token is a zero byte, '"', or '('.

+ +

Note that it's possible that len might be zero. This will be the +case for null addresses used as return addresses for delivery status +notifications.

+ +

Working with E-mail addresses

+
void rfc822_deladdr(struct rfc822a *addrs, int index);
+
+void rfc822tok_print(const struct rfc822token *list,
+        void (*func)(char, void *), void *func_arg);
+
+void rfc822_print(const struct rfc822a *addrs,
+        void (*print_func)(char, void *),
+        void (*print_separator)(const char *, void *), void *callback_arg);
+ 
+void rfc822_addrlist(const struct rfc822a *addrs,
+                void (*print_func)(char, void *),
+                void *callback_arg);
+ 
+void rfc822_namelist(const struct rfc822a *addrs,
+                void (*print_func)(char, void *),
+                void *callback_arg);
+
+void rfc822_praddr(const struct rfc822a *addrs,
+                int index,
+                void (*print_func)(char, void *),
+                void *callback_arg);
+
+void rfc822_prname(const struct rfc822a *addrs,
+                int index,
+                void (*print_func)(char, void *),
+                void *callback_arg);
+
+void rfc822_prname_orlist(const struct rfc822a *addrs,
+                int index,
+                void (*print_func)(char, void *),
+                void *callback_arg);
+
+char *rfc822_gettok(const struct rfc822token *list);
+char *rfc822_getaddrs(const struct rfc822a *addrs);
+char *rfc822_getaddr(const struct rfc822a *addrs, int index);
+char *rfc822_getname(const struct rfc822a *addrs, int index);
+char *rfc822_getname_orlist(const struct rfc822a *addrs, int index);
+
+char *rfc822_getaddrs_wrap(const struct rfc822a *, int);
+ +

These functions are used to work with individual addresses that are parsed +by rfc822a_alloc().

+ +

rfc822_deladdr() removes a single rfc822addr structure, whose +index is given, from the address array in rfc822addr. +naddrs is decremented by one.

+ +

rfc822tok_print() converts a tokenized list of rfc822token +objects into a text string. The callback function, func, is called one +character at a time, for every character in the tokenized objects. An +arbitrary pointer, func_arg, is passed unchanged as the additional +argument to the callback function. rfc822tok_print() is not usually the most +convenient and efficient function, but it has its uses.

+ +

rfc822_print() takes an entire rfc822a structure, and uses the +callback functions to print the contained addresses, in their original form, +separated by commas. The function pointed to by print_func is used to +print each individual address, one character at a time. Between the +addresses, the print_separator function is called to print the address +separator, usually the string ", ". The callback_arg argument is passed +along unchanged, as an additional argument to these functions.

+ +

The functions rfc822_addrlist() and rfc822_namelist() also print the +contents of the entire rfc822a structure, but in a different way. +rfc822_addrlist() prints just the actual E-mail addresses, not the recipient +names or comments. Each E-mail address is followed by a newline character. +rfc822_namelist() prints just the names or comments, followed by newlines.

+ +

The functions rfc822_praddr() and rfc822_prname() are just like +rfc822_addrlist() and rfc822_namelist(), except that they print a single name +or address in the rfc822a structure, given its index. The +functions rfc822_gettok(), rfc822_getaddrs(), rfc822_getaddr(), and +rfc822_getname() are equivalent to rfc822tok_print(), rfc822_print(), +rfc822_praddr() and rfc822_prname(), but, instead of using a callback function +pointer, these functions write the output into a dynamically allocated buffer. +That buffer must be destroyed by free(3) after use. These functions will +return a null pointer in the event of a failure to allocate memory for the +buffer.

+ +

rfc822_prname_orlist() is similar to rfc822_prname(), except that it will +also print the legacy RFC822 group list syntax (which are also parsed by +rfc822a_alloc()). rfc822_praddr() will print an empty string for an index +that corresponds to a group list name (or terminated semicolon). +rfc822_prname() will also print an empty string. rfc822_prname_orlist() will +instead print either the name of the group list, or a single string ";". +rfc822_getname_orlist() will instead save it into a dynamically allocated +buffer.

+ +

The function rfc822_getaddrs_wrap() is similar to rfc822_getaddrs(), except +that the generated text is wrapped on or about the 73rd column, using newline +characters.

+ +

Working with dates

+
time_t timestamp=rfc822_parsedt(const char *datestr)
+const char *datestr=rfc822_mkdate(time_t timestamp);
+void rfc822_mkdate_buf(time_t timestamp, char *buffer);
+ +

These functions convert between timestamps and dates expressed in the Date: +E-mail header format.

+ +

rfc822_parsedt() returns the timestamp corresponding to the given date +string (0 if there was a syntax error).

+ +

rfc822_mkdate() returns a date string corresponding to the given timestamp. +rfc822_mkdate_buf() writes the date string into the given buffer instead, +which must be of sufficient size to accommodate it.

+ +

Working with 8-bit MIME-encoded headers

+
int error=rfc2047_decode(const char *text,
+                int (*callback_func)(const char *, int, const char *, void *),
+                void *callback_arg);
+ 
+extern char *str=rfc2047_decode_simple(const char *text);
+ 
+extern char *str=rfc2047_decode_enhanced(const char *text,
+                const char *charset);
+ 
+void rfc2047_print(const struct rfc822a *a,
+        const char *charset,
+        void (*print_func)(char, void *),
+        void (*print_separator)(const char *, void *), void *);
+
+ 
+char *buffer=rfc2047_encode_str(const char *string,
+                const char *charset);
+ 
+int error=rfc2047_encode_callback(const char *string,
+        const char *charset,
+        int (*func)(const char *, size_t, void *),
+        void *callback_arg);
+ 
+char *buffer=rfc2047_encode_header(const struct rfc822a *a,
+        const char *charset);
+ +

These functions provide additional logic to encode or decode 8-bit content +in 7-bit RFC 822 headers, as specified in RFC 2047.

+ +

rfc2047_decode() is a basic RFC 2047 decoding function. It receives a +pointer to some 7bit RFC 2047-encoded text, and a callback function. The +callback function is repeatedly called. Each time it's called it receives a +piece of decoded text. The arguments are: a pointer to a text fragment, number +of bytes in the text fragment, followed by a pointer to the character set of +the text fragment. The character set pointer is NULL for portions of the +original text that are not RFC 2047-encoded.

+ +

The callback function also receives callback_arg, as its last +argument. If the callback function returns a non-zero value, rfc2047_decode() +terminates, returning that value. Otherwise, rfc2047_decode() returns 0 after +a successful decoding. rfc2047_decode() returns -1 if it was unable to +allocate sufficient memory.

+ +

rfc2047_decode_simple() and rfc2047_decode_enhanced() are alternatives to +rfc2047_decode() which forego a callback function, and return the decoded text +in a dynamically-allocated memory buffer. The buffer must be free(3)-ed after +use. rfc2047_decode_simple() discards all character set specifications, and +merely decodes any 8-bit text. rfc2047_decode_enhanced() is a compromise to +discarding all character set information. The local character set being used +is specified as the second argument to rfc2047_decode_enhanced(). Any RFC +2047-encoded text in a different character set will be prefixed by the name of +the character set, in brackets, in the resulting output.

+ +

rfc2047_decode_simple() and rfc2047_decode_enhanced() return a null pointer +if they are unable to allocate sufficient memory.

+ +

The rfc2047_print() function is equivalent to rfc822_print(), followed by +rfc2047_decode_enhanced() on the result. The callback functions are used in +an identical fashion, except that they receive text that's already +decoded.

+ +

The function rfc2047_encode_str() takes a string and charset +being the name of the local character set, then encodes any 8-bit portions of +string using RFC 2047 encoding. rfc2047_encode_str() returns a +dynamically-allocated buffer with the result, which must be free(3)-ed after +use, or NULL if there was insufficient memory to allocate the buffer.

+ +

The function rfc2047_encode_callback() is similar to rfc2047_encode_str() +except that the callback function is repeatedly called to received the +encoding string. Each invocation of the callback function receives a pointer +to a portion of the encoded text, the number of characters in this portion, +and callback_arg.

+ +

The function rfc2047_encode_header() is basically equivalent to +rfc822_getaddrs(), followed by rfc2047_encode_str();

+ +

Working with subjects

+
char *basesubj=rfc822_coresubj(const char *subj)
+
+char *basesubj=rfc822_coresubj_nouc(const char *subj)
+ +

This function takes the contents of the subject header, and returns the +"core" subject header that's used in the specification of the IMAP THREAD +function. This function is designed to strip all subject line artifacts that +might've been added in the process of forwarding or replying to a message. +Currently, rfc822_coresubj() performs the following transformations:

+
    +
  • Whitespace - leading and trailing whitespace is removed. Consecutive + whitespace characters are collapsed into a single whitespace character. + All whitespace characters are replaced by a space.
    +
    +
  • +
  • Re:, (fwd) [foo] - these artifacts (and several others) are removed from + the subject line.
  • +
+ +

Note that this function does NOT do MIME decoding. In order to implement +IMAP THREAD, it is necessary to call something like rfc2047_decode() before +calling rfc822_coresubj().

+ +

This function returns a pointer to a dynamically-allocated buffer, which +must be free(3)-ed after use.

+ +

rfc822_coresubj_nouc() is like rfc822_coresubj(), except that the subject +is not converted to uppercase.

+ +

SEE ALSO

+rfc2045(3), reformime(1), reformail(1). + diff --git a/packages/clib/maildrop/rfc822/rfc822_getaddr.c b/packages/clib/maildrop/rfc822/rfc822_getaddr.c new file mode 100644 index 000000000..3cd1976c3 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822_getaddr.c @@ -0,0 +1,101 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ +#include "rfc822.h" +#include + +static void cntlen(char c, void *p) +{ + if (c != '\n') + ++ *(size_t *)p; +} + +static void saveaddr(char c, void *p) +{ + if (c != '\n') + { + char **cp=(char **)p; + + *(*cp)++=c; + } +} + +char *rfc822_getaddr(const struct rfc822a *rfc, int n) +{ +size_t addrbuflen=0; +char *addrbuf, *ptr; + + rfc822_praddr(rfc, n, &cntlen, &addrbuflen); + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822_praddr(rfc, n, &saveaddr, &ptr); + addrbuf[addrbuflen]=0; + return (addrbuf); +} + +char *rfc822_getname(const struct rfc822a *rfc, int n) +{ +char *p, *q; +size_t addrbuflen=0; +char *addrbuf, *ptr; + + rfc822_prname(rfc, n, &cntlen, &addrbuflen); + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822_prname(rfc, n, &saveaddr, &ptr); + addrbuf[addrbuflen]=0; + + /* Get rid of surrounding quotes */ + + for (p=q=addrbuf; *p; p++) + if (*p != '"') *q++=*p; + *q=0; + return (addrbuf); +} + +char *rfc822_getname_orlist(const struct rfc822a *rfc, int n) +{ +char *p, *q; +size_t addrbuflen=0; +char *addrbuf, *ptr; + + rfc822_prname_orlist(rfc, n, &cntlen, &addrbuflen); + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822_prname_orlist(rfc, n, &saveaddr, &ptr); + addrbuf[addrbuflen]=0; + + /* Get rid of surrounding quotes */ + + for (p=q=addrbuf; *p; p++) + if (*p != '"') *q++=*p; + *q=0; + return (addrbuf); +} + +char *rfc822_gettok(const struct rfc822token *t) +{ +size_t addrbuflen=0; +char *addrbuf, *ptr; + + rfc822tok_print(t, &cntlen, &addrbuflen); + + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822tok_print(t, &saveaddr, &ptr); + addrbuf[addrbuflen]=0; + return (addrbuf); +} diff --git a/packages/clib/maildrop/rfc822/rfc822_getaddrs.c b/packages/clib/maildrop/rfc822/rfc822_getaddrs.c new file mode 100644 index 000000000..664cb7e36 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822_getaddrs.c @@ -0,0 +1,94 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ +#include "rfc822.h" +#include + +static void cntlen(char c, void *p) +{ + c=c; + ++ *(size_t *)p; +} + +static void cntlensep(const char *p, void *ptr) +{ + while (*p) cntlen(*p++, ptr); +} + +static void saveaddr(char c, void *ptr) +{ + *(*(char **)ptr)++=c; +} + +static void saveaddrsep(const char *p, void *ptr) +{ + while (*p) saveaddr(*p++, ptr); +} + +char *rfc822_getaddrs(const struct rfc822a *rfc) +{ +size_t addrbuflen=0; +char *addrbuf, *ptr; + + rfc822_print(rfc, &cntlen, &cntlensep, &addrbuflen); + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822_print(rfc, &saveaddr, &saveaddrsep, &ptr); + addrbuf[addrbuflen]=0; + return (addrbuf); +} + +static void saveaddrsep_wrap(const char *p, void *ptr) +{ +int c; + + while ((c=*p++) != 0) + { + if (c == ' ') c='\n'; + saveaddr(c, ptr); + } +} + +char *rfc822_getaddrs_wrap(const struct rfc822a *rfc, int w) +{ +size_t addrbuflen=0; +char *addrbuf, *ptr, *start, *lastnl; + + rfc822_print(rfc, &cntlen, &cntlensep, &addrbuflen); + if (!(addrbuf=malloc(addrbuflen+1))) + return (0); + + ptr=addrbuf; + rfc822_print(rfc, &saveaddr, &saveaddrsep_wrap, &ptr); + addrbuf[addrbuflen]=0; + + for (lastnl=0, start=ptr=addrbuf; *ptr; ) + { + while (*ptr && *ptr != '\n') ptr++; + if (ptr-start < w) + { + if (lastnl) *lastnl=' '; + lastnl=ptr; + if (*ptr) ++ptr; + } + else + { + if (lastnl) + start=lastnl+1; + else + { + start=ptr+1; + if (*ptr) ++ptr; + } + lastnl=0; + } + } + return (addrbuf); +} diff --git a/packages/clib/maildrop/rfc822/rfc822_mkdate.c b/packages/clib/maildrop/rfc822/rfc822_mkdate.c new file mode 100644 index 000000000..9c6a3daa8 --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822_mkdate.c @@ -0,0 +1,113 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ + +#include "rfc822.h" + +#include +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif + +static const char * const months[]={ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec"}; + +static const char * const wdays[]={ + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat"}; + +void rfc822_mkdate_buf(time_t t, char *buf) +{ +struct tm *p; +int offset; + +#if USE_TIME_ALTZONE + + p=localtime(&t); + offset= -timezone; + + if (p->tm_isdst > 0) + offset= -altzone; + + if (offset % 60) + { + offset=0; + p=gmtime(&t); + } + offset /= 60; +#else +#if USE_TIME_DAYLIGHT + + p=localtime(&t); + offset= -timezone; + + if (p->tm_isdst > 0) + offset += 60*60; + if (offset % 60) + { + offset=0; + p=gmtime(&t); + } + offset /= 60; +#else +#if USE_TIME_GMTOFF + p=localtime(&t); + offset= p->tm_gmtoff; + + if (offset % 60) + { + offset=0; + p=gmtime(&t); + } + offset /= 60; +#else + p=gmtime(&t); + offset=0; +#endif +#endif +#endif + + offset = (offset % 60) + offset / 60 * 100; + + sprintf(buf, "%s, %02d %s %04d %02d:%02d:%02d %+05d", + wdays[p->tm_wday], + p->tm_mday, + months[p->tm_mon], + p->tm_year+1900, + p->tm_hour, + p->tm_min, + p->tm_sec, + offset); +} + +const char *rfc822_mkdate(time_t t) +{ +static char buf[50]; + + rfc822_mkdate_buf(t, buf); + return (buf); +} diff --git a/packages/clib/maildrop/rfc822/rfc822_parsedt.c b/packages/clib/maildrop/rfc822/rfc822_parsedt.c new file mode 100644 index 000000000..92c1f0cca --- /dev/null +++ b/packages/clib/maildrop/rfc822/rfc822_parsedt.c @@ -0,0 +1,243 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** $Id$ +*/ +#include +#include +#include +#include + +/* +** time_t rfc822_parsedate(const char *p) +** +** p - contents of the Date: header, attempt to parse it into a time_t. +** +** returns - time_t, or 0 if the date cannot be parsed +*/ + +static unsigned parsedig(const char **p) +{ +unsigned i=0; + + while (isdigit((int)(unsigned char)**p)) + { + i=i*10 + **p - '0'; + ++*p; + } + return (i); +} + +static const char * const weekdays[7]={ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + } ; + +static const char * const mnames[13]={ + "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec", NULL}; + +#define leap(y) ( \ + ((y) % 400) == 0 || \ + (((y) % 4) == 0 && (y) % 100) ) + +static unsigned mlength[]={31,28,31,30,31,30,31,31,30,31,30,31}; +#define mdays(m,y) ( (m) != 2 ? mlength[(m)-1] : leap(y) ? 29:28) + +static const char * const zonenames[] = { + "UT","GMT", + "EST","EDT", + "CST","CDT", + "MST","MDT", + "PST","PDT", + "Z", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", + NULL}; + +#define ZH(n) ( (n) * 60 * 60 ) + +static int zoneoffset[] = { + 0, 0, + ZH(-5), ZH(-4), + ZH(-6), ZH(-5), + ZH(-7), ZH(-6), + ZH(-8), ZH(-7), + 0, + + ZH(-1), ZH(-2), ZH(-3), ZH(-4), ZH(-5), ZH(-6), ZH(-7), ZH(-8), ZH(-9), ZH(-10), ZH(-11), ZH(-12), + ZH(1), ZH(2), ZH(3), ZH(4), ZH(5), ZH(6), ZH(7), ZH(8), ZH(9), ZH(10), ZH(11), ZH(12) }; + +static unsigned parsekey(const char **mon, const char * const *ary) +{ +unsigned m, j; + + for (m=0; ary[m]; m++) + { + for (j=0; ary[m][j]; j++) + if (tolower(ary[m][j]) != tolower((*mon)[j])) + break; + if (!ary[m][j]) + { + *mon += j; + return (m+1); + } + } + return (0); +} + +static int parsetime(const char **t) +{ +unsigned h,m,s=0; + + if (!isdigit((int)(unsigned char)**t)) return (-1); + h=parsedig(t); + if (h > 23) return (-1); + if (**t != ':') return (-1); + ++*t; + if (!isdigit((int)(unsigned char)**t)) return (-1); + m=parsedig(t); + if (**t == ':') + { + ++*t; + if (!isdigit((int)(unsigned char)**t)) return (-1); + s=parsedig(t); + } + if (m > 59 || s > 59) return (-1); + return (h * 60 * 60 + m * 60 + s); +} + +time_t rfc822_parsedt(const char *rfcdt) +{ +unsigned day=0, mon=0, year; +int secs; +int offset; +time_t t; +unsigned y; + + /* Ignore day of the week. Tolerate "Tue, 25 Feb 1997 ... " + ** without the comma. Tolerate "Feb 25 1997 ...". + */ + + while (!day || !mon) + { + if (!*rfcdt) return (0); + if (isalpha((int)(unsigned char)*rfcdt)) + { + if (mon) return (0); + mon=parsekey(&rfcdt, mnames); + if (!mon) + while (*rfcdt && isalpha((int)(unsigned char)*rfcdt)) + ++rfcdt; + continue; + } + + if (isdigit((int)(unsigned char)*rfcdt)) + { + if (day) return (0); + day=parsedig(&rfcdt); + if (!day) return (0); + continue; + } + ++rfcdt; + } + + while (*rfcdt && isspace((int)(unsigned char)*rfcdt)) + ++rfcdt; + if (!isdigit((int)(unsigned char)*rfcdt)) return (0); + year=parsedig(&rfcdt); + if (year < 70) year += 2000; + if (year < 100) year += 1900; + + while (*rfcdt && isspace((int)(unsigned char)*rfcdt)) + ++rfcdt; + + if (day == 0 || mon == 0 || mon > 12 || day > mdays(mon,year)) + return (0); + + secs=parsetime(&rfcdt); + if (secs < 0) return (0); + + offset=0; + + /* RFC822 sez no parenthesis, but I've seen (EST) */ + + while ( *rfcdt ) + { + if (isalnum((int)(unsigned char)*rfcdt) || *rfcdt == '+' || *rfcdt == '-') + break; + ++rfcdt; + } + + if (isalpha((int)(unsigned char)*rfcdt)) + { + int n=parsekey(&rfcdt, zonenames); + + if (n > 0) offset= zoneoffset[n-1]; + } + else + { + int sign=1; + unsigned n; + + switch (*rfcdt) { + case '-': + sign= -1; + case '+': + ++rfcdt; + } + + if (isdigit((int)(unsigned char)*rfcdt)) + { + n=parsedig(&rfcdt); + if (n > 2359 || (n % 100) > 59) n=0; + offset = sign * ( (n % 100) * 60 + n / 100 * 60 * 60); + } + } + + if (year < 1970) return (0); + + t=0; + for (y=1970; y= 4) + { + y += 3; + t += ( 365*3+366 ) * 24 * 60 * 60; + continue; + } + t += 24 * 60 * 60; + } + t += 365 * 24 * 60 * 60; + } + + for (y=1; y < mon; y++) + t += mdays(y, year) * 24 * 60 * 60; + + return ( t + (day-1) * 24 * 60 * 60 + secs - offset ); +} + +const char *rfc822_mkdt(time_t t) +{ +static char buf[80]; +struct tm *tmptr=gmtime(&t); + + buf[0]=0; + if (tmptr) + { + sprintf(buf, "%s, %02d %s %04d %02d:%02d:%02d GMT", + weekdays[tmptr->tm_wday], + tmptr->tm_mday, + mnames[tmptr->tm_mon], + tmptr->tm_year + 1900, + tmptr->tm_hour, + tmptr->tm_min, + tmptr->tm_sec); + } + return (buf); +} diff --git a/packages/clib/maildrop/rfc822/stamp-h.in b/packages/clib/maildrop/rfc822/stamp-h.in new file mode 100644 index 000000000..9788f7023 --- /dev/null +++ b/packages/clib/maildrop/rfc822/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/packages/clib/maildrop/rfc822/stamp-h1 b/packages/clib/maildrop/rfc822/stamp-h1 new file mode 100644 index 000000000..4547fe1b5 --- /dev/null +++ b/packages/clib/maildrop/rfc822/stamp-h1 @@ -0,0 +1 @@ +timestamp for config.h diff --git a/packages/clib/maildrop/rfc822/testsuite.c b/packages/clib/maildrop/rfc822/testsuite.c new file mode 100644 index 000000000..98fe63bb9 --- /dev/null +++ b/packages/clib/maildrop/rfc822/testsuite.c @@ -0,0 +1,86 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#include "rfc822.h" +#include +#include + +static const char rcsid[]="$Id$"; + +static void print_func(char c, void *p) +{ + p=p; + putchar(c); +} + +static void print_separator(const char *s, void *p) +{ + p=p; + printf("%s", s); +} + +static struct rfc822t *tokenize(const char *p) +{ +struct rfc822t *tp; +int i; +char buf[2]; + + printf("Tokenize: %s\n", p); + tp=rfc822t_alloc(p, NULL); + if (!tp) exit(0); + buf[1]=0; + for (i=0; intokens; i++) + { + buf[0]=tp->tokens[i].token; + if (buf[0] == '\0' || buf[0] == '"' || buf[0] == '(') + { + printf("%s: ", buf[0] == '"' ? "Quote": + buf[0] == '(' ? "Comment":"Atom"); + fwrite(tp->tokens[i].ptr, tp->tokens[i].len, 1, stdout); + printf("\n"); + } + else printf("Token: %s\n", buf[0] ? buf:"atom"); + } + return (tp); +} + +static struct rfc822a *doaddr(struct rfc822t *t) +{ +struct rfc822a *a=rfc822a_alloc(t); + + if (!a) exit(0); + printf("----\n"); + rfc822_print(a, print_func, print_separator, NULL); + printf("\n"); + rfc822_addrlist(a, print_func, NULL); + rfc822_namelist(a, print_func, NULL); + return (a); +} + +int main() +{ +struct rfc822t *t1, *t2, *t3, *t4; +struct rfc822a *a1, *a2, *a3, *a4; + + t1=tokenize("nobody@example.com (Nobody (is) here\\) right)"); + t2=tokenize("Distribution list: nobody@example.com daemon@example.com"); + t3=tokenize("Mr Nobody , Mr. Nobody "); + t4=tokenize("nobody@example.com, , Mr. Nobody "); + + a1=doaddr(t1); + a2=doaddr(t2); + a3=doaddr(t3); + a4=doaddr(t4); + + rfc822a_free(a4); + rfc822a_free(a3); + rfc822a_free(a2); + rfc822a_free(a1); + rfc822t_free(t4); + rfc822t_free(t3); + rfc822t_free(t2); + rfc822t_free(t1); + return (0); +} diff --git a/packages/clib/maildrop/rfc822/testsuite.txt b/packages/clib/maildrop/rfc822/testsuite.txt new file mode 100644 index 000000000..a4fdcd175 --- /dev/null +++ b/packages/clib/maildrop/rfc822/testsuite.txt @@ -0,0 +1,91 @@ +Tokenize: nobody@example.com (Nobody (is) here\) right) +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Comment: (Nobody (is) here\) right) +Tokenize: Distribution list: nobody@example.com daemon@example.com +Atom: Distribution +Atom: list +Token: : +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Atom: daemon +Token: @ +Atom: example +Token: . +Atom: com +Tokenize: Mr Nobody , Mr. Nobody +Atom: Mr +Atom: Nobody +Token: < +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Token: > +Token: , +Atom: Mr +Token: . +Atom: Nobody +Token: < +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Token: > +Tokenize: nobody@example.com, , Mr. Nobody +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Token: , +Token: < +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Token: > +Token: , +Atom: Mr +Token: . +Atom: Nobody +Token: < +Atom: nobody +Token: @ +Atom: example +Token: . +Atom: com +Token: > +---- +nobody@example.com (Nobody (is) here\) right) +nobody@example.com +Nobody (is) here\) right +---- +Distribution list: nobody@example.com, daemon@example.com +nobody@example.com +daemon@example.com +nobody@example.com +daemon@example.com +---- +Mr Nobody , "Mr. Nobody" +nobody@example.com +nobody@example.com +Mr Nobody +"Mr. Nobody" +---- +nobody@example.com, nobody@example.com, "Mr. Nobody" +nobody@example.com +nobody@example.com +nobody@example.com +nobody@example.com +nobody@example.com +"Mr. Nobody" diff --git a/packages/clib/md5.c b/packages/clib/md5.c new file mode 100644 index 000000000..7e8325544 --- /dev/null +++ b/packages/clib/md5.c @@ -0,0 +1,381 @@ +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id$ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#include +#include "md5.h" + +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define BYTE_ORDER 0 +#endif + +#define T_MASK ((md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + + +static void +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +{ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; +#if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; +#else + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + const md5_word_t *X; +#endif + + { +#if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ +#endif +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; + +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +md5_init(md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +void +md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes) +{ + const md5_byte_t *p = data; + size_t left = nbytes; + size_t offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += (int)(nbytes >> 29); + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +{ + static const md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/packages/clib/md5.h b/packages/clib/md5.h new file mode 100644 index 000000000..47bf44182 --- /dev/null +++ b/packages/clib/md5.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id$ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Initialize the algorithm. */ +void md5_init(md5_state_t *pms); + +/* Append a string to the message. */ +void md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes); + +/* Finish the message and return the digest. */ +void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* md5_INCLUDED */ diff --git a/packages/clib/md5passwd.c b/packages/clib/md5passwd.c new file mode 100644 index 000000000..a5883ff81 --- /dev/null +++ b/packages/clib/md5passwd.c @@ -0,0 +1,169 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Header$"; +#endif /* LIBC_SCCS and not lint */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include "md5.h" + +#define MD5_CTX md5_state_t +#define MD5Init md5_init +#define MD5Update(ctx, data, len) md5_append(ctx, (md5_byte_t*)data, len) +#define MD5Final(digest, ctx) md5_finish(ctx, digest) + + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void +to64(s, v, n) + char *s; + unsigned long v; + int n; +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ + +char * +md5_crypt(pw, salt) + register const char *pw; + register const char *salt; +{ + static char *magic = "$1$"; /* + * This string is magic for + * this algorithm. Having + * it this way, we can get + * get better later on + */ + static char passwd[120], *p; + static const char *sp,*ep; + unsigned char final[16]; + size_t sl,pl,i,j; + MD5_CTX ctx,ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if(!strncmp(sp,magic,strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5Update(&ctx,pw,strlen(pw)); + + /* Then our magic string */ + MD5Update(&ctx,magic,strlen(magic)); + + /* Then the raw salt */ + MD5Update(&ctx,sp,sl); + + /* Then just as many characters of the MD5(pw,salt,pw) */ + MD5Init(&ctx1); + MD5Update(&ctx1,pw,strlen(pw)); + MD5Update(&ctx1,sp,sl); + MD5Update(&ctx1,pw,strlen(pw)); + MD5Final(final,&ctx1); + for(pl = strlen(pw); pl > 0; ) + { MD5Update(&ctx,final,pl>16 ? 16 : pl); + if ( pl > 16 ) + pl -= 16; + else + break; + } + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + /* Then something really weird... */ + for (j=0,i = strlen(pw); i ; i >>= 1) + if(i&1) + MD5Update(&ctx, final+j, 1); + else + MD5Update(&ctx, pw+j, 1); + + /* Now make the output string */ + strcpy(passwd,magic); + strncat(passwd,sp,sl); + strcat(passwd,"$"); + + MD5Final(final,&ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for(i=0;i<1000;i++) { + MD5Init(&ctx1); + if(i & 1) + MD5Update(&ctx1,pw,strlen(pw)); + else + MD5Update(&ctx1,final,16); + + if(i % 3) + MD5Update(&ctx1,sp,sl); + + if(i % 7) + MD5Update(&ctx1,pw,strlen(pw)); + + if(i & 1) + MD5Update(&ctx1,final,16); + else + MD5Update(&ctx1,pw,strlen(pw)); + MD5Final(final,&ctx1); + } + + p = passwd + strlen(passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; + l = final[11] ; to64(p,l,2); p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final,0,sizeof final); + + return passwd; +} + diff --git a/packages/clib/memfile.c b/packages/clib/memfile.c new file mode 100644 index 000000000..9535c27bc --- /dev/null +++ b/packages/clib/memfile.c @@ -0,0 +1,515 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include "error.h" + +#define streq(s,q) (strcmp((s), (q)) == 0) + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Memory-files + +make_memory_file(-Handle) +free_memory_file(+Handle) +open_memory_file(+Handle, +Mode, -Stream) +size_memory_file(+Handle, -Size) +memory_file_to_codes(+Handle, -Codes) +memory_file_to_atom(+Handle, -Atom) +atom_to_memory_file(+Atom, -Handle) +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static functor_t FUNCTOR_memory_file1; +static atom_t ATOM_encoding; +static atom_t ATOM_unknown; +static atom_t ATOM_octet; +static atom_t ATOM_ascii; +static atom_t ATOM_iso_latin_1; +static atom_t ATOM_text; +static atom_t ATOM_utf8; +static atom_t ATOM_unicode_be; +static atom_t ATOM_unicode_le; +static atom_t ATOM_wchar_t; +static atom_t ATOM_read; +static atom_t ATOM_write; +static atom_t ATOM_free_on_close; + +#define MEMFILE_MAGIC 0x5624a6b3L +#define NOSIZE ((size_t)-1) + +typedef struct +{ long magic; /* MEMFILE_MAGIC */ + IOENC encoding; /* encoding of the data */ + int free_on_close; /* free if it is closed */ + char *data; /* data of the file */ + size_t data_size; /* byte-size of data */ + size_t size; /* size in characters */ + IOSTREAM *stream; /* Stream hanging onto it */ + atom_t atom; /* Created from atom */ +} memfile; + + +static int +unify_memfile(term_t handle, memfile *f) +{ return PL_unify_term(handle, + PL_FUNCTOR, FUNCTOR_memory_file1, + PL_POINTER, f); +} + + +static int +get_memfile(term_t handle, memfile **f) +{ if ( PL_is_functor(handle, FUNCTOR_memory_file1) ) + { term_t a = PL_new_term_ref(); + void *ptr; + + _PL_get_arg(1, handle, a); + if ( PL_get_pointer(a, &ptr) ) + { memfile *m = ptr; + + if ( m->magic == MEMFILE_MAGIC ) + { *f = ptr; + return TRUE; + } + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, + "memory_file", handle); + } + } + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + handle, "memory_file"); +} + + +static foreign_t +new_memory_file(term_t handle) +{ memfile *m = calloc(1, sizeof(*m)); + + if ( !m ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, + "create", "memory_file", handle); + + m->magic = MEMFILE_MAGIC; + m->encoding = ENC_UTF8; + m->data = 0; + m->size = 0; + + if ( unify_memfile(handle, m) ) + return TRUE; + + m->magic = 0; + free(m); + return FALSE; +} + + +static int +destroy_memory_file(memfile *m) +{ if ( m->stream ) + Sclose(m->stream); + if ( m->atom ) + PL_unregister_atom(m->atom); + else if ( m->data ) + Sfree(m->data); /* MS-Windows: malloc by other DLL! */ + m->magic = 0; + free(m); + + return TRUE; +} + + +static foreign_t +free_memory_file(term_t handle) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + return destroy_memory_file(m); + + return FALSE; +} + + +static void +closehook(void *closure) +{ memfile *m = closure; + + m->stream = NULL; + if ( m->free_on_close ) + destroy_memory_file(m); +} + + +static foreign_t +alreadyOpen(term_t handle, const char *op) +{ return pl_error(NULL, 0, "already open", + ERR_PERMISSION, handle, op, "memory_file"); +} + + +static struct encname +{ IOENC code; + atom_t *name; +} encoding_names[] = +{ { ENC_UNKNOWN, &ATOM_unknown }, + { ENC_OCTET, &ATOM_octet }, + { ENC_ASCII, &ATOM_ascii }, + { ENC_ISO_LATIN_1, &ATOM_iso_latin_1 }, + { ENC_ANSI, &ATOM_text }, + { ENC_UTF8, &ATOM_utf8 }, + { ENC_UNICODE_BE, &ATOM_unicode_be }, + { ENC_UNICODE_LE, &ATOM_unicode_le }, + { ENC_WCHAR, &ATOM_wchar_t }, + { ENC_UNKNOWN, NULL }, +}; + + +IOENC +atom_to_encoding(atom_t a) +{ struct encname *en; + + for(en=encoding_names; en->name; en++) + { if ( *en->name == a ) + return en->code; + } + + return ENC_UNKNOWN; +} + + +static int +get_encoding(term_t t, IOENC *enc) +{ atom_t en; + + if ( PL_get_atom(t, &en) ) + { IOENC encoding; + + if ( (encoding = atom_to_encoding(en)) == ENC_UNKNOWN ) + return pl_error(NULL, 0, NULL, ERR_DOMAIN, t, "encoding"); + + *enc = encoding; + return TRUE; + } + + return pl_error(NULL, 0, NULL, ERR_TYPE, t, "encoding"); +} + + +static foreign_t +open_memory_file4(term_t handle, term_t mode, term_t stream, term_t options) +{ memfile *m; + char *x; + atom_t iom; + IOSTREAM *fd; + IOENC encoding; + int free_on_close = FALSE; + + if ( !get_memfile(handle, &m) ) + return FALSE; + if ( m->stream ) + return alreadyOpen(handle, "open"); + if ( !PL_get_atom(mode, &iom) ) + return pl_error("open_memory_file", 3, NULL, ERR_ARGTYPE, 2, + mode, "io_mode"); + encoding = m->encoding; + + if ( options ) + { term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + { int arity; + atom_t name; + + if ( PL_get_name_arity(head, &name, &arity) && arity == 1 ) + { term_t arg = PL_new_term_ref(); + + _PL_get_arg(1, head, arg); + if ( name == ATOM_encoding ) + { if ( !get_encoding(arg, &encoding) ) + return FALSE; + } else if ( name == ATOM_free_on_close ) + { if ( !PL_get_bool(arg, &free_on_close) ) + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, + arg, "boolean"); + } + } else + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, head, "option"); + } + if ( !PL_get_nil(tail) ) + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, tail, "list"); + } + + if ( iom == ATOM_write ) + { x = "w"; + if ( m->atom ) + return pl_error("open_memory_file", 3, NULL, ERR_PERMISSION, + handle, "write", "memory_file"); + if ( m->data ) + { Sfree(m->data); + m->data = NULL; + } + m->data_size = 0; + m->size = NOSIZE; /* don't know */ + m->encoding = encoding; + } else if ( iom == ATOM_read ) + { x = "r"; + m->free_on_close = free_on_close; + } else + { return pl_error("open_memory_file", 3, NULL, ERR_DOMAIN, + mode, "io_mode"); + } + + if ( !(fd = Sopenmem(&m->data, &m->data_size, x)) ) + return pl_error("open_memory_file", 3, NULL, ERR_ERRNO, errno, + "create", "memory_file", handle); + + fd->close_hook = closehook; + fd->closure = m; + fd->encoding = encoding; + m->stream = fd; + + return PL_unify_stream(stream, fd); +} + + +static foreign_t +open_memory_file(term_t handle, term_t mode, term_t stream) +{ return open_memory_file4(handle, mode, stream, 0); +} + + + +static foreign_t +size_memory_file(term_t handle, term_t size) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + { if ( m->stream && !m->atom ) + return alreadyOpen(handle, "size"); + if ( m->data ) + { if ( m->size == NOSIZE ) + { switch( m->encoding ) + { case ENC_ISO_LATIN_1: + case ENC_OCTET: + m->size = m->data_size; + break; + case ENC_WCHAR: + m->size = m->data_size / sizeof(wchar_t); + break; + case ENC_UTF8: + m->size = PL_utf8_strlen(m->data, m->data_size); + break; + default: + assert(0); + return FALSE; + } + } + return PL_unify_integer(size, m->size); + } else + return PL_unify_integer(size, 0); + } + + return FALSE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +utf8_position_memory_file(+MF, -Here, -Size) + +Given MF is a UTF-8 encoded memory file, unify here with the +byte-position of the read-pointer and Size with the total size of the +memory file in bytes. This is a bit hacky predicate, but the information +is easily available at low cost, while it is very valuable for producing +answers in content-length computation of the HTTP server. See +http_wrapper.pl +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static foreign_t +utf8_position(term_t handle, term_t here, term_t size) +{ memfile *m; + + if ( !get_memfile(handle, &m) ) + return FALSE; + if ( m->encoding != ENC_UTF8 ) + return pl_error(NULL, 0, "no UTF-8 encoding", + ERR_PERMISSION, handle, "utf8_position", "memory_file"); + if ( !PL_unify_integer(size, m->data_size) ) + return FALSE; + if ( m->stream ) + { IOPOS *op = m->stream->position; + long p; + + m->stream->position = NULL; + p = Stell(m->stream); + m->stream->position = op; + + return PL_unify_integer(here, p); + } else + return PL_unify_integer(here, 0); +} + + +static foreign_t +atom_to_memory_file(term_t atom, term_t handle) +{ atom_t a; + + if ( PL_get_atom(atom, &a) ) + { memfile *m = calloc(1, sizeof(*m)); + + if ( !m ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "create", "memory_file", handle); + + m->atom = a; + PL_register_atom(m->atom); + m->magic = MEMFILE_MAGIC; + + if ( (m->data = (char *)PL_atom_nchars(a, &m->size)) ) + { m->encoding = ENC_ISO_LATIN_1; + m->data_size = m->size; + } else if ( (m->data = (char *)PL_atom_wchars(a, &m->size)) ) + { m->encoding = ENC_WCHAR; + m->data_size = m->size * sizeof(wchar_t); + } else if ( PL_blob_data(a, &m->size, NULL) ) + { m->data = PL_blob_data(a, &m->data_size, NULL); + m->encoding = ENC_OCTET; + m->size = m->data_size; + } + + if ( unify_memfile(handle, m) ) + return TRUE; + else + { PL_unregister_atom(m->atom); + m->magic = 0; + free(m); + return FALSE; + } + } else + { return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + atom, "atom"); + } +} + + +static foreign_t +memory_file_to_text(term_t handle, term_t atom, term_t encoding, int flags) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + { IOENC enc; + + if ( encoding ) + { if ( !get_encoding(encoding, &enc) ) + return FALSE; + } else + enc = m->encoding; + + if ( m->stream ) + return alreadyOpen(handle, "to_atom"); + if ( m->data ) + { switch(enc) + { case ENC_ISO_LATIN_1: + case ENC_OCTET: + return PL_unify_chars(atom, flags, m->data_size, m->data); + case ENC_WCHAR: + return PL_unify_wchars(atom, flags, m->data_size/sizeof(wchar_t), (pl_wchar_t*)m->data); + case ENC_UTF8: + return PL_unify_chars(atom, flags|REP_UTF8, m->data_size, m->data); + default: + assert(0); + } + } else + return PL_unify_chars(atom, flags, 0, ""); + } + + return FALSE; +} + + +static foreign_t +memory_file_to_atom2(term_t handle, term_t atom) +{ return memory_file_to_text(handle, atom, 0, PL_ATOM); +} + + +static foreign_t +memory_file_to_atom3(term_t handle, term_t atom, term_t encoding) +{ return memory_file_to_text(handle, atom, encoding, PL_ATOM); +} + + +static foreign_t +memory_file_to_codes2(term_t handle, term_t atom) +{ return memory_file_to_text(handle, atom, 0, PL_CODE_LIST); +} + + +static foreign_t +memory_file_to_codes3(term_t handle, term_t atom, term_t encoding) +{ return memory_file_to_text(handle, atom, encoding, PL_CODE_LIST); +} + + +#define MKATOM(n) ATOM_ ## n = PL_new_atom(#n); + +install_t +install_memfile() +{ +#if !_YAP_NOT_INSTALLED_ +if ( PL_query(PL_QUERY_VERSION) <= 50505 ) + { PL_warning("Requires SWI-Prolog version 5.5.6 or later"); + return; + } +#endif + + FUNCTOR_memory_file1 = PL_new_functor(PL_new_atom("$memory_file"), 1); + MKATOM(encoding); + MKATOM(unknown); + MKATOM(octet); + MKATOM(ascii); + MKATOM(iso_latin_1); + MKATOM(text); + MKATOM(utf8); + MKATOM(unicode_be); + MKATOM(unicode_le); + MKATOM(wchar_t); + MKATOM(read); + MKATOM(write); + MKATOM(free_on_close); + + PL_register_foreign("new_memory_file", 1, new_memory_file, 0); + PL_register_foreign("free_memory_file", 1, free_memory_file, 0); + PL_register_foreign("size_memory_file", 2, size_memory_file, 0); + PL_register_foreign("open_memory_file", 3, open_memory_file, 0); + PL_register_foreign("open_memory_file", 4, open_memory_file4, 0); + PL_register_foreign("atom_to_memory_file", 2, atom_to_memory_file, 0); + PL_register_foreign("memory_file_to_atom", 2, memory_file_to_atom2, 0); + PL_register_foreign("memory_file_to_codes", 2, memory_file_to_codes2,0); + PL_register_foreign("memory_file_to_atom", 3, memory_file_to_atom3, 0); + PL_register_foreign("memory_file_to_codes", 3, memory_file_to_codes3,0); + PL_register_foreign("utf8_position_memory_file", 3, utf8_position, 0); +} diff --git a/packages/clib/memfile.c~ b/packages/clib/memfile.c~ new file mode 100644 index 000000000..54766160a --- /dev/null +++ b/packages/clib/memfile.c~ @@ -0,0 +1,512 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include "error.h" + +#define streq(s,q) (strcmp((s), (q)) == 0) + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Memory-files + +make_memory_file(-Handle) +free_memory_file(+Handle) +open_memory_file(+Handle, +Mode, -Stream) +size_memory_file(+Handle, -Size) +memory_file_to_codes(+Handle, -Codes) +memory_file_to_atom(+Handle, -Atom) +atom_to_memory_file(+Atom, -Handle) +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static functor_t FUNCTOR_memory_file1; +static atom_t ATOM_encoding; +static atom_t ATOM_unknown; +static atom_t ATOM_octet; +static atom_t ATOM_ascii; +static atom_t ATOM_iso_latin_1; +static atom_t ATOM_text; +static atom_t ATOM_utf8; +static atom_t ATOM_unicode_be; +static atom_t ATOM_unicode_le; +static atom_t ATOM_wchar_t; +static atom_t ATOM_read; +static atom_t ATOM_write; +static atom_t ATOM_free_on_close; + +#define MEMFILE_MAGIC 0x5624a6b3L +#define NOSIZE ((size_t)-1) + +typedef struct +{ long magic; /* MEMFILE_MAGIC */ + IOENC encoding; /* encoding of the data */ + int free_on_close; /* free if it is closed */ + char *data; /* data of the file */ + size_t data_size; /* byte-size of data */ + size_t size; /* size in characters */ + IOSTREAM *stream; /* Stream hanging onto it */ + atom_t atom; /* Created from atom */ +} memfile; + + +static int +unify_memfile(term_t handle, memfile *f) +{ return PL_unify_term(handle, + PL_FUNCTOR, FUNCTOR_memory_file1, + PL_POINTER, f); +} + + +static int +get_memfile(term_t handle, memfile **f) +{ if ( PL_is_functor(handle, FUNCTOR_memory_file1) ) + { term_t a = PL_new_term_ref(); + void *ptr; + + _PL_get_arg(1, handle, a); + if ( PL_get_pointer(a, &ptr) ) + { memfile *m = ptr; + + if ( m->magic == MEMFILE_MAGIC ) + { *f = ptr; + return TRUE; + } + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, + "memory_file", handle); + } + } + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + handle, "memory_file"); +} + + +static foreign_t +new_memory_file(term_t handle) +{ memfile *m = calloc(1, sizeof(*m)); + + if ( !m ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, + "create", "memory_file", handle); + + m->magic = MEMFILE_MAGIC; + m->encoding = ENC_UTF8; + m->data = 0; + m->size = 0; + + if ( unify_memfile(handle, m) ) + return TRUE; + + m->magic = 0; + free(m); + return FALSE; +} + + +static int +destroy_memory_file(memfile *m) +{ if ( m->stream ) + Sclose(m->stream); + if ( m->atom ) + PL_unregister_atom(m->atom); + else if ( m->data ) + Sfree(m->data); /* MS-Windows: malloc by other DLL! */ + m->magic = 0; + free(m); + + return TRUE; +} + + +static foreign_t +free_memory_file(term_t handle) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + return destroy_memory_file(m); + + return FALSE; +} + + +static void +closehook(void *closure) +{ memfile *m = closure; + + m->stream = NULL; + if ( m->free_on_close ) + destroy_memory_file(m); +} + + +static foreign_t +alreadyOpen(term_t handle, const char *op) +{ return pl_error(NULL, 0, "already open", + ERR_PERMISSION, handle, op, "memory_file"); +} + + +static struct encname +{ IOENC code; + atom_t *name; +} encoding_names[] = +{ { ENC_UNKNOWN, &ATOM_unknown }, + { ENC_OCTET, &ATOM_octet }, + { ENC_ASCII, &ATOM_ascii }, + { ENC_ISO_LATIN_1, &ATOM_iso_latin_1 }, + { ENC_ANSI, &ATOM_text }, + { ENC_UTF8, &ATOM_utf8 }, + { ENC_UNICODE_BE, &ATOM_unicode_be }, + { ENC_UNICODE_LE, &ATOM_unicode_le }, + { ENC_WCHAR, &ATOM_wchar_t }, + { ENC_UNKNOWN, NULL }, +}; + + +IOENC +atom_to_encoding(atom_t a) +{ struct encname *en; + + for(en=encoding_names; en->name; en++) + { if ( *en->name == a ) + return en->code; + } + + return ENC_UNKNOWN; +} + + +static int +get_encoding(term_t t, IOENC *enc) +{ atom_t en; + + if ( PL_get_atom(t, &en) ) + { IOENC encoding; + + if ( (encoding = atom_to_encoding(en)) == ENC_UNKNOWN ) + return pl_error(NULL, 0, NULL, ERR_DOMAIN, t, "encoding"); + + *enc = encoding; + return TRUE; + } + + return pl_error(NULL, 0, NULL, ERR_TYPE, t, "encoding"); +} + + +static foreign_t +open_memory_file4(term_t handle, term_t mode, term_t stream, term_t options) +{ memfile *m; + char *x; + atom_t iom; + IOSTREAM *fd; + IOENC encoding; + int free_on_close = FALSE; + + if ( !get_memfile(handle, &m) ) + return FALSE; + if ( m->stream ) + return alreadyOpen(handle, "open"); + if ( !PL_get_atom(mode, &iom) ) + return pl_error("open_memory_file", 3, NULL, ERR_ARGTYPE, 2, + mode, "io_mode"); + encoding = m->encoding; + + if ( options ) + { term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + { int arity; + atom_t name; + + if ( PL_get_name_arity(head, &name, &arity) && arity == 1 ) + { term_t arg = PL_new_term_ref(); + + _PL_get_arg(1, head, arg); + if ( name == ATOM_encoding ) + { if ( !get_encoding(arg, &encoding) ) + return FALSE; + } else if ( name == ATOM_free_on_close ) + { if ( !PL_get_bool(arg, &free_on_close) ) + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, + arg, "boolean"); + } + } else + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, head, "option"); + } + if ( !PL_get_nil(tail) ) + return pl_error("open_memory_file", 4, NULL, ERR_TYPE, tail, "list"); + } + + if ( iom == ATOM_write ) + { x = "w"; + if ( m->atom ) + return pl_error("open_memory_file", 3, NULL, ERR_PERMISSION, + handle, "write", "memory_file"); + if ( m->data ) + { Sfree(m->data); + m->data = NULL; + } + m->data_size = 0; + m->size = NOSIZE; /* don't know */ + m->encoding = encoding; + } else if ( iom == ATOM_read ) + { x = "r"; + m->free_on_close = free_on_close; + } else + { return pl_error("open_memory_file", 3, NULL, ERR_DOMAIN, + mode, "io_mode"); + } + + if ( !(fd = Sopenmem(&m->data, &m->data_size, x)) ) + return pl_error("open_memory_file", 3, NULL, ERR_ERRNO, errno, + "create", "memory_file", handle); + + fd->close_hook = closehook; + fd->closure = m; + fd->encoding = encoding; + m->stream = fd; + + return PL_unify_stream(stream, fd); +} + + +static foreign_t +open_memory_file(term_t handle, term_t mode, term_t stream) +{ return open_memory_file4(handle, mode, stream, 0); +} + + + +static foreign_t +size_memory_file(term_t handle, term_t size) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + { if ( m->stream && !m->atom ) + return alreadyOpen(handle, "size"); + if ( m->data ) + { if ( m->size == NOSIZE ) + { switch( m->encoding ) + { case ENC_ISO_LATIN_1: + case ENC_OCTET: + m->size = m->data_size; + break; + case ENC_WCHAR: + m->size = m->data_size / sizeof(wchar_t); + break; + case ENC_UTF8: + m->size = PL_utf8_strlen(m->data, m->data_size); + break; + default: + assert(0); + return FALSE; + } + } + return PL_unify_integer(size, m->size); + } else + return PL_unify_integer(size, 0); + } + + return FALSE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +utf8_position_memory_file(+MF, -Here, -Size) + +Given MF is a UTF-8 encoded memory file, unify here with the +byte-position of the read-pointer and Size with the total size of the +memory file in bytes. This is a bit hacky predicate, but the information +is easily available at low cost, while it is very valuable for producing +answers in content-length computation of the HTTP server. See +http_wrapper.pl +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static foreign_t +utf8_position(term_t handle, term_t here, term_t size) +{ memfile *m; + + if ( !get_memfile(handle, &m) ) + return FALSE; + if ( m->encoding != ENC_UTF8 ) + return pl_error(NULL, 0, "no UTF-8 encoding", + ERR_PERMISSION, handle, "utf8_position", "memory_file"); + if ( !PL_unify_integer(size, m->data_size) ) + return FALSE; + if ( m->stream ) + { IOPOS *op = m->stream->position; + long p; + + m->stream->position = NULL; + p = Stell(m->stream); + m->stream->position = op; + + return PL_unify_integer(here, p); + } else + return PL_unify_integer(here, 0); +} + + +static foreign_t +atom_to_memory_file(term_t atom, term_t handle) +{ atom_t a; + + if ( PL_get_atom(atom, &a) ) + { memfile *m = calloc(1, sizeof(*m)); + + if ( !m ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "create", "memory_file", handle); + + m->atom = a; + PL_register_atom(m->atom); + m->magic = MEMFILE_MAGIC; + + if ( (m->data = (char *)PL_atom_nchars(a, &m->size)) ) + { m->encoding = ENC_ISO_LATIN_1; + m->data_size = m->size; + } else if ( (m->data = (char *)PL_atom_wchars(a, &m->size)) ) + { m->encoding = ENC_WCHAR; + m->data_size = m->size * sizeof(wchar_t); + } else if ( PL_blob_data(a, &m->size, NULL) ) + { m->data = PL_blob_data(a, &m->data_size, NULL); + m->encoding = ENC_OCTET; + m->size = m->data_size; + } + + if ( unify_memfile(handle, m) ) + return TRUE; + else + { PL_unregister_atom(m->atom); + m->magic = 0; + free(m); + return FALSE; + } + } else + { return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + atom, "atom"); + } +} + + +static foreign_t +memory_file_to_text(term_t handle, term_t atom, term_t encoding, int flags) +{ memfile *m; + + if ( get_memfile(handle, &m) ) + { IOENC enc; + + if ( encoding ) + { if ( !get_encoding(encoding, &enc) ) + return FALSE; + } else + enc = m->encoding; + + if ( m->stream ) + return alreadyOpen(handle, "to_atom"); + if ( m->data ) + { switch(enc) + { case ENC_ISO_LATIN_1: + case ENC_OCTET: + return PL_unify_chars(atom, flags, m->data_size, m->data); + case ENC_WCHAR: + return PL_unify_wchars(atom, flags, m->data_size/sizeof(wchar_t), (pl_wchar_t*)m->data); + case ENC_UTF8: + return PL_unify_chars(atom, flags|REP_UTF8, m->data_size, m->data); + default: + assert(0); + } + } else + return PL_unify_chars(atom, flags, 0, ""); + } + + return FALSE; +} + + +static foreign_t +memory_file_to_atom2(term_t handle, term_t atom) +{ return memory_file_to_text(handle, atom, 0, PL_ATOM); +} + + +static foreign_t +memory_file_to_atom3(term_t handle, term_t atom, term_t encoding) +{ return memory_file_to_text(handle, atom, encoding, PL_ATOM); +} + + +static foreign_t +memory_file_to_codes2(term_t handle, term_t atom) +{ return memory_file_to_text(handle, atom, 0, PL_CODE_LIST); +} + + +static foreign_t +memory_file_to_codes3(term_t handle, term_t atom, term_t encoding) +{ return memory_file_to_text(handle, atom, encoding, PL_CODE_LIST); +} + + +#define MKATOM(n) ATOM_ ## n = PL_new_atom(#n); + +install_t +install_memfile() +{ if ( PL_query(PL_QUERY_VERSION) <= 50505 ) + { PL_warning("Requires SWI-Prolog version 5.5.6 or later"); + return; + } + + FUNCTOR_memory_file1 = PL_new_functor(PL_new_atom("$memory_file"), 1); + MKATOM(encoding); + MKATOM(unknown); + MKATOM(octet); + MKATOM(ascii); + MKATOM(iso_latin_1); + MKATOM(text); + MKATOM(utf8); + MKATOM(unicode_be); + MKATOM(unicode_le); + MKATOM(wchar_t); + MKATOM(read); + MKATOM(write); + MKATOM(free_on_close); + + PL_register_foreign("new_memory_file", 1, new_memory_file, 0); + PL_register_foreign("free_memory_file", 1, free_memory_file, 0); + PL_register_foreign("size_memory_file", 2, size_memory_file, 0); + PL_register_foreign("open_memory_file", 3, open_memory_file, 0); + PL_register_foreign("open_memory_file", 4, open_memory_file4, 0); + PL_register_foreign("atom_to_memory_file", 2, atom_to_memory_file, 0); + PL_register_foreign("memory_file_to_atom", 2, memory_file_to_atom2, 0); + PL_register_foreign("memory_file_to_codes", 2, memory_file_to_codes2,0); + PL_register_foreign("memory_file_to_atom", 3, memory_file_to_atom3, 0); + PL_register_foreign("memory_file_to_codes", 3, memory_file_to_codes3,0); + PL_register_foreign("utf8_position_memory_file", 3, utf8_position, 0); +} diff --git a/packages/clib/memfile.pl b/packages/clib/memfile.pl new file mode 100644 index 000000000..fa697a382 --- /dev/null +++ b/packages/clib/memfile.pl @@ -0,0 +1,45 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(memory_file, + [ new_memory_file/1, % -Handle + free_memory_file/1, % +Handle + size_memory_file/2, % +Handle, -Size + open_memory_file/3, % +Handle, +Mode, -Stream + open_memory_file/4, % +Handle, +Mode, -Stream, +Options + atom_to_memory_file/2, % +Atom, -Handle + memory_file_to_atom/2, % +Handle, -Atom + memory_file_to_codes/2, % +Handle, -CodeList + memory_file_to_atom/3, % +Handle, -Atom, +Encoding + memory_file_to_codes/3, % +Handle, -CodeList, +Encoding + utf8_position_memory_file/3 % +Handle, -Here, -Size + ]). +:- use_foreign_library(foreign(memfile)). diff --git a/packages/clib/mime.c b/packages/clib/mime.c new file mode 100644 index 000000000..9b86b648b --- /dev/null +++ b/packages/clib/mime.c @@ -0,0 +1,391 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2005, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef __WINDOWS__ +#define HAVE_MALLOC_H 1 +#endif + +#include +#include +#include +#include "error.h" +#ifdef HAVE_MALLOC_H +#include +#endif +#include + +#undef max /* be sure we have ours */ +#define max(x, y) ((x)>(y) ? (x) : (y)) + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +This module defines an interface to the rfc2045 (MIME) parsing library +by Double Precision, Inc, part of the maildrop system. + +Parsing MIME messages is accomplished using a single predicate. This +predicate parses the input and returns a complex term holding the +various MIME message parts. The mime message is encoded into the +following structure: + + mime(Attributes, Data, SubMimeList) + +Where Data is the (decoded) field data returned as an atom, Attributes +is a property-list and SubMimeList is a list of mime/3 terms reflecting +the sub-parts. Attributes contains the following members: + + # id(Atom) + # description(Atom) + # language(Atom) + # md5(Atom) + # type(Atom) + # character_set(Atom) + # transfer_encoding(Atom) + # disposition(Atom) + # filename(Atom) + # name(Atom) +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static atom_t ATOM_; +static atom_t ATOM_stream; +static functor_t FUNCTOR_type1; +static functor_t FUNCTOR_transfer_encoding1; +static functor_t FUNCTOR_character_set1; +static functor_t FUNCTOR_mime3; +static functor_t FUNCTOR_id1; +static functor_t FUNCTOR_description1; +static functor_t FUNCTOR_language1; +static functor_t FUNCTOR_md51; +static functor_t FUNCTOR_disposition1; +static functor_t FUNCTOR_name1; +static functor_t FUNCTOR_filename1; + +struct dbuf +{ char *buf; + int size; + int allocated; +}; + +static int +add_data(const char *ndata, size_t len, void *closure) +{ struct dbuf *dbuf = closure; + + if ( dbuf->size + (int)len > dbuf->allocated ) + { dbuf->allocated = max(dbuf->allocated, max(1024, dbuf->size + (int)len)); + if ( dbuf->buf ) + dbuf->buf = realloc(dbuf->buf, dbuf->allocated); + else + dbuf->buf = malloc(dbuf->allocated); + + if ( !dbuf->buf ) + { pl_error("mime_parse", 3, NULL, ERR_ERRNO, errno, "add_data", "mime", 0); + return -1; + } + } + + memcpy(dbuf->buf+dbuf->size, ndata, len); + dbuf->size += len; + + return 0; +} + + + +static int +mime_unify_data(term_t data, struct rfc2045 *rfc, const char *buffer) +{ off_t start_pos, end_pos, start_body, nlines, nbodylines; + struct dbuf dbuf; + int rval; + + dbuf.buf = NULL; + dbuf.size = 0; + dbuf.allocated = 0; + + rfc2045_mimepos(rfc, + &start_pos, &end_pos, &start_body, &nlines, &nbodylines); + rfc2045_cdecode_start(rfc, add_data, &dbuf); + if ( rfc2045_cdecode(rfc, buffer+start_body, end_pos-start_body) == 0 && + rfc2045_cdecode_end(rfc) == 0 ) + { rval = PL_unify_atom_nchars(data, dbuf.size, dbuf.buf); + } else + rval = FALSE; + + if ( dbuf.buf ) + free(dbuf.buf); + + return rval; +} + + +/* add_attribute() adds a name(value) term to the list if value is provided + (i.e. not NULL and non "") +*/ + +static int +add_attribute(term_t list, const char *value, functor_t functor) +{ if ( value && value[0] ) + { term_t h = PL_new_term_ref(); + int rval; + + rval = PL_unify_list(list, h, list) && + PL_unify_term(h, PL_FUNCTOR, functor, PL_CHARS, value); + + PL_reset_term_refs(h); + return rval; + } + + return TRUE; +} + + +static int +mime_unify(term_t result, struct rfc2045 *rfc, const char *buffer) +{ term_t data = PL_new_term_ref(); + term_t subs = PL_new_term_ref(); + term_t atts = PL_new_term_ref(); + + if ( !PL_unify_term(result, + PL_FUNCTOR, FUNCTOR_mime3, + PL_TERM, atts, + PL_TERM, data, + PL_TERM, subs) ) + return FALSE; + + if ( rfc->isdummy ) + { if ( !PL_unify_nil(data) || + !PL_unify_nil(atts) ) + return FALSE; + } else + { term_t at = PL_copy_term_ref(atts); + const char *type, *enc, *cset; + const char *disp, *name, *fnam; + + const char *id = rfc2045_content_id(rfc); + const char *desc = rfc2045_content_description(rfc); + const char *lang = rfc2045_content_language(rfc); + const char *md5 = rfc2045_content_md5(rfc); + + rfc2045_mimeinfo(rfc, &type, &enc, &cset); + rfc2045_dispositioninfo(rfc, &disp, &name, &fnam); + + if ( !add_attribute(at, type, FUNCTOR_type1) ) return FALSE; + if ( !add_attribute(at, enc, FUNCTOR_transfer_encoding1) ) return FALSE; + if ( !add_attribute(at, cset, FUNCTOR_character_set1) ) return FALSE; + if ( !add_attribute(at, id, FUNCTOR_id1) ) return FALSE; + if ( !add_attribute(at, desc, FUNCTOR_description1) ) return FALSE; + if ( !add_attribute(at, lang, FUNCTOR_language1) ) return FALSE; + if ( !add_attribute(at, disp, FUNCTOR_disposition1) ) return FALSE; + if ( !add_attribute(at, name, FUNCTOR_name1) ) return FALSE; + if ( !add_attribute(at, fnam, FUNCTOR_filename1) ) return FALSE; + if ( !add_attribute(at, md5, FUNCTOR_md51) ) return FALSE; + + if ( !PL_unify_nil(at) ) + return FALSE; + } + + if ( rfc->firstpart ) + { term_t st = PL_copy_term_ref(subs); + term_t s = PL_new_term_ref(); + struct rfc2045 *sub; + + if ( !PL_unify_atom(data, ATOM_) ) + return FALSE; + + for(sub=rfc->firstpart; sub; sub = sub->next) + { if ( sub->isdummy ) + continue; + + if ( !PL_unify_list(st, s, st) || + !mime_unify(s, sub, buffer) ) + return FALSE; + } + return PL_unify_nil(st); + } else + { if ( !PL_unify_nil(subs) || + !mime_unify_data(data, rfc, buffer) ) + return FALSE; + } + + return TRUE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +get_character_data() + Get a buffer of data from a specification. Currently the following + specs are acceptable: + + stream(Stream) All data from this stream + stream(Stream, N) At most N characters from stream + Atom, String, CodeList Data from native Prolog character data +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static int +get_character_data(term_t from, char **data, size_t *len, int *malloced) +{ atom_t name; + int arity; + char *buf; + size_t size; + + if ( PL_get_name_arity(from, &name, &arity) && arity > 0 ) + { if ( name == ATOM_stream ) + { IOSTREAM *stream; + term_t arg = PL_new_term_ref(); + + _PL_get_arg(1, from, arg); + if ( !PL_get_stream_handle(arg, &stream) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, from, "stream"); + + if ( arity == 1 ) /* stream(Stream) */ + { int c; + size_t done, allocated = 1024; + + if ( !(buf = malloc(allocated)) ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "allocate", "memory", 0); + + for( done=0; (c=Sgetcode(stream)) != EOF; ) + { if ( done >= allocated ) + { allocated *= 2; + + if ( !(buf = realloc(buf, allocated)) ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "allocate", "memory", 0); + } + + buf[done++] = c; + } + + *len = done; + *data = buf; + *malloced = TRUE; + + return TRUE; + } else if ( arity == 2 ) /* stream(Stream, Length) */ + { long size; + long done; + int c; + + _PL_get_arg(2, from, arg); + if ( !PL_get_long(arg, &size) || size < 0 ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, arg, "natural"); + + if ( !(buf = malloc(size)) ) + return pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "allocate", "memory", 0); + + for( done=0; (c=Sgetcode(stream)) != EOF && done < size; ) + buf[done++] = c; + + *len = done; + *data = buf; + *malloced = TRUE; + + return TRUE; + } + } + } else if ( PL_get_nchars(from, &size, data, CVT_ATOM|CVT_STRING|CVT_LIST) ) + { *len = size; + *malloced = FALSE; + + return TRUE; + } + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, from, "data"); +} + + + +foreign_t +mime_parse(term_t handle, term_t result) +{ char *buf; + size_t len = 0; + int malloced = FALSE; + struct rfc2045 *rfc; + int rval; + + if ( !get_character_data(handle, &buf, &len, &malloced) ) + return FALSE; + + rfc = rfc2045_alloc(); + rfc2045_parse(rfc, buf, len); + rval = mime_unify(result, rfc, buf); + + if ( malloced ) + free(buf); + rfc2045_free(rfc); + + return rval; +} + + /******************************* + * ERRORS * + *******************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Not typically elegant, but the documentation whishes us to call exit(), +which is even worse. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +void +rfc2045_error(const char *errmsg) +{ term_t e = PL_new_term_ref(); + + if ( (e=PL_new_term_ref()) && + PL_unify_term(e, + PL_FUNCTOR_CHARS, "error", 2, + PL_FUNCTOR_CHARS, "mime", 1, + PL_CHARS, errmsg, + PL_VARIABLE) ) + PL_throw(e); + + PL_fatal_error("Could not recover from rfc2045 error"); +} + + /******************************* + * INSTALL * + *******************************/ + +#define mkfunctor(n, a) PL_new_functor(PL_new_atom(n), a) + + +install_t +install_mime() +{ ATOM_ = PL_new_atom(""); + ATOM_stream = PL_new_atom("stream"); + + FUNCTOR_type1 = mkfunctor("type", 1); + FUNCTOR_transfer_encoding1 = mkfunctor("transfer_encoding", 1); + FUNCTOR_character_set1 = mkfunctor("character_set", 1); + FUNCTOR_mime3 = mkfunctor("mime", 3); + FUNCTOR_id1 = mkfunctor("id", 1); + FUNCTOR_description1 = mkfunctor("description", 1); + FUNCTOR_language1 = mkfunctor("language", 1); + FUNCTOR_md51 = mkfunctor("md5", 1); + FUNCTOR_disposition1 = mkfunctor("disposition", 1); + FUNCTOR_name1 = mkfunctor("name", 1); + FUNCTOR_filename1 = mkfunctor("filename", 1); + + PL_register_foreign("mime_parse", 2, mime_parse, 0); +} diff --git a/packages/clib/mime.pl b/packages/clib/mime.pl new file mode 100644 index 000000000..1bab29993 --- /dev/null +++ b/packages/clib/mime.pl @@ -0,0 +1,67 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(mime, + [ mime_parse/2 % +Data, -Mime + ]). +:- use_module(library(shlib)). + +:- use_foreign_library(foreign(mime), install_mime). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +This module defines an interface to the rfc2045 (MIME) parsing library +by Double Precision, Inc, part of the maildrop system. This library is +distributed under the GPL and therefore all code using this library +should comply to the GPL. + +Parsing MIME messages is accomplished using a single predicate. This +predicate parses the input and returns a complex term holding the +various MIME message parts. The mime message is encoded into the +following structure: + + mime(Attributes, Data, SubMimeList) + +Where Data is the (decoded) field data returned as an atom, Attributes +is a property-list and SubMimeList is a list of mime/3 terms reflecting +the sub-parts. Attributes contains the following members: + + # id(Atom) + # description(Atom) + # language(Atom) + # md5(Atom) + # type(Atom) + # character_set(Atom) + # transfer_encoding(Atom) + # disposition(Atom) + # filename(Atom) + # name(Atom) +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + diff --git a/packages/clib/missing b/packages/clib/missing new file mode 100755 index 000000000..e7ef83a1c --- /dev/null +++ b/packages/clib/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2003-09-02.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/packages/clib/nonblockio.c b/packages/clib/nonblockio.c new file mode 100644 index 000000000..591dbe05d --- /dev/null +++ b/packages/clib/nonblockio.c @@ -0,0 +1,2396 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2007, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define O_DEBUG 1 + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +This module is extracted from socket.c to provide a common ground for +accessing sockets and possibly other devices in non-blocking mode, +allowing for GUI (XPCE) event dispatching, timeout handling and +multi-threaded signal and timeout handling. + +Besides dealing with nonblocking aspects, an important facet of this +library is to hide OS differences. + + +API +--- + +The API is completely the same as for blocking IO. It is however built +on top of sockets used in non-blocking mode which enables the layer to +listen to Prolog events such as timeouts, GUI processing and thread +interaction. The functions are modelled after the POSIX socket API, +prefixed with nbio_*: + + nbio_socket() + nbio_connect() + nbio_bind() + nbio_listen() + nbio_accept() + nbio_closesocket() + +and IO is realised using + + nbio_read() See also below + nbio_write() + +Overall control of the library: + + nbio_init() + nbio_cleanup() + nbio_debug() + +Error handling + + nbio_error() Raises a Prolog exception + +Settings + + nbio_setopt() + nbio_get_flags() + +Address Converstion + + nbio_get_sockaddr() + nbio_get_ip4() + +Waiting + + nbio_select() + +Alternative to nbio_read() and nbio_write(), the application program may +call the low-level I/O routines in non-blocking mode and call +nbio_wait(int socket, nbio_request request). This function returns 0 if +it thinks the call might now succeed and -1 if an error occurred, +leaving the exception context in Prolog. On receiving -1, the user must +return an I/O error as soon as possible. + + +Windows issues +-------------- + +Winsock is hard to handle in blocking mode without blocking the whole +lot, notably (timeout) signals. We therefore have a seperate thread +dealing with I/O and operating the sockets through WSAAsyncSelect() +generated events. Requests are registered with the plsocket structure, +handled and handled in the socket thread. Upon completion, a message is +sent back to the waiting thread. + +Unix issues +----------- + +In the Unix version we simply call PL_dispatch() before doing recv() and +leave the details to this function. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef __CYGWIN__ +#undef HAVE_H_ERRNO +#endif + +#include "nonblockio.h" + +#include +#include "clib.h" + +#include +#include +#include +#include +#include +#include +#ifdef __WINDOWS__ +#include +#endif + + +#ifndef __WINDOWS__ +#define closesocket(n) close((n)) /* same on Unix */ +#endif + +#ifndef SD_SEND +#define SD_RECEIVE 0 /* shutdown() parameters */ +#define SD_SEND 1 +#define SD_BOTH 2 +#endif + +#ifndef SOCKET_ERROR +#define SOCKET_ERROR (-1) +#endif + +#ifdef _REENTRANT +#if __WINDOWS__ +static CRITICAL_SECTION mutex; +static CRITICAL_SECTION mutex_free; + +#define LOCK() EnterCriticalSection(&mutex) +#define UNLOCK() LeaveCriticalSection(&mutex) +#define LOCK_FREE() EnterCriticalSection(&mutex_free) +#define UNLOCK_FREE() LeaveCriticalSection(&mutex_free) +#define INITLOCK() (InitializeCriticalSection(&mutex), \ + InitializeCriticalSection(&mutex_free)) +#else +#include + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +#define LOCK() pthread_mutex_lock(&mutex) +#define UNLOCK() pthread_mutex_unlock(&mutex) +#define LOCK_FREE() +#define UNLOCK_FREE() +#define INITLOCK() +#endif +#else +#define LOCK() +#define UNLOCK() +#define LOCK_FREE() +#define UNLOCK_FREE() +#define INITLOCK() +#endif + +#define set(s, f) ((s)->flags |= (f)) +#define clear(s, f) ((s)->flags &= ~(f)) +#define true(s, f) ((s)->flags & (f)) +#define false(s, f) (!true(s, f)) + +#define PLSOCK_MAGIC 0x38da3f2c + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +NOTE: We must lock the structure to avoid freeSocket() called from +Prolog deleting the socket while there are still pending events on it +that are concurrently executed in the socket thread. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +typedef struct _plsocket +{ int magic; /* PLSOCK_MAGIC */ + nbio_sock_t id; /* Integer id */ + SOCKET socket; /* The OS socket */ + int flags; /* Misc flags */ + IOSTREAM * input; /* input stream */ + IOSTREAM * output; /* output stream */ +#ifdef __WINDOWS__ + nbio_request request; /* our request */ + DWORD thread; /* waiting thread */ + DWORD error; /* error while executing request */ + int done; /* request completed */ + int w32_flags; /* or of received FD_* */ + union + { struct + { struct sockaddr_in addr; /* accepted address */ + int addrlen; /* address length */ + nbio_sock_t slave; /* descriptor of slave */ + } accept; + struct + { struct sockaddr_in addr; /* accepted address */ + size_t addrlen; /* address length */ + } connect; + struct + { int bytes; /* byte count */ + char *buffer; /* the buffer */ + size_t size; /* buffer size */ + } read; + struct + { int bytes; /* byte count */ + char *buffer; /* the buffer */ + size_t written; + size_t size; /* buffer size */ + } write; + struct + { int bytes; /* byte count */ + void *buffer; /* the buffer */ + size_t size; /* buffer size */ + int flags; + struct sockaddr *from; + socklen_t *fromlen; + } recvfrom; + struct + { int bytes; /* byte count */ + void *buffer; /* the buffer */ + int size; /* buffer size */ + int flags; + const struct sockaddr *to; + int tolen; + } sendto; + } rdata; +#endif +} plsocket; + +static plsocket *allocSocket(SOCKET socket); +#ifdef __WINDOWS__ +static plsocket *lookupOSSocket(SOCKET socket); +static const char *WinSockError(unsigned long eno); +#endif + +static int +need_retry(int error) +{ if ( error == EINTR || error == EAGAIN || error == EWOULDBLOCK ) + return TRUE; + + return FALSE; +} + +#ifdef O_DEBUG +static int debugging; + +NBIO_EXPORT(int) +nbio_debug(int level) +{ int old = debugging; + + if ( level >= 0 ) /* -1 --> return current setting */ + debugging = level; + + return old; +} + +#define DEBUG(l, g) if ( debugging >= l ) g +#else +#define DEBUG(l, g) (void)0 + +int +nbio_debug(int level) +{ return 0; +} + +#endif + +void /* allow debugger breakpoint */ +tcp_debug() +{ Sdprintf("Trapping debugger\n"); +} + + + /******************************* + * COMPATIBILITY * + *******************************/ + +#ifdef __WINDOWS__ +static UINT WM_SOCKET = WM_APP+20; +static UINT WM_REQUEST = WM_APP+21; +static UINT WM_READY = WM_APP+22; +static UINT WM_DONE = WM_APP+23; + +#if O_DEBUG +static char * +request_name(nbio_request request) +{ switch(request) + { case REQ_NONE: return "req_none"; + case REQ_ACCEPT: return "req_accept"; + case REQ_CONNECT: return "req_connect"; + case REQ_READ: return "req_read"; + case REQ_WRITE: return "req_write"; + case REQ_RECVFROM:return "req_recvfrom"; + case REQ_SENDTO: return "req_sendto"; + default: return "req_???"; + } +} + +static char * +event_name(int ev) +{ char buf[256]; + char *o = buf; + + o[0] = '\0'; + if ( (ev & FD_READ) ) strcat(o, "|FD_READ"); + if ( (ev & FD_WRITE) ) strcat(o, "|FD_WRITE"); + if ( (ev & FD_ACCEPT) ) strcat(o, "|FD_ACCEPT"); + if ( (ev & FD_CONNECT) ) strcat(o, "|FD_CONNECT"); + if ( (ev & FD_CLOSE) ) strcat(o, "|FD_CLOSE"); + if ( (ev & FD_OOB) ) strcat(o, "|FD_OOB"); + if ( (ev & ~(FD_READ|FD_WRITE|FD_ACCEPT|FD_CONNECT|FD_CLOSE)) ) + strcat(o, "|FD_???"); + + return strdup(buf); +} + +#endif + +#define F_SETFL 0 +#define O_NONBLOCK 0 + +static int +nbio_fcntl(nbio_sock_t socket, int op, int arg) +{ plsocket *s; + + if ( !(s=nbio_to_plsocket(socket)) ) + return -1; + + switch(op) + { case F_SETFL: + switch(arg) + { case O_NONBLOCK: + { int rval; + int non_block; + + non_block = 1; + rval = ioctlsocket(s->socket, FIONBIO, &non_block); + if ( rval ) + { s->flags |= PLSOCK_NONBLOCK; + return 0; + } + + return -1; + } + default: + return -1; + } + break; + default: + return -1; + } +} + +static HINSTANCE hinstance; /* hinstance */ + +typedef struct +{ HWND hwnd; /* our window */ + DWORD tid; /* thread id */ +} local_state; + +static local_state nbio_state; +#define State() (&nbio_state) + +static int +doneRequest(plsocket *s) +{ SOCKET sock; + + s->done = TRUE; + s->request = REQ_NONE; + + if ( (s->w32_flags & FD_CLOSE) && (sock=s->socket) >= 0 ) + { s->socket = -1; + closesocket(sock); + } + + if ( s->thread ) + { DEBUG(2, Sdprintf("doneRequest(): posting %d\n", s->thread)); + PostThreadMessage(s->thread, WM_DONE, 0, (WPARAM)s); + } + + return TRUE; +} + + +static int +waitRequest(plsocket *s) +{ assert(s->magic == PLSOCK_MAGIC); + + DEBUG(2, Sdprintf("[%d] (%ld): Waiting for %s on %d ...", + PL_thread_self(), s->thread, + request_name(s->request), (int)s->socket)); + + for(;;) + { MSG msg; + + if ( PL_handle_signals() < 0 ) + { DEBUG(1, Sdprintf("[%d]: Exception\n", PL_thread_self())); + return FALSE; + } + if ( s->done ) + { DEBUG(2, Sdprintf("[%d]: Done\n", PL_thread_self())); + return TRUE; + } + + if ( false(s, PLSOCK_DISPATCH) ) + { if ( !GetMessage(&msg, NULL, WM_DONE, WM_DONE) ) + return FALSE; + } else if ( GetMessage(&msg, NULL, 0, 0) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + } else + { ExitThread(0); /* WM_QUIT received */ + return FALSE; /* NOTREACHED */ + } + } +} + + +int +nbio_wait(nbio_sock_t socket, nbio_request request) +{ plsocket *s; + + if ( !(s=nbio_to_plsocket(socket)) ) + return -1; + + s->flags |= PLSOCK_WAITING; + s->done = FALSE; + s->error = 0; + s->thread = GetCurrentThreadId(); + s->request = request; + + SendMessage(State()->hwnd, WM_REQUEST, 1, (LPARAM)&s); + + DEBUG(2, Sdprintf("[%d] (%ld): Waiting ...", + PL_thread_self(), s->thread)); + + for(;;) + { MSG msg; + + if ( PL_handle_signals() < 0 ) + { DEBUG(1, Sdprintf("[%d]: Exception\n", PL_thread_self())); + return -1; + } + if ( s->done ) + { DEBUG(2, Sdprintf("[%d]: Done\n", PL_thread_self())); + return 0; + } + + if ( false(s, PLSOCK_DISPATCH) ) + { if ( !GetMessage(&msg, NULL, WM_DONE, WM_DONE) ) + return FALSE; + } else if ( GetMessage(&msg, NULL, 0, 0) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + } else + { ExitThread(0); /* WM_QUIT received */ + return -1; /* NOTREACHED */ + } + } +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +nbio_select() selects using a set of socket streams. + +NOTE: The Windows versions uses our nbio_sock_t abstraction, while the +other version uses the raw Unix file descriptors referencing the +underlying socket. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +int +nbio_select(int n, + fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ plsocket **sockets = alloca(n * sizeof(plsocket*)); + int i; + DWORD t_end; + + if ( !sockets ) + { errno = ENOMEM; + return -1; + } + for(i=0; iflags |= PLSOCK_WAITING; + s->done = FALSE; + s->error = 0; + s->thread = GetCurrentThreadId(); + s->request = (s->flags & PLSOCK_LISTEN) ? REQ_ACCEPT : REQ_READ; + sockets[i] = s; + } else + { DEBUG(2, Sdprintf("nbio_select(): no socket for %d\n", i)); + } + } + } + } + if ( writefds ) + return -1; /* not yet implemented */ + if ( exceptfds ) + return -1; /* idem (might never be) */ + + if ( timeout ) + { t_end = GetTickCount(); + t_end += timeout->tv_sec*1000; + t_end += timeout->tv_usec/1000; + } + + FD_ZERO(readfds); + SendMessage(State()->hwnd, WM_REQUEST, n, (LPARAM)sockets); + + for(;;) + { MSG msg; + plsocket **s; + int ready; + + if ( PL_handle_signals() < 0 ) + { DEBUG(1, Sdprintf("[%d]: Exception\n", PL_thread_self())); + return -1; + } + + for(ready=0, i=0, s=sockets; idone ) + { ready++; + FD_SET((unsigned)i, readfds); + } + } + if ( ready > 0 ) + return ready; + + if ( timeout ) + { DWORD rc; + DWORD t = GetTickCount(); + long msec = t_end - t; + + if ( msec < 0 ) + msec = -msec; /* wrapped around */ + + rc = MsgWaitForMultipleObjects(0, NULL, FALSE, msec, QS_ALLINPUT); + if ( rc == WAIT_OBJECT_0 ) + { if ( GetMessage(&msg, NULL, 0, 0) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + } else + { ExitThread(0); /* WM_QUIT received */ + return -1; /* NOTREACHED */ + } + } else if ( rc == WAIT_TIMEOUT ) + { return 0; + } else + { assert(0); + } + } else + { if ( GetMessage(&msg, NULL, 0, 0) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + } else + { ExitThread(0); /* WM_QUIT received */ + return -1; /* NOTREACHED */ + } + } + } +} + + +static int +placeRequest(plsocket *s, nbio_request request) +{ if ( s->magic != PLSOCK_MAGIC ) + Sdprintf("placeRequest: %p has bad magic\n", s); + + s->error = 0; + s->done = FALSE; + s->thread = GetCurrentThreadId(); + s->request = request; + clear(s, PLSOCK_WAITING); + + SendMessage(State()->hwnd, WM_REQUEST, 1, (LPARAM)&s); + DEBUG(2, Sdprintf("%d (%ld): Placed %s request for %d\n", + PL_thread_self(), s->thread, + request_name(request), (int)s->socket)); + + return TRUE; +} + +static int +doRequest(plsocket *s) +{ if ( s->magic != PLSOCK_MAGIC ) + Sdprintf("doRequest: %p has bad magic\n", s); + + switch(s->request) + { case REQ_NONE: + break; + case REQ_CONNECT: + if ( s->w32_flags & FD_CONNECT ) + { s->w32_flags &= ~FD_CONNECT; + + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + if ( connect(s->socket, + (struct sockaddr*)&s->rdata.connect.addr, + (int)s->rdata.connect.addrlen) ) + { s->error = WSAGetLastError(); + + switch(s->error) + { case WSAEWOULDBLOCK: + case WSAEINVAL: + case WSAEALREADY: + break; + case WSAEISCONN: + s->error = 0; + doneRequest(s); + break; + default: + doneRequest(s); + } + } else + { s->error = 0; + doneRequest(s); + } + } + break; + case REQ_ACCEPT: + if ( s->w32_flags & FD_ACCEPT ) + { SOCKET slave; + + s->w32_flags &= ~FD_ACCEPT; + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + slave = accept(s->socket, + (struct sockaddr*)&s->rdata.accept.addr, + &s->rdata.accept.addrlen); + + if ( slave == SOCKET_ERROR ) + { s->error = WSAGetLastError(); + + DEBUG(2, Sdprintf("Accept(%d): %s\n", + (int)s->socket, WinSockError(s->error))); + + if ( s->error != WSAEWOULDBLOCK ) + { s->rdata.accept.slave = (SOCKET)-1; + doneRequest(s); + } + } else + { plsocket *pls; + + DEBUG(2, Sdprintf("Accept(%d) --> %d\n", + (int)s->socket, (int)slave)); + if ( (pls = allocSocket(slave)) ) + { pls->flags |= PLSOCK_ACCEPT; /* requests */ + + s->rdata.accept.slave = pls->id; + s->error = 0; + doneRequest(s); + } else + { DEBUG(1, Sdprintf("Socket %d already registered; " + "considering bogus\n", (int)slave)); + } + } + } + break; + case REQ_READ: + if ( s->w32_flags & (FD_READ|FD_CLOSE) ) + { s->w32_flags &= ~FD_READ; + + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + s->rdata.read.bytes = recv(s->socket, + s->rdata.read.buffer, + (int)s->rdata.read.size, + 0); + if ( s->rdata.read.bytes < 0 ) + { s->error = WSAGetLastError(); + + if ( s->error != WSAEWOULDBLOCK ) + { DEBUG(1, Sdprintf("Error reading from %d: %s\n", + s->socket, WinSockError(s->error))); + doneRequest(s); + } + } else + { doneRequest(s); + } + } + break; + case REQ_RECVFROM: + if ( s->w32_flags & (FD_READ|FD_CLOSE) ) + { int iflen = (int)*s->rdata.recvfrom.fromlen; + + s->w32_flags &= ~FD_READ; + + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + s->rdata.recvfrom.bytes = + recvfrom(s->socket, + s->rdata.recvfrom.buffer, + (int)s->rdata.recvfrom.size, + s->rdata.recvfrom.flags, + s->rdata.recvfrom.from, + &iflen); + + if ( s->rdata.recvfrom.bytes < 0 ) + { s->error = WSAGetLastError(); + + if ( s->error != WSAEWOULDBLOCK ) + { DEBUG(1, Sdprintf("Error recvfrom from %d: %s\n", + s->socket, WinSockError(s->error))); + doneRequest(s); + } + } else + { *s->rdata.recvfrom.fromlen = iflen; + doneRequest(s); + } + } + break; + case REQ_WRITE: + if ( s->w32_flags & FD_WRITE ) + { int n; + int len = (int)(s->rdata.write.size - s->rdata.write.written); + + s->w32_flags &= ~FD_WRITE; + + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + DEBUG(2, Sdprintf("send() %d bytes\n", s->rdata.write.size)); + n = send(s->socket, + s->rdata.write.buffer + s->rdata.write.written, + len, 0); + DEBUG(2, Sdprintf("Wrote %d bytes\n", n)); + if ( n < 0 ) + { s->error = WSAGetLastError(); + if ( s->error == WSAEWOULDBLOCK ) + break; + s->rdata.write.bytes = n; + DEBUG(1, Sdprintf("[%d]: send(%d, %d bytes): %s\n", + PL_thread_self(), s->socket, len, + WinSockError(s->error))); + doneRequest(s); + } else + s->error = 0; + + s->rdata.write.written += n; + if ( s->rdata.write.written >= s->rdata.write.size ) + { s->rdata.write.bytes = (int)s->rdata.write.written; + doneRequest(s); + } + } + case REQ_SENDTO: + if ( s->w32_flags & FD_WRITE ) + { int n; + + s->w32_flags &= ~FD_WRITE; + + if ( true(s, PLSOCK_WAITING) ) + { doneRequest(s); + break; + } + + DEBUG(2, Sdprintf("sendto() %d bytes\n", s->rdata.write.size)); + n = sendto(s->socket, + s->rdata.sendto.buffer, + s->rdata.sendto.size, + s->rdata.sendto.flags, + s->rdata.sendto.to, + s->rdata.sendto.tolen); + DEBUG(2, Sdprintf("Wrote %d bytes\n", n)); + if ( n < 0 ) + { s->error = WSAGetLastError(); + s->rdata.write.bytes = n; + DEBUG(1, Sdprintf("[%d]: send(%d, %d bytes): %s\n", + PL_thread_self(), s->socket, + s->rdata.sendto.size, + WinSockError(s->error))); + doneRequest(s); + } else + s->error = 0; + + s->rdata.sendto.bytes = n; + doneRequest(s); + } + } + + return TRUE; +} + + +static LRESULT WINAPI +socket_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ if ( message == WM_REQUEST ) + { plsocket **s = (plsocket **)lParam; + int i, n = (int)wParam; + + for(i=0; imagic != PLSOCK_MAGIC ) + { goto nosocket; + } + } __except(EXCEPTION_EXECUTE_HANDLER) + { goto nosocket; + } + + doRequest(s[i]); + } + } + + return 0; + + nosocket: + Sdprintf("%p@%d is not a socket!?\n", s[i], i); + return 0; + } else if ( message == WM_SOCKET ) + { SOCKET sock = (SOCKET) wParam; + int err = WSAGETSELECTERROR(lParam); + int evt = WSAGETSELECTEVENT(lParam); + plsocket *s; + + if ( evt&FD_CLOSE ) + { DEBUG(1, + { char *nm = event_name(evt); + Sdprintf("WM_SOCKET on %d: ev=(%s); err=%s\n", + (int)sock, nm, err ? WinSockError(err) : "none"); + free(nm); + }); + } else + { DEBUG(3, + { char *nm = event_name(evt); + Sdprintf("WM_SOCKET on %d: ev=(%s); err=%s\n", + (int)sock, nm, err ? WinSockError(err) : "none"); + free(nm); + }); + } + + LOCK_FREE(); + s = lookupOSSocket(sock); + + if ( s ) + { if ( (s->w32_flags & FD_CLOSE) ) + { DEBUG(1, + { char *nm = event_name(evt); + Sdprintf("Got event %s (err=%s) on closed socket %d=%d\n", + nm, WinSockError(err), s->id, sock); + free(nm); + }) + } + + s->w32_flags |= evt; + if ( err == WSAECONNABORTED && s->request == REQ_READ ) + { s->rdata.read.bytes = 0; + doneRequest(s); + } else if ( err ) + { SOCKET sock = s->socket; + + s->error = err; + if ( sock ) + { s->socket = -1; + closesocket(sock); + } + + switch(s->request) + { case REQ_CONNECT: + break; + case REQ_ACCEPT: + s->rdata.accept.slave = SOCKET_ERROR; + break; + case REQ_READ: + s->rdata.read.bytes = -1; + break; + case REQ_RECVFROM: + s->rdata.recvfrom.bytes = -1; + break; + case REQ_WRITE: + s->rdata.write.bytes = -1; + break; + case REQ_SENDTO: + s->rdata.sendto.bytes = -1; + break; + } + doneRequest(s); + } else if ( s->socket >= 0 ) + { doRequest(s); + } else + { doneRequest(s); + } + } else + { DEBUG(1, Sdprintf("Socket %d is gone (error=%s)\n", + sock, WinSockError(err))); + } + + UNLOCK_FREE(); + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +static char * +HiddenFrameClass() +{ static char *name; + static WNDCLASS wndClass; + + if ( !name ) + { char buf[50]; + + sprintf(buf, "PlSocketWin%d", (int)hinstance); + name = strdup(buf); + + wndClass.style = 0; + wndClass.lpfnWndProc = (LPVOID) socket_wnd_proc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = hinstance; + wndClass.hIcon = NULL; + wndClass.hCursor = NULL; + wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = name; + + RegisterClass(&wndClass); + } + + return name; +} + + +static void +destroyHiddenWindow(int rval, void *closure) +{ local_state *s = State(); + + if ( s->hwnd ) + { DestroyWindow(s->hwnd); + s->hwnd = 0; + } +} + + +static HWND +SocketHiddenWindow() +{ local_state *s = State(); + + if ( !s->hwnd ) + { s->hwnd = CreateWindow(HiddenFrameClass(), + "SWI-Prolog socket window", + WS_POPUP, + 0, 0, 32, 32, + NULL, NULL, hinstance, NULL); + assert(s->hwnd); + DEBUG(1, Sdprintf("%d created hidden window %p\n", + PL_thread_self(), s->hwnd)); + } + + return s->hwnd; +} + + +DWORD WINAPI +socket_thread(LPVOID arg) +{ DWORD parent = (DWORD)arg; + + SocketHiddenWindow(); + PostThreadMessage(parent, WM_READY, (WPARAM)0, (LPARAM)0); + + for(;;) + { MSG msg; + + if ( GetMessage(&msg, NULL, 0, 0) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return 0; +} + + +static int +startSocketThread() +{ DWORD me = GetCurrentThreadId(); + MSG msg; + + CreateThread(NULL, /* security */ + 2048, /* stack */ + socket_thread, (LPVOID)me, /* proc+arg */ + 0, /* flags */ + &State()->tid); + + GetMessage(&msg, NULL, WM_READY, WM_READY); + DEBUG(1, Sdprintf("Socket thread started\n")); + + return TRUE; +} + +#else /*__WINDOWS__*/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +wait_socket() is the Unix way to wait for input on the socket. By +default event-dispatching on behalf of XPCE is performed. If this is not +desired, you can use tcp_setopt(Socket, dispatch(false)), in which case +this call returns immediately, assuming the actual TCP call will block +without dispatching if no input is available. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static int +wait_socket(plsocket *s) +{ if ( true(s, PLSOCK_DISPATCH) ) + { int fd = s->socket; + + if ( true(s, PLSOCK_NONBLOCK) && !PL_dispatch(fd, PL_DISPATCH_INSTALLED) ) + { fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 250000; + + select(fd+1, &rfds, NULL, NULL, &tv); + return TRUE; + } else + { return PL_dispatch(fd, PL_DISPATCH_WAIT); + } + } + + return TRUE; +} + + +int +nbio_wait(nbio_sock_t socket, nbio_request request) +{ plsocket *s; + + if ( !(s=nbio_to_plsocket(socket)) ) + return -1; + + return wait_socket(s) ? 0 : -1; +} + + +static int +nbio_fcntl(nbio_sock_t socket, int op, int arg) +{ plsocket *s; + int rc; + + if ( !(s=nbio_to_plsocket(socket)) ) + return -1; + + rc = fcntl(s->socket, op, arg); + + if ( rc == 0 ) + { if ( op == F_SETFL && arg == O_NONBLOCK ) + s->flags |= PLSOCK_NONBLOCK; + } else + nbio_error(errno, TCP_ERRNO); + + return rc; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +NOTE: when called througb wait_for_input/3, the descriptors in the sets +are real underlying Unix socket descriptors and *not* the nbio_sock_t +psuedo descriptors. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +int +nbio_select(int n, + fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ return select(n, readfds, writefds, exceptfds, timeout); +} + +#endif /*__WINDOWS__*/ + + + /******************************* + * ADMINISTRATION * + *******************************/ + +static functor_t FUNCTOR_module2; +static functor_t FUNCTOR_ip4; +static functor_t FUNCTOR_ip1; +static atom_t ATOM_any; +static atom_t ATOM_broadcast; +static atom_t ATOM_loopback; + +static plsocket **sockets = NULL; /* id --> plsocket* */ +static size_t socks_count = 0; /* #registered sockets */ +static size_t socks_allocated = 0; /* #allocated entries */ +static int initialised = FALSE; /* Windows only */ + +#ifdef __WINDOWS__ + +static plsocket * +lookupOSSocket(SOCKET socket) +{ plsocket *p; + size_t i; + + LOCK(); + for(i=0; isocket == socket ) + { UNLOCK(); + + if ( p->magic != PLSOCK_MAGIC ) + { errno = EINVAL; + DEBUG(1, Sdprintf("Invalid OS socket: %d\n", socket)); + return NULL; + } + + return p; + } + } + UNLOCK(); + + return NULL; +} + +#endif /*__WINDOWS__*/ + + +static plsocket * +nbio_to_plsocket_nolock(nbio_sock_t socket) +{ plsocket *p; + + if ( socket < 0 || (size_t)socket >= socks_allocated ) + { errno = EINVAL; + return NULL; + } + + p = sockets[socket]; + + if ( !p || p->magic != PLSOCK_MAGIC ) + { DEBUG(1, Sdprintf("Invalid NBIO socket: %d\n", socket)); + errno = EINVAL; + return NULL; + } + + return p; +} + + +SOCKET +plsocket_handle(plsocket_ptr pls) +{ return pls->socket; +} + + +static plsocket * +nbio_to_plsocket_raw(nbio_sock_t socket) +{ plsocket *s; + + LOCK(); + s = nbio_to_plsocket_nolock(socket); + UNLOCK(); + + return s; +} + + +plsocket * +nbio_to_plsocket(nbio_sock_t socket) +{ plsocket *p; + + if ( !(p=nbio_to_plsocket_raw(socket)) ) + return NULL; + +#ifdef __WINDOWS__ + if ( p->socket < 0 ) + { p->error = WSAECONNRESET; + return NULL; + } +#endif + + return p; +} + + +NBIO_EXPORT(SOCKET) +nbio_fd(nbio_sock_t socket) +{ plsocket *p; + + if ( !(p=nbio_to_plsocket_nolock(socket)) ) + return -1; + + return p->socket; +} + + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Allocate a wrapper for an OS socket. The wrapper is allocated in an +array of pointers, to keep small integer identifiers we can use with +FD_SET, etc. for implementing a compatible nbio_select(). +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static plsocket * +allocSocket(SOCKET socket) +{ plsocket *p = NULL; + size_t i; + +#ifdef __WINDOWS__ + if ( (p=lookupOSSocket(socket)) ) + { DEBUG(1, Sdprintf("WinSock %d already registered on %d\n", + (int)socket, p->id)); + p->socket = (SOCKET)-1; + } +#endif + + LOCK(); + if ( socks_count+1 > socks_allocated ) + { if ( socks_allocated ) + { size_t newa = socks_allocated*2; + + sockets = PL_realloc(sockets, sizeof(plsocket*)*newa); + for(i=socks_allocated; iid = (int)i; /* place in the array */ + p->socket = socket; + p->flags = PLSOCK_DISPATCH; /* by default, dispatch */ + p->magic = PLSOCK_MAGIC; +#ifdef __WINDOWS__ + p->w32_flags = 0; + p->request = REQ_NONE; +#endif + p->input = p->output = (IOSTREAM*)NULL; + + DEBUG(2, Sdprintf("[%d]: allocSocket(%d): bound to %p\n", + PL_thread_self(), socket, p)); + + return p; +} + + +static int +freeSocket(plsocket *s) +{ int rval; + nbio_sock_t socket; + SOCKET sock; + + DEBUG(2, Sdprintf("Closing %d\n", s->id)); + if ( !s || s->magic != PLSOCK_MAGIC ) + { errno = EINVAL; + return -1; + } + + LOCK_FREE(); + LOCK(); + sockets[s->id] = NULL; + socks_count--; + UNLOCK(); + + sock = s->socket; + socket = s->id; + s->magic = 0; + PL_free(s); + UNLOCK_FREE(); + + if ( sock >= 0 ) + { again: + if ( (rval=closesocket(sock)) == SOCKET_ERROR ) + { if ( errno == EINTR ) + goto again; + } + DEBUG(2, Sdprintf("freeSocket(%d=%d) returned %d\n", + socket, (int)sock, rval)); + } else + { rval = 0; /* already closed. Use s->error? */ + } + + return rval; +} + + + /******************************* + * ERRORS * + *******************************/ + +#ifdef __WINDOWS__ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +The code in BILLY_GETS_BETTER is, according to various documents the +right code, but it doesn't work, so we do it by hand. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef BILLY_GETS_BETTER + +static const char * +WinSockError(unsigned long eno) +{ char buf[1024]; + static HMODULE netmsg = 0; + static int netmsg_loaded = FALSE; + unsigned long flags = (FORMAT_MESSAGE_FROM_SYSTEM| + FORMAT_MESSAGE_IGNORE_INSERTS); + + if ( !netmsg_loaded ) + { netmsg_loaded = TRUE; + netmsg = LoadLibraryEx("netmsg.dll", 0, LOAD_LIBRARY_AS_DATAFILE); + if ( !netmsg ) + Sdprintf("failed to load netmsg.dll\n"); + else + Sdprintf("Loaded netmsg.dll as %p\n", netmsg); + } + + if ( netmsg ) + flags |= FORMAT_MESSAGE_FROM_HMODULE; + + if ( !FormatMessage(flags, + netmsg, + eno, + GetUserDefaultLangID(), + /*MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),*/ + buf, sizeof(buf), + 0)) + { sprintf(buf, "Unknown socket error (%u)", eno); + } + + buf[sizeof(buf)-1]='\0'; + + return strdup(buf); +} + +#else /*BILLY_GETS_BETTER*/ + +static const char * +WinSockError(unsigned long error) +{ struct + { int index; + const char *string; + } *ep, edefs[] = + { { WSAEACCES, "Permission denied" }, + { WSAEADDRINUSE, "Address already in use" }, + { WSAEADDRNOTAVAIL, "Cannot assign requested address" }, + { WSAEAFNOSUPPORT, "Address family not supported by protocol family" }, + { WSAEALREADY, "Operation already in progress" }, + { WSAECONNABORTED, "Software caused connection abort" }, + { WSAECONNREFUSED, "Connection refused" }, + { WSAECONNRESET, "Connection reset by peer" }, + { WSAEDESTADDRREQ, "Destination address required" }, + { WSAEFAULT, "Bad address" }, + { WSAEHOSTDOWN, "Host is down" }, + { WSAEHOSTUNREACH, "No route to host" }, + { WSAEINPROGRESS, "Operation now in progress" }, + { WSAEINTR, "Interrupted function call" }, + { WSAEINVAL, "Invalid argument" }, + { WSAEISCONN, "Socket is already connected" }, + { WSAEMFILE, "Too many open files" }, + { WSAEMSGSIZE, "Message too long" }, + { WSAENETDOWN, "Network is down" }, + { WSAENETRESET, "Network dropped connection on reset" }, + { WSAENETUNREACH, "Network is unreachable" }, + { WSAENOBUFS, "No buffer space available" }, + { WSAENOPROTOOPT, "Bad protocol option" }, + { WSAENOTCONN, "Socket is not connected" }, + { WSAENOTSOCK, "Socket operation on non-socket" }, + { WSAEOPNOTSUPP, "Operation not supported" }, + { WSAEPFNOSUPPORT, "Protocol family not supported" }, + { WSAEPROCLIM, "Too many processes" }, + { WSAEPROTONOSUPPORT, "Protocol not supported" }, + { WSAEPROTOTYPE, "Protocol wrong type for socket" }, + { WSAESHUTDOWN, "Cannot send after socket shutdown" }, + { WSAESOCKTNOSUPPORT, "Socket type not supported" }, + { WSAETIMEDOUT, "Connection timed out" }, + { WSAEWOULDBLOCK, "Resource temporarily unavailable" }, + { WSAEDISCON, "Graceful shutdown in progress" }, + { WSANOTINITIALISED, "Socket layer not initialised" }, + /* WinSock 2 errors */ + { WSAHOST_NOT_FOUND, "Host not found" }, + { 0, NULL } + }; + char tmp[100]; + + for(ep=edefs; ep->string; ep++) + { if ( ep->index == (int)error ) + return ep->string; + } + + sprintf(tmp, "Unknown error %ld", error); + return strdup(tmp); /* leaks memory on unknown errors */ +} + +#endif /*BILLY_GETS_BETTER*/ +#endif /*__WINDOWS__*/ + +#ifdef HAVE_H_ERRNO +typedef struct +{ int code; + const char *string; +} error_codes; + +static error_codes h_errno_codes[] = { +#ifdef HOST_NOT_FOUND + { HOST_NOT_FOUND, "Host not found" }, +#endif +#ifdef TRY_AGAIN + { TRY_AGAIN, "Try Again" }, +#endif +#ifdef NO_RECOVERY + { NO_RECOVERY, "No Recovery" }, +#endif +#ifdef NO_DATA + { NO_DATA, "No Data" }, +#endif +#ifdef NO_ADDRESS + { NO_ADDRESS, "No Address" }, +#endif + {0, NULL} +}; + +#else /*HAVE_H_ERRNO*/ +#define h_errno_codes NULL +typedef void * error_codes; +#endif /*HAVE_H_ERRNO*/ + +int +nbio_error(int code, nbio_error_map mapid) +{ const char *msg; + term_t except = PL_new_term_ref(); + error_codes *map; + + if ( code == EPLEXCEPTION ) + return FALSE; + + switch( mapid ) + { case TCP_HERRNO: + map = h_errno_codes; + break; + default: + map = NULL; + } + + { +#ifdef __WINDOWS__ + msg = WinSockError(code); +#else + +#ifdef HAVE_H_ERRNO + static char msgbuf[100]; + + if ( map ) + { while( map->code && map->code != code ) + map++; + if ( map->code ) + msg = map->string; + else + { sprintf(msgbuf, "Unknown error %d", code); + msg = msgbuf; + } + } else +#endif + msg = strerror(code); +#endif /*__WINDOWS__*/ + + if ( !PL_unify_term(except, + CompoundArg("error", 2), + CompoundArg("socket_error", 1), + AtomArg(msg), + PL_VARIABLE) ) + return FALSE; + } + + return PL_raise_exception(except); +} + + +const char * +nbio_last_error(nbio_sock_t socket) +{ +#ifdef __WINDOWS__ + plsocket *s; + + if ( !(s=nbio_to_plsocket_raw(socket)) ) + return NULL; + + if ( s->error ) + return WinSockError(s->error); +#endif + + return NULL; +} + + + /******************************* + * INITIALISATION * + *******************************/ + +NBIO_EXPORT(int) +nbio_init(const char *module) +{ INITLOCK(); /* is this ok? */ + + LOCK(); + if ( initialised ) + { UNLOCK(); + return TRUE; + } + initialised = TRUE; + + FUNCTOR_module2 = PL_new_functor(PL_new_atom(":"), 2); + FUNCTOR_ip4 = PL_new_functor(PL_new_atom("ip"), 4); + FUNCTOR_ip1 = PL_new_functor(PL_new_atom("ip"), 1); + ATOM_any = PL_new_atom("any"); + ATOM_broadcast = PL_new_atom("broadcast"); + ATOM_loopback = PL_new_atom("loopback"); + +#ifdef __WINDOWS__ +{ WSADATA WSAData; + + hinstance = GetModuleHandle(module); + +#if 0 + WM_SOCKET = RegisterWindowMessage("SWI-Prolog:nonblockio:WM_SOCKET"); + WM_REQUEST = RegisterWindowMessage("SWI-Prolog:nonblockio:WM_REQUEST"); + WM_READY = RegisterWindowMessage("SWI-Prolog:nonblockio:WM_READY"); + WM_DONE = RegisterWindowMessage("SWI-Prolog:nonblockio:WM_DONE"); +#endif + + if ( WSAStartup(MAKEWORD(2,0), &WSAData) ) + { UNLOCK(); + return PL_warning("nbio_init() - WSAStartup failed."); + } + startSocketThread(); +} +#endif /*__WINDOWS__*/ + + UNLOCK(); + return TRUE; +} + + +NBIO_EXPORT(int) +nbio_cleanup(void) +{ if ( initialised ) + { +#ifdef __WINDOWS__ + WSACleanup(); +#endif + } + + return 0; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +socket(-Socket) + Create a stream inet socket. The socket is represented by a term of + the format $socket(Id). +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +NBIO_EXPORT(nbio_sock_t) +nbio_socket(int domain, int type, int protocol) +{ SOCKET sock; + plsocket *s; + + assert(initialised); + + if ( (sock = socket(domain, type , protocol)) < 0) + { nbio_error(errno, TCP_ERRNO); + return -1; + } + if ( !(s=allocSocket(sock)) ) /* register it */ + { closesocket(sock); + return -1; + } + +#ifdef __WINDOWS__ + WSAAsyncSelect(sock, State()->hwnd, WM_SOCKET, + FD_READ|FD_WRITE|FD_ACCEPT|FD_CONNECT|FD_CLOSE); +#endif + + return s->id; +} + + +NBIO_EXPORT(int) +nbio_closesocket(nbio_sock_t socket) +{ plsocket *s; + + if ( !(s = nbio_to_plsocket_raw(socket)) ) + { DEBUG(1, Sdprintf("nbio_closesocket(%d): no plsocket\n", socket)); + return -1; + } + + if ( true(s, PLSOCK_OUTSTREAM|PLSOCK_INSTREAM) ) + { int flags = s->flags; /* may drop out! */ + + if ( flags & PLSOCK_INSTREAM ) + { assert(s->input); + Sclose(s->input); + } + if ( flags & PLSOCK_OUTSTREAM ) + { assert(s->output); + Sclose(s->output); + } + } else + { +#ifdef __WINDOWS__ + if ( true(s, PLSOCK_CONNECT) ) + { if ( s->socket >= 0 ) + shutdown(s->socket, SD_SEND); + } +#endif + + freeSocket(s); + } + + return 0; +} + +NBIO_EXPORT(int) +nbio_setopt(nbio_sock_t socket, nbio_option opt, ...) +{ plsocket *s; + va_list args; + int rc; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + + va_start(args, opt); + + switch(opt) + { case TCP_NONBLOCK: + rc = nbio_fcntl(socket, F_SETFL, O_NONBLOCK); + break; + case TCP_REUSEADDR: + { int val = va_arg(args, int); + + if( setsockopt(s->socket, SOL_SOCKET, SO_REUSEADDR, + (const char *)&val, sizeof(val)) == -1 ) + { nbio_error(h_errno, TCP_HERRNO); + rc = -1; + } else + rc = 0; + + break; + } + case TCP_NO_DELAY: +#ifdef TCP_NODELAY + { int val = va_arg(args, int); + +#ifndef IPPROTO_TCP /* Is this correct? */ +#define IPPROTO_TCP SOL_SOCKET +#endif + if ( setsockopt(s->socket, IPPROTO_TCP, TCP_NODELAY, + (const char *)&val, sizeof(val)) == -1 ) + { nbio_error(h_errno, TCP_HERRNO); + rc = -1; + } else + { rc = 0; + } + + break; + } +#else + rc = -2; /* not implemented */ +#endif + case UDP_BROADCAST: + { int val = va_arg(args, int); + + if ( setsockopt(s->socket, SOL_SOCKET, SO_BROADCAST, + (const char *)&val, sizeof(val)) == -1 ) + { nbio_error(h_errno, TCP_HERRNO); + rc = -1; + } else + rc = 0; + + break; + } + case TCP_DISPATCH: + { int val = va_arg(args, int); + + if ( val ) + set(s, PLSOCK_DISPATCH); + else + clear(s, PLSOCK_DISPATCH); + + rc = 0; + + break; + } + case TCP_INSTREAM: + { IOSTREAM *in = va_arg(args, IOSTREAM*); + + s->flags |= PLSOCK_INSTREAM; + s->input = in; + + rc = 0; + + break; + } + case TCP_OUTSTREAM: + { IOSTREAM *out = va_arg(args, IOSTREAM*); + + s->flags |= PLSOCK_OUTSTREAM; + s->output = out; + + rc = 0; + + break; + } + default: + rc = -1; + assert(0); + } + + va_end(args); + + return rc; +} + + +int +nbio_get_flags(nbio_sock_t socket) +{ plsocket *s; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + + return s->flags; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Translate a host + port-number into a sockaddr structure. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static int +nbio_get_port(term_t Port, int *port) +{ char *name; + + if ( PL_get_atom_chars(Port, &name) ) + { struct servent *service; + + if ( !(service = getservbyname(name, "tcp")) ) + return pl_error(NULL, 0, NULL, ERR_EXISTENCE, "service", Port); + + *port = ntohs(service->s_port); + DEBUG(1, Sdprintf("Service %s at port %d\n", name, *port)); + return TRUE; + } + + if ( PL_get_integer(Port, port) ) + return TRUE; + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, -1, Port, "port"); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Convert a term Host:Port to a socket address. Port is either an integer +or the name of a registered port (e.g. 'smtp'). +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +int +nbio_get_sockaddr(term_t Address, struct sockaddr_in *addr) +{ int port; + + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + if ( PL_is_functor(Address, FUNCTOR_module2) ) + { char *hostName; + term_t arg = PL_new_term_ref(); + + _PL_get_arg(1, Address, arg); + if ( PL_get_atom_chars(arg, &hostName) ) + { struct hostent *host; + + if( !(host = gethostbyname(hostName)) ) + return nbio_error(h_errno, TCP_HERRNO); + if ( (int)sizeof(addr->sin_addr) < host->h_length ) + return PL_warning("Oops, host address too long!"); + memcpy(&addr->sin_addr, host->h_addr, host->h_length); + } else if ( !nbio_get_ip(arg, &addr->sin_addr) ) + { return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, arg, "atom|ip/4"); + } + + _PL_get_arg(2, Address, arg); + if ( !nbio_get_port(arg, &port) ) + return FALSE; + } else if ( PL_is_variable(Address) ) + { port = 0; + } else if ( !nbio_get_port(Address, &port) ) + return FALSE; + + addr->sin_port = htons((short)port); + + return TRUE; +} + + +int +nbio_get_ip(term_t ip4, struct in_addr *ip) +{ unsigned long hip = 0; + + if ( PL_is_functor(ip4, FUNCTOR_ip4) ) + { int i, ia; + term_t a = PL_new_term_ref(); + + for(i=1; i<=4; i++) + { _PL_get_arg(i, ip4, a); + if ( PL_get_integer(a, &ia) ) + hip |= ia << ((4-i)*8); + else + return FALSE; + } + hip = htonl(hip); + memcpy(ip, &hip, sizeof(hip)); + + return TRUE; + } else if ( PL_is_functor(ip4, FUNCTOR_ip1) ) + { term_t a = PL_new_term_ref(); + atom_t id; + + _PL_get_arg(1, ip4, a); + if ( PL_get_atom(a, &id) ) + { if ( id == ATOM_any ) + ip->s_addr = INADDR_ANY; + else if ( id == ATOM_broadcast ) + ip->s_addr = INADDR_BROADCAST; + else if ( id == ATOM_loopback ) + ip->s_addr = INADDR_LOOPBACK; + else + return FALSE; + + return TRUE; + } + } + + return FALSE; +} + + +int +nbio_unify_ip4(term_t Ip, unsigned long hip) +{ return PL_unify_term(Ip, + PL_FUNCTOR, FUNCTOR_ip4, + IntArg((hip >> 24) & 0xff), + IntArg((hip >> 16) & 0xff), + IntArg((hip >> 8) & 0xff), + IntArg((hip >> 0) & 0xff)); +} + + +int +nbio_bind(nbio_sock_t socket, struct sockaddr *my_addr, size_t addrlen) +{ plsocket *s; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + if ( bind(s->socket, my_addr, (int)addrlen) ) +#else + if ( bind(s->socket, my_addr, addrlen) ) +#endif + { nbio_error(errno, TCP_ERRNO); + return -1; + } + + s->flags |= PLSOCK_BIND; + + return 0; +} + + +int +nbio_connect(nbio_sock_t socket, + const struct sockaddr *serv_addr, + size_t addrlen) +{ plsocket *s; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + if ( connect(s->socket, serv_addr, (int)addrlen) ) + { s->error = WSAGetLastError(); + + if ( s->error == WSAEWOULDBLOCK ) + { s->rdata.connect.addrlen = addrlen; + memcpy(&s->rdata.connect.addr, serv_addr, addrlen); + placeRequest(s, REQ_CONNECT); + waitRequest(s); + } + + if ( s->error ) + { nbio_error(s->error, TCP_ERRNO); + return -1; + } + } +#else /*!__WINDOWS__*/ + for(;;) + { if ( connect(s->socket, serv_addr, addrlen) ) + { if ( need_retry(errno) ) + { if ( PL_handle_signals() < 0 ) + return -1; + continue; + } + nbio_error(errno, TCP_ERRNO); + return -1; + } else + break; + } +#endif + + s->flags |= PLSOCK_CONNECT; + + return 0; +} + + +nbio_sock_t +nbio_accept(nbio_sock_t master, struct sockaddr *addr, socklen_t *addrlen) +{ SOCKET slave; + plsocket *m, *s; + + if ( !(m = nbio_to_plsocket(master)) ) + return -1; + +#ifdef __WINDOWS__ +{ int alen = (int)*addrlen; + slave = accept(m->socket, addr, &alen); + *addrlen = alen; +} + + if ( slave == SOCKET_ERROR ) + { m->error = WSAGetLastError(); + + if ( m->error == WSAEWOULDBLOCK ) + { m->rdata.accept.addrlen = sizeof(m->rdata.accept.addr); + placeRequest(m, REQ_ACCEPT); + if ( !waitRequest(m) ) + return -1; + if ( m->error ) + return nbio_error(m->error, TCP_ERRNO); + *addrlen = m->rdata.accept.addrlen; + memcpy(addr, &m->rdata.accept.addr, m->rdata.accept.addrlen); + + return m->rdata.accept.slave; /* already registered */ + } else + { nbio_error(m->error, TCP_ERRNO); + return -1; + } + } + +#else /*__WINDOWS__*/ + + for(;;) + { if ( !wait_socket(m) ) + return -1; + + slave = accept(m->socket, addr, addrlen); + + if ( slave == SOCKET_ERROR ) + { if ( need_retry(errno) ) + { if ( PL_handle_signals() < 0 ) + return -1; + + continue; + } else + { nbio_error(errno, TCP_ERRNO); + return -1; + } + } else + break; + } + +#endif /*__WINDOWS__*/ + + s = allocSocket(slave); + s->flags |= PLSOCK_ACCEPT; +#ifndef __WINDOWS__ + if ( true(s, PLSOCK_NONBLOCK) ) + nbio_setopt(slave, TCP_NONBLOCK); +#endif + + return s->id; +} + + +int +nbio_listen(nbio_sock_t socket, int backlog) +{ plsocket *s; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + + if( listen(s->socket, backlog) == -1 ) + { nbio_error(errno, TCP_ERRNO); + return -1; + } + + s->flags |= PLSOCK_LISTEN; + + return 0; +} + + + /******************************* + * IO-STREAM STUFF * + *******************************/ + +#define fdFromHandle(p) ((int)((intptr_t)(p))) + +ssize_t +nbio_read(int socket, char *buf, size_t bufSize) +{ plsocket *s; + int n; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + + DEBUG(3, Sdprintf("[%d] reading from socket %d\n", + PL_thread_self(), socket)); + + n = recv(s->socket, buf, (int)bufSize, 0); + if ( n < 0 ) + { int wsaerrno; + + if ( (wsaerrno=WSAGetLastError()) == WSAEWOULDBLOCK ) + { s->rdata.read.buffer = buf; + s->rdata.read.size = bufSize; + placeRequest(s, REQ_READ); + if ( !waitRequest(s) ) + { errno = EPLEXCEPTION; + return -1; + } + n = s->rdata.read.bytes; + } + + if ( n < 0 ) + { s->error = wsaerrno; + errno = EIO; + } + } else + { s->error = 0; + } + +#else /*__WINDOWS__*/ + + for(;;) + { if ( !wait_socket(s) ) + { errno = EPLEXCEPTION; + return -1; + } + + n = recv(s->socket, buf, bufSize, 0); + + if ( n == -1 && need_retry(errno) ) + { if ( PL_handle_signals() < 0 ) + { errno = EPLEXCEPTION; + return -1; + } + continue; + } + + break; + } + +#endif /*__WINDOWS__*/ + + return n; +} + + +ssize_t +nbio_write(nbio_sock_t socket, char *buf, size_t bufSize) +{ plsocket *s; + size_t len = bufSize; + char *str = buf; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + while( len != 0 ) + { ssize_t n; + + DEBUG(3, Sdprintf("[%d] sending %d bytes using socket %d\n", + PL_thread_self(), (int)len, socket)); + + n = send(s->socket, str, (int)len, 0); + if ( n < 0 ) + { int error = WSAGetLastError(); + + if ( error == WSAEWOULDBLOCK ) + break; + + DEBUG(1, Sdprintf("[%d]: send(%d, %d bytes): %s\n", + PL_thread_self(), s->socket, (int)bufSize, + WinSockError(error))); + + s->error = error; + return -1; + } + + len -= n; + str += n; + } + + if ( len > 0 ) /* operation would block */ + { s->rdata.write.buffer = str; + s->rdata.write.size = len; + s->rdata.write.written = 0; + placeRequest(s, REQ_WRITE); + if ( !waitRequest(s) ) + { errno = EPLEXCEPTION; /* handled Prolog signal */ + return -1; + } + if ( s->rdata.write.bytes < 0 ) + return -1; /* error in s->error */ + } + +#else /*__WINDOWS__*/ + + while( len > 0 ) + { int n; + + n = send(s->socket, str, len, 0); + if ( n < 0 ) + { if ( need_retry(errno) ) + { if ( PL_handle_signals() < 0 ) + { errno = EPLEXCEPTION; + return -1; + } + continue; + } + return -1; + } + + len -= n; + str += n; + } + +#endif /*__WINDOWS__*/ + + return bufSize; +} + + +int +nbio_close_input(nbio_sock_t socket) +{ int rc = 0; + plsocket *s; + + if ( !(s = nbio_to_plsocket_raw(socket)) ) + return -1; + + DEBUG(2, Sdprintf("[%d]: nbio_close_input(%d, flags=0x%x)\n", + PL_thread_self(), socket, s->flags)); + s->flags &= ~PLSOCK_INSTREAM; +#ifdef __WINDOWS__ + if ( false(s, PLSOCK_LISTEN) ) + { SOCKET sock; + + if ( (sock=s->socket) < 0 ) + { s->error = WSAECONNRESET; + rc = -1; + } else if ( shutdown(sock, SD_RECEIVE) == SOCKET_ERROR ) + { DEBUG(1, Sdprintf("shutdown(%d=%d, SD_RECEIVE) failed: %s\n", + socket, s->socket, + WinSockError(WSAGetLastError()))); + Sseterr(s->input, SIO_FERR, WinSockError(WSAGetLastError())); + rc = -1; + } + } +#endif + + s->input = NULL; + if ( !(s->flags & (PLSOCK_INSTREAM|PLSOCK_OUTSTREAM)) ) + return freeSocket(s); + + return rc; +} + + +int +nbio_close_output(nbio_sock_t socket) +{ int rc = 0; + plsocket *s; + + if ( !(s = nbio_to_plsocket_raw(socket)) ) + return -1; + + DEBUG(2, Sdprintf("[%d]: nbio_close_output(%d, flags=0x%x)\n", + PL_thread_self(), socket, s->flags)); + if ( s->output ) + { +#if __WINDOWS__ + SOCKET sock; +#endif + + s->flags &= ~PLSOCK_OUTSTREAM; +#if __WINDOWS__ + if ( (sock=s->socket) < 0 ) + { s->error = WSAECONNRESET; + rc = -1; + } else if ( shutdown(sock, SD_SEND) == SOCKET_ERROR ) + { const char *msg; + + msg = WinSockError(WSAGetLastError()); + Sseterr(s->output, SIO_FERR, msg); + DEBUG(1, Sdprintf("shutdown(%d=%d, SD_SEND) failed: %s\n", + socket, s->socket, msg)); + rc = -1; + } +#endif + } + + DEBUG(3, Sdprintf("%d->flags = 0x%x\n", socket, s->flags)); + s->output = NULL; + if ( !(s->flags & (PLSOCK_INSTREAM|PLSOCK_OUTSTREAM)) ) + return freeSocket(s); + + return rc; +} + + + /******************************* + * UDP SUPPORT * + *******************************/ + +ssize_t +nbio_recvfrom(int socket, void *buf, size_t bufSize, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ plsocket *s; + int n; + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + DEBUG(3, Sdprintf("[%d] recvfrom from socket %d\n", + PL_thread_self(), socket)); + + { int iflen = (int)*fromlen; /* Windows recvfrom uses int */ + + n = recvfrom(s->socket, buf, (int)bufSize, flags, from, &iflen); + if ( n < 0 ) + { int wsaerrno; + + if ( (wsaerrno=WSAGetLastError()) == WSAEWOULDBLOCK ) + { s->rdata.recvfrom.buffer = buf; + s->rdata.recvfrom.size = bufSize; + s->rdata.recvfrom.flags = flags; + s->rdata.recvfrom.from = from; + s->rdata.recvfrom.fromlen = fromlen; + placeRequest(s, REQ_RECVFROM); + if ( !waitRequest(s) ) + { errno = EPLEXCEPTION; + return -1; + } + n = s->rdata.recvfrom.bytes; + } + + if ( n < 0 ) + { s->error = wsaerrno; + errno = EIO; + } + } else + { *fromlen = iflen; + s->error = 0; + } + } + +#else /*__WINDOWS__*/ + + for(;;) + { if ( (flags & MSG_DONTWAIT) == 0 && !wait_socket(s) ) + { errno = EPLEXCEPTION; + return -1; + } + + n = recvfrom(s->socket, buf, bufSize, flags, from, fromlen); + + if ( n == -1 && need_retry(errno) ) + { if ( PL_handle_signals() < 0 ) + { errno = EPLEXCEPTION; + return -1; + } + + if((flags & MSG_DONTWAIT) != 0) + break; + + continue; + } + + break; + } + +#endif /*__WINDOWS__*/ + + return n; +} + + +ssize_t +nbio_sendto(nbio_sock_t socket, void *buf, size_t bufSize, int flags, + const struct sockaddr *to, socklen_t tolen) +{ plsocket *s; +#ifdef __WINDOWS__ + ssize_t n; +#endif + + if ( !(s = nbio_to_plsocket(socket)) ) + return -1; + +#ifdef __WINDOWS__ + DEBUG(3, Sdprintf("[%d] sending %d bytes using socket %d\n", + PL_thread_self(), (int)bufSize, socket)); + + n = sendto(s->socket, buf, (int)bufSize, flags, to, (int)tolen); + if ( n < 0 ) + { int error = WSAGetLastError(); + + if ( error == WSAEWOULDBLOCK ) + goto wouldblock; + + DEBUG(1, Sdprintf("[%d]: sendto(%d, %d bytes): %s\n", + PL_thread_self(), s->socket, (int)bufSize, + WinSockError(error))); + + s->error = error; + return -1; + } else + return n; + +wouldblock: + s->rdata.sendto.buffer = buf; + s->rdata.sendto.size = (int)bufSize; + s->rdata.sendto.bytes = 0; + s->rdata.sendto.flags = flags; + s->rdata.sendto.to = to; + s->rdata.sendto.tolen = (int)tolen; + placeRequest(s, REQ_SENDTO); + if ( !waitRequest(s) ) + { errno = EPLEXCEPTION; /* handled Prolog signal */ + return -1; + } + + return s->rdata.sendto.bytes; + +#else /*__WINDOWS__*/ + + return sendto(s->socket, buf, bufSize, flags, to, tolen); +#endif /*__WINDOWS__*/ +} diff --git a/packages/clib/nonblockio.h b/packages/clib/nonblockio.h new file mode 100644 index 000000000..081f86faf --- /dev/null +++ b/packages/clib/nonblockio.h @@ -0,0 +1,196 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2007, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +#ifndef H_NONBLOCKIO_INCLUDED +#define H_NONBLOCKIO_INCLUDED + + + /******************************* + * GET REQUIRED HEADERS * + *******************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#ifdef __WINDOWS__ + +#include +#include +typedef size_t socklen_t; + +#else /*__WINDOWS__*/ + +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#ifdef HAVE_NETINET_TCP_H +#include +#endif +#ifdef HAVE_H_ERRNO +extern int h_errno; +#else +#define h_errno errno +#endif +#ifndef HAVE_SOCKLEN_T +#define socklen_t size_t +#endif + +typedef int SOCKET; + +#endif /*__WINDOWS__*/ + +typedef enum +{ TCP_ERRNO, + TCP_HERRNO +} nbio_error_map; + +typedef enum /* nbio_setopt() commands */ +{ TCP_NONBLOCK, + TCP_REUSEADDR, + TCP_NO_DELAY, + TCP_DISPATCH, + TCP_INSTREAM, + TCP_OUTSTREAM, + UDP_BROADCAST, + NBIO_END +} nbio_option; + +typedef enum +{ REQ_NONE = 0, /* no request pending */ + REQ_ACCEPT, + REQ_CONNECT, + REQ_READ, + REQ_WRITE, + REQ_RECVFROM, + REQ_SENDTO +} nbio_request; + + /* nbio_get_flags() mask */ +#define PLSOCK_INSTREAM 0x001 +#define PLSOCK_OUTSTREAM 0x002 +#define PLSOCK_BIND 0x004 /* What have we done? */ +#define PLSOCK_LISTEN 0x008 +#define PLSOCK_CONNECT 0x010 +#define PLSOCK_ACCEPT 0x020 /* Set on accepted sockets */ +#define PLSOCK_NONBLOCK 0x040 /* Set to non-blocking mode */ +#define PLSOCK_DISPATCH 0x080 /* do not dispatch events */ +#define PLSOCK_CLOSE_SEEN 0x100 /* FD_CLOSE seen */ +#define PLSOCK_EOF_SEEN 0x200 /* Seen end-of-file */ +#define PLSOCK_WAITING 0x400 /* using nbio_wait() */ + + +typedef int nbio_sock_t; /* socket handle (not a file-descr) */ +typedef struct _plsocket *plsocket_ptr; /* wrapped socket */ + + /******************************* + * BASIC FUNCTIONS * + *******************************/ + +#ifdef HAVE_DECLSPEC +#define NBIO_EXPORT(type) __declspec(dllexport) type +#else +#define NBIO_EXPORT(type) extern type +#endif + +NBIO_EXPORT(int) nbio_init(const char *module); +NBIO_EXPORT(int) nbio_cleanup(void); +NBIO_EXPORT(int) nbio_debug(int level); + +NBIO_EXPORT(nbio_sock_t) + nbio_socket(int domain, int type, int protocol); +NBIO_EXPORT(int) nbio_connect(nbio_sock_t socket, + const struct sockaddr *serv_addr, + size_t addrlen); +NBIO_EXPORT(int) nbio_bind(nbio_sock_t socket, + struct sockaddr *my_addr, + size_t addrlen); +NBIO_EXPORT(int) nbio_listen(nbio_sock_t socket, int backlog); +NBIO_EXPORT(nbio_sock_t) + nbio_accept(nbio_sock_t master, + struct sockaddr *addr, + socklen_t *addrlen); + +extern ssize_t nbio_read(nbio_sock_t socket, char *buf, size_t bufSize); +extern ssize_t nbio_write(nbio_sock_t socket, char *buf, size_t bufSize); +NBIO_EXPORT(int) nbio_closesocket(nbio_sock_t socket); +extern int nbio_close_input(nbio_sock_t socket); +extern int nbio_close_output(nbio_sock_t socket); +extern ssize_t nbio_recvfrom(int socket, void *buf, size_t bufSize, int flags, + struct sockaddr *from, socklen_t *fromlen); +extern ssize_t nbio_sendto(nbio_sock_t socket, void *buf, size_t bufSize, int flags, + const struct sockaddr *to, socklen_t tolen); + +NBIO_EXPORT(int) nbio_wait(nbio_sock_t socket, nbio_request); +NBIO_EXPORT(SOCKET) nbio_fd(nbio_sock_t socket); +extern int nbio_select(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout); + +extern int nbio_unify_ip4(term_t ip4, unsigned long hip); +extern int nbio_get_ip(term_t ip4, struct in_addr *ip); + +extern int nbio_error(int code, nbio_error_map map); +extern const char* + nbio_last_error(nbio_sock_t socket); +NBIO_EXPORT(int) nbio_setopt(int socket, nbio_option opt, ...); +extern int nbio_get_flags(int socket); + + /* support tipc_setopt() */ +extern plsocket_ptr + nbio_to_plsocket(nbio_sock_t socket); +extern SOCKET plsocket_handle(plsocket_ptr s); + + + /******************************* + * CONVERSION * + *******************************/ + +extern int nbio_get_sockaddr(term_t Address, + struct sockaddr_in *addr); +extern int nbio_get_ip4(term_t ip4, struct in_addr *ip); + +#endif /*H_NONBLOCKIO_INCLUDED*/ diff --git a/packages/clib/pltotex.pl b/packages/clib/pltotex.pl new file mode 100644 index 000000000..491271d84 --- /dev/null +++ b/packages/clib/pltotex.pl @@ -0,0 +1,60 @@ +:- module(pltotex, + [ pltotex/2, + pltotex/0 + ]). +:- use_module(library(doc_latex)). +:- use_module(library(main)). +:- use_module(library(error)). +:- use_module(library(apply)). +:- use_module(library(lists)). + +pltotex(Lib, Options) :- + ( file_name_extension(_, pl, Lib) + -> Spec = Lib + ; atom_to_term(Lib, Spec, _) + ), + absolute_file_name(Spec, File, + [ access(read), + file_type(prolog) + ]), + tex_file(File, Out), + user:use_module(File), % we want the operators in user + doc_latex(File, Out, + [ stand_alone(false) + | Options + ]). + +tex_file(File, TeXFile) :- + file_base_name(File, Local), + file_name_extension(Base0, _, Local), + strip(Base0, 0'_, Base), + file_name_extension(Base, tex, TeXFile). + +strip(In, Code, Out) :- + atom_codes(In, Codes0), + delete(Codes0, Code, Codes), + atom_codes(Out, Codes). + + +%% pltotex +% +% Usage: pl -q -s pltotex.pl -g pltotex -- file ... + +pltotex :- + main. + +main(Argv) :- + partition(is_option, Argv, OptArgs, Files), + maplist(to_option, OptArgs, Options), + maplist(process_file(Options), Files). + +is_option(Arg) :- + sub_atom(Arg, 0, _, _, --). + +to_option('--section', section_level(section)). +to_option('--subsection', section_level(subsection)). +to_option('--subsubsection', section_level(subsubsection)). + +process_file(Options, File) :- + pltotex(File, Options). + diff --git a/packages/clib/process.c b/packages/clib/process.c new file mode 100644 index 000000000..70e8e1d8d --- /dev/null +++ b/packages/clib/process.c @@ -0,0 +1,1627 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2008-2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/*#define O_DEBUG 1*/ +#include +#include +#include "error.h" +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +static atom_t ATOM_stdin; +static atom_t ATOM_stdout; +static atom_t ATOM_stderr; +static atom_t ATOM_std; +static atom_t ATOM_null; +static atom_t ATOM_process; +static atom_t ATOM_detached; +static atom_t ATOM_cwd; +static atom_t ATOM_env; +static atom_t ATOM_window; +static atom_t ATOM_timeout; +static atom_t ATOM_release; +static atom_t ATOM_infinite; +static functor_t FUNCTOR_error2; +static functor_t FUNCTOR_type_error2; +static functor_t FUNCTOR_domain_error2; +static functor_t FUNCTOR_resource_error1; +static functor_t FUNCTOR_process_error2; +static functor_t FUNCTOR_system_error2; +static functor_t FUNCTOR_pipe1; +static functor_t FUNCTOR_exit1; +static functor_t FUNCTOR_killed1; +static functor_t FUNCTOR_eq2; /* =/2 */ + +#define MAYBE 2 + +#if O_DEBUG +#define DEBUG(g) g +#else +#define DEBUG(g) (void)0 +#endif + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ISSUES: + - Deal with child errors (no cwd, cannot execute, etc.) + - Windows version + - Complete test suite +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + + /******************************* + * ERRORS * + *******************************/ + +static int +type_error(term_t actual, const char *expected) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_type_error2, + PL_CHARS, expected, + PL_TERM, actual, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +domain_error(term_t actual, const char *expected) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_domain_error2, + PL_CHARS, expected, + PL_TERM, actual, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +resource_error(const char *resource) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_resource_error1, + PL_CHARS, resource, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + + /******************************* + * ADMIN * + *******************************/ + +#ifdef __WINDOWS__ +#include +#include +#include +#include +typedef DWORD pid_t; +typedef wchar_t echar; /* environment character */ +#else +typedef char echar; +#endif + +typedef enum std_type +{ std_std, + std_null, + std_pipe +} std_type; + + +typedef struct p_stream +{ term_t term; /* P in pipe(P) */ + std_type type; /* type of stream */ +#ifdef __WINDOWS__ + HANDLE fd[2]; /* pipe handles */ +#else + int fd[2]; /* pipe handles */ +#endif +} p_stream; + + +typedef struct ecbuf +{ echar *buffer; + size_t size; + size_t allocated; +} ecbuf; + + +typedef struct p_options +{ atom_t exe_name; /* exe as atom */ +#ifdef __WINDOWS__ + wchar_t *exe; /* Executable */ + wchar_t *cmdline; /* Command line */ + wchar_t *cwd; /* CWD of new process */ +#else + char *exe; /* Executable */ + char **argv; /* argument vector */ + char *cwd; /* CWD of new process */ + char **envp; /* New environment */ +#endif + ecbuf envbuf; /* environment buffer */ + term_t pid; /* process(PID) */ + int pipes; /* #pipes found */ + p_stream streams[3]; + int detached; /* create as detached */ + int window; /* Show a window? */ +} p_options; + + +typedef struct wait_options +{ double timeout; + int has_timeout; + int release; +} wait_options; + + +#ifdef __WINDOWS__ +static int win_command_line(term_t t, int arity, + const wchar_t *exepath, wchar_t **cmdline); +#endif + + /******************************* + * STRING BUFFER * + *******************************/ + +static void +free_ecbuf(ecbuf *b) +{ if ( b->buffer ) + { PL_free(b->buffer); + b->buffer = NULL; + } +} + + +static int +add_ecbuf(ecbuf *b, echar *data, size_t len) +{ if ( b->size + len > b->allocated ) + { size_t newsize = (b->allocated ? b->allocated * 2 : 2048); + + while( b->size + len > newsize ) + newsize *= 2; + + if ( b->buffer ) + { b->buffer = PL_realloc(b->buffer, newsize*sizeof(echar)); + } else + { b->buffer = PL_malloc(newsize*sizeof(echar)); + } + + b->allocated = newsize; + } + + memcpy(b->buffer+b->size, data, len*sizeof(echar)); + b->size += len; + + return TRUE; +} + + /******************************* + * ENVIRONMENT PARSING * + *******************************/ + +static int +get_echars_arg_ex(int i, term_t from, term_t arg, echar **sp, size_t *lenp) +{ const echar *s, *e; + + if ( !PL_get_arg(i, from, arg) ) + return FALSE; + +#ifdef __WINDOWS__ + if ( !PL_get_wchars(arg, lenp, sp, + CVT_ATOMIC|CVT_EXCEPTION) ) +#else + if ( !PL_get_nchars(arg, lenp, sp, + CVT_ATOMIC|CVT_EXCEPTION|REP_FN) ) +#endif + return FALSE; + + for(s = *sp, e = s+*lenp; senvbuf; + int count = 0, c = 0; +#ifndef __WINDOWS__ + echar *q; + char **ep; +#endif + + assert(eb->size == 0); + assert(eb->allocated == 0); + assert(eb->buffer == NULL); + + while( PL_get_list(tail, head, tail) ) + { echar *s; + size_t len; + + if ( !PL_is_functor(head, FUNCTOR_eq2) ) + return type_error(head, "environment_variable"); + + if ( !get_echars_arg_ex(1, head, tmp, &s, &len) ) + return FALSE; + add_ecbuf(eb, s, len); + add_ecbuf(eb, ECHARS("="), 1); + if ( !get_echars_arg_ex(2, head, tmp, &s, &len) ) + return FALSE; + add_ecbuf(eb, s, len); + add_ecbuf(eb, ECHARS("\0"), 1); + + count++; + } + + if ( !PL_get_nil(tail) ) + return type_error(tail, "list"); + +#ifdef __WINDOWS__ + add_ecbuf(eb, ECHARS("\0"), 1); +#else + info->envp = PL_malloc((count+1)*sizeof(char*)); + + for(ep=info->envp, c=0, q=eb->buffer; cbuffer) == eb->size); + *ep = NULL; +#endif + + return TRUE; +} + + +static int +get_stream(term_t t, p_options *info, p_stream *stream) +{ atom_t a; + + if ( PL_get_atom(t, &a) ) + { if ( a == ATOM_null ) + { stream->type = std_null; + return TRUE; + } else if ( a == ATOM_std ) + { stream->type = std_std; + return TRUE; + } else + { return domain_error(t, "process_stream"); + } + } else if ( PL_is_functor(t, FUNCTOR_pipe1) ) + { stream->term = PL_new_term_ref(); + _PL_get_arg(1, t, stream->term); + stream->type = std_pipe; + info->pipes++; + return TRUE; + } else + return type_error(t, "process_stream"); +} + + +static int +parse_options(term_t options, p_options *info) +{ term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + term_t arg = PL_new_term_ref(); + + info->window = MAYBE; + + while(PL_get_list(tail, head, tail)) + { atom_t name; + int arity; + + if ( !PL_get_name_arity(head, &name, &arity) || arity != 1 ) + return type_error(head, "option"); + _PL_get_arg(1, head, arg); + + if ( name == ATOM_stdin ) + { if ( !get_stream(arg, info, &info->streams[0]) ) + return FALSE; + } else if ( name == ATOM_stdout ) + { if ( !get_stream(arg, info, &info->streams[1]) ) + return FALSE; + } else if ( name == ATOM_stderr ) + { if ( !get_stream(arg, info, &info->streams[2]) ) + return FALSE; + } else if ( name == ATOM_process ) + { info->pid = PL_copy_term_ref(arg); + } else if ( name == ATOM_detached ) + { if ( !PL_get_bool(arg, &info->detached) ) + return type_error(arg, "boolean"); + } else if ( name == ATOM_cwd ) + { +#ifdef __WINDOWS__ + if ( !PL_get_wchars(arg, NULL, &info->cwd, + CVT_ATOM|CVT_STRING|CVT_EXCEPTION|BUF_MALLOC) ) + return FALSE; +#else + if ( !PL_get_chars(arg, &info->cwd, + CVT_ATOM|CVT_STRING|CVT_EXCEPTION|BUF_MALLOC|REP_FN) ) + return FALSE; +#endif + } else if ( name == ATOM_window ) + { if ( !PL_get_bool(arg, &info->window) ) + return type_error(arg, "boolean"); + } else if ( name == ATOM_env ) + { if ( !parse_environment(arg, info) ) + return FALSE; + } else + return domain_error(head, "process_option"); + } + + if ( !PL_get_nil(tail) ) + return type_error(tail, "list"); + + return TRUE; +} + + +static int +get_exe(term_t exe, p_options *info) +{ int arity; + term_t arg = PL_new_term_ref(); + + if ( !PL_get_name_arity(exe, &info->exe_name, &arity) ) + return type_error(exe, "callable"); + + PL_put_atom(arg, info->exe_name); + +#ifdef __WINDOWS__ + if ( !PL_get_wchars(arg, NULL, &info->exe, CVT_ATOM|CVT_EXCEPTION|BUF_MALLOC) ) + return FALSE; + if ( !win_command_line(exe, arity, info->exe, &info->cmdline) ) + return FALSE; +#else /*__WINDOWS__*/ + if ( !PL_get_chars(arg, &info->exe, CVT_ATOM|CVT_EXCEPTION|BUF_MALLOC|REP_FN) ) + return FALSE; + + info->argv = PL_malloc((arity+2)*sizeof(char*)); + memset(info->argv, 0, (arity+2)*sizeof(char*)); + info->argv[0] = strdup(info->exe); + { int i; + + for(i=1; i<=arity; i++) + { _PL_get_arg(i, exe, arg); + + if ( !PL_get_chars(arg, &info->argv[i], + CVT_ATOMIC|CVT_EXCEPTION|BUF_MALLOC|REP_FN) ) + return FALSE; + } + info->argv[i] = NULL; + } +#endif /*__WINDOWS__*/ + + return TRUE; +} + + +static void +free_options(p_options *info) /* TBD: close streams */ +{ if ( info->exe ) + { PL_free(info->exe); + info->exe = NULL; + } + if ( info->cwd ) + { PL_free(info->cwd); + info->cwd = NULL; + } +#ifndef __WINDOWS__ + if ( info->envp ) + { PL_free(info->envp); + info->envp = NULL; + } +#endif + free_ecbuf(&info->envbuf); +#ifdef __WINDOWS__ + if ( info->cmdline ) + { PL_free(info->cmdline); + info->cmdline = NULL; + } + +#else /*__WINDOWS__*/ + + if ( info->argv ) + { char **a; + for(a=info->argv; *a; a++) + { if ( *a ) + PL_free(*a); + } + PL_free(info->argv); + + info->argv = NULL; + } + +#endif /*__WINDOWS__*/ +} + + + /******************************* + * PROCESS READS * + *******************************/ + +#define PROCESS_MAGIC 0x29498001 + +typedef struct process_context +{ int magic; /* PROCESS_MAGIC */ +#ifdef __WINDOWS__ + HANDLE handle; /* process handle */ +#else + pid_t pid; /* the process id */ +#endif + int open_mask; /* Open streams */ + int pipes[3]; /* stdin/stdout/stderr */ +} process_context; + +static int wait_for_process(process_context *pc); + +static int +process_fd(void *handle, process_context **PC) +{ process_context *pc = (process_context*) ((uintptr_t)handle&~(uintptr_t)0x3); + int pipe = (int)(uintptr_t)handle & 0x3; + + if ( pc->magic == PROCESS_MAGIC ) + { if ( PC ) + *PC = pc; + return pc->pipes[pipe]; + } + + return -1; +} + + +static ssize_t +Sread_process(void *handle, char *buf, size_t size) +{ int fd = process_fd(handle, NULL); + + return (*Sfilefunctions.read)((void*)(uintptr_t)fd, buf, size); +} + + +static ssize_t +Swrite_process(void *handle, char *buf, size_t size) +{ int fd = process_fd(handle, NULL); + + return (*Sfilefunctions.write)((void*)(uintptr_t)fd, buf, size); +} + + +static int +Sclose_process(void *handle) +{ process_context *pc; + int fd = process_fd(handle, &pc); + + if ( fd >= 0 ) + { int which = (int)(uintptr_t)handle & 0x3; + int rc; + + rc = (*Sfilefunctions.close)((void*)(uintptr_t)fd); + pc->open_mask &= ~(1<open_mask)); + + if ( !pc->open_mask ) + { int rcw = wait_for_process(pc); + + return rcw ? 0 : -1; + } + + return rc; + } + + return -1; +} + + +static int +Scontrol_process(void *handle, int action, void *arg) +{ process_context *pc; + int fd = process_fd(handle, &pc); + + switch(action) + { case SIO_GETFILENO: + { int *fdp = arg; + *fdp = fd; + return 0; + } + default: + return (*Sfilefunctions.control)((void*)(uintptr_t)fd, action, arg); + } +} + + +static IOFUNCTIONS Sprocessfunctions = +{ Sread_process, + Swrite_process, + NULL, /* seek */ + Sclose_process, + Scontrol_process, + NULL /* seek64 */ +}; + + +static IOSTREAM * +#ifdef __WINDOWS__ +open_process_pipe(process_context *pc, int which, HANDLE fd) +#else +open_process_pipe(process_context *pc, int which, int fd) +#endif +{ void *handle; + int flags; + + pc->open_mask |= (1<pipes[which] = _open_osfhandle((long)fd, _O_BINARY); +#else + pc->pipes[which] = fd; +#endif + +#define ISO_FLAGS (SIO_RECORDPOS|SIO_FBUF|SIO_TEXT) + + if ( which == 0 ) + flags = SIO_OUTPUT|ISO_FLAGS; + else + flags = SIO_INPUT|ISO_FLAGS; + + handle = (void *)((uintptr_t)pc | (uintptr_t)which); + + return Snew(handle, flags, &Sprocessfunctions); +} + + + /******************************* + * OS STUFF * + *******************************/ + + +#ifdef __WINDOWS__ + +CRITICAL_SECTION process_lock; +#define LOCK() EnterCriticalSection(&process_lock); +#define UNLOCK() LeaveCriticalSection(&process_lock); + +static void +win_init() +{ InitializeCriticalSection(&process_lock); +} + + +static atom_t +WinError() +{ int id = GetLastError(); + char *msg; + static WORD lang; + static lang_initialised = 0; + + if ( !lang_initialised ) + lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK); + +again: + if ( FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| + FORMAT_MESSAGE_IGNORE_INSERTS| + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, /* source */ + id, /* identifier */ + lang, + (LPTSTR) &msg, + 0, /* size */ + NULL) ) /* arguments */ + { atom_t a = PL_new_atom(msg); + + LocalFree(msg); + lang_initialised = 1; + + return a; + } else + { if ( lang_initialised == 0 ) + { lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + lang_initialised = 1; + goto again; + } + + return PL_new_atom("Unknown Windows error"); + } +} + + +static int +win_error(const char *op) +{ atom_t msg = WinError(); + term_t ex = PL_new_term_ref(); + + PL_unify_term(ex, PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_system_error2, + PL_CHARS, op, + PL_ATOM, msg, + PL_VARIABLE); + + return PL_raise_exception(ex); +} + + +typedef struct arg_string +{ size_t len; + wchar_t *text; + wchar_t quote; +} arg_string; + +#define QMISC 0x1 +#define QDBLQ 0x2 +#define QSBLQ 0x4 + +static int +set_quote(arg_string *as) +{ int needq = 0; + const wchar_t *s = as->text; + + for(; *s; s++) + { if ( !iswalnum(*s) ) + { if ( *s == '"' ) + needq |= QDBLQ; + else if ( *s == '\'' ) + needq |= QSBLQ; + else + needq |= QMISC; + } + } + + if ( !needq ) + { as->quote = 0; + return TRUE; + } + needq &= ~QMISC; + switch( needq ) + { case QDBLQ: + as->quote = '\''; + return TRUE; + case 0: + case QSBLQ: + as->quote = '"'; + return TRUE; + default: + return FALSE; + } +} + + +static int +win_command_line(term_t t, int arity, const wchar_t *exe, wchar_t **cline) +{ if ( arity > 0 ) + { arg_string *av = PL_malloc((arity+1)*sizeof(*av)); + term_t arg = PL_new_term_ref(); + size_t cmdlen; + wchar_t *cmdline, *o; + const wchar_t *b; + int i; + + if ( (b=wcsrchr(exe, '\\')) ) + b++; + else + b = exe; + av[0].text = (wchar_t*)b; + av[0].len = wcslen(av[0].text); + set_quote(&av[0]); + cmdlen = av[0].len+(av[0].quote?2:0)+1; + + for( i=1; i<=arity; i++) + { PL_get_arg(i, t, arg); + + if ( !PL_get_wchars(arg, &av[i].len, &av[i].text, + CVT_ATOMIC|CVT_EXCEPTION|BUF_MALLOC) ) + return FALSE; + + if ( wcslen(av[i].text) != av[i].len ) + return domain_error(arg, "no_zero_code_atom"); + + if ( !set_quote(&av[i]) ) + return domain_error(arg, "dos_quotable_atom"); + + cmdlen += av[i].len+(av[i].quote?2:0)+1; + } + + cmdline = PL_malloc(cmdlen*sizeof(wchar_t)); + for( o=cmdline,i=0; i<=arity; ) + { wchar_t *s = av[i].text; + + if ( av[i].quote ) + *o++ = av[i].quote; + wcsncpy(o, s, av[i].len); + o += av[i].len; + if ( i > 0 ) + PL_free(s); /* do not free shared exename */ + if ( av[i].quote ) + *o++ = av[i].quote; + + if (++i <= arity) + *o++ = ' '; + } + *o = 0; + PL_free(av); + + *cline = cmdline; + } else + { *cline = NULL; + } + + return TRUE; +} + + +typedef struct win_process +{ DWORD pid; + HANDLE handle; + struct win_process *next; +} win_process; + + +static win_process *processes; + +static void +register_process(DWORD pid, HANDLE h) +{ win_process *wp = PL_malloc(sizeof(*wp)); + + wp->pid = pid; + wp->handle = h; + LOCK(); + wp->next = processes; + processes = wp; + UNLOCK(); +} + + +static int +unregister_process(DWORD pid) +{ win_process **wpp, *wp; + + LOCK(); + for(wpp=&processes, wp=*wpp; wp; wpp=&wp->next, wp=*wpp) + { if ( wp->pid == pid ) + { *wpp = wp->next; + PL_free(wp); + UNLOCK(); + return TRUE; + } + } + + UNLOCK(); + return FALSE; +} + + +static HANDLE +find_process_from_pid(DWORD pid, const char *pred) +{ win_process *wp; + + LOCK(); + for(wp=processes; wp; wp=wp->next) + { if ( wp->pid == pid ) + { HANDLE h = wp->handle; + UNLOCK(); + return h; + } + } + + UNLOCK(); + + if ( pred ) + { term_t ex = PL_new_term_ref(); + + PL_put_integer(ex, pid); + pl_error(NULL, 2, NULL, ERR_EXISTENCE, + "process", ex); + } + + return (HANDLE)0; +} + + +#define WP_TIMEOUT 2 + +static int +wait_process_handle(HANDLE process, ULONG *rc, DWORD timeout) +{ DWORD wc; + +retry: + wc = MsgWaitForMultipleObjects(1, + &process, + FALSE, /* return on any event */ + timeout, + QS_ALLINPUT); + + switch(wc) + { case WAIT_OBJECT_0: + if ( !GetExitCodeProcess(process, rc) ) + { win_error("GetExitCodeProcess"); + CloseHandle(process); + return FALSE; + } + CloseHandle(process); + return TRUE; + case WAIT_OBJECT_0+1: + { MSG msg; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + if ( PL_handle_signals() < 0 ) + return FALSE; + } + goto retry; + } + case WAIT_TIMEOUT: + return WP_TIMEOUT; + default: + win_error("WaitForSingleObject"); + CloseHandle(process); + return FALSE; + } +} + + +static int +wait_for_pid(pid_t pid, term_t code, wait_options *opts) +{ HANDLE *h; + + if ( (h=find_process_from_pid(pid, "process_wait")) ) + { ULONG rc; + DWORD timeout; + int wc; + + if ( opts->has_timeout ) + timeout = (DWORD)(opts->timeout * 1000.0); + else + timeout = INFINITE; + + if ( !(wc=wait_process_handle(h, &rc, timeout)) ) + return FALSE; + if ( wc == WP_TIMEOUT ) + return PL_unify_atom(code, ATOM_timeout); + + unregister_process(pid); + + return PL_unify_term(code, + PL_FUNCTOR, FUNCTOR_exit1, + PL_LONG, rc); + } else + { return FALSE; + } +} + + +static int +wait_for_process(process_context *pc) +{ int rc; + ULONG prc; + + rc = wait_process_handle(pc->handle, &prc, INFINITE); + CloseHandle(pc->handle); + PL_free(pc); + + return rc; +} + + +static int +win_wait_success(atom_t exe, HANDLE process) +{ ULONG rc; + + if ( !wait_process_handle(process, &rc, INFINITE) ) + return FALSE; + + if ( rc != 0 ) + { term_t code = PL_new_term_ref(); + term_t ex = PL_new_term_ref(); + + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_process_error2, + PL_ATOM, exe, + PL_FUNCTOR, FUNCTOR_exit1, + PL_LONG, rc, + PL_VARIABLE); + return PL_raise_exception(ex); + } + + return TRUE; +} + + +static int +create_pipes(p_options *info) +{ int i; + SECURITY_ATTRIBUTES sa; + + sa.nLength = sizeof(sa); /* Length in bytes */ + sa.bInheritHandle = 1; /* the child must inherit these handles */ + sa.lpSecurityDescriptor = NULL; + + for(i=0; i<3; i++) + { p_stream *s = &info->streams[i]; + + if ( s->term ) + { if ( !CreatePipe(&s->fd[0], &s->fd[1], &sa, 1<<13) ) + { return win_error("CreatePipe"); + } + } + } + + return TRUE; +} + + +static IOSTREAM * +Sopen_handle(HANDLE h, const char *mode) +{ return Sfdopen(_open_osfhandle((long)h, _O_BINARY), mode); +} + + +static HANDLE +open_null_stream(DWORD access) +{ SECURITY_ATTRIBUTES sa; + + sa.nLength = sizeof(sa); /* Length in bytes */ + sa.bInheritHandle = 1; /* the child must inherit these handles */ + sa.lpSecurityDescriptor = NULL; + + return CreateFile("nul", + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, /* security */ + OPEN_EXISTING, + 0, + NULL); +} + + +static int +console_app(void) +{ HANDLE h; + + if ( (h = GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE ) + { DWORD mode; + + if ( GetConsoleMode(h, &mode) ) + return TRUE; + } + + return FALSE; +} + + +static int +do_create_process(p_options *info) +{ int flags = 0; + PROCESS_INFORMATION pi; + STARTUPINFOW si; + + switch(info->window) + { case MAYBE: + if ( !console_app() ) + flags |= CREATE_NO_WINDOW; + break; + case TRUE: + break; + case FALSE: + flags |= CREATE_NO_WINDOW; + break; + } + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + + /* stdin */ + switch( info->streams[0].type ) + { case std_pipe: + si.hStdInput = info->streams[0].fd[0]; + SetHandleInformation(info->streams[0].fd[1], + HANDLE_FLAG_INHERIT, FALSE); + break; + case std_null: + si.hStdInput = open_null_stream(GENERIC_READ); + break; + case std_std: + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + break; + } + /* stdout */ + switch( info->streams[1].type ) + { case std_pipe: + si.hStdOutput = info->streams[1].fd[1]; + SetHandleInformation(info->streams[1].fd[0], + HANDLE_FLAG_INHERIT, FALSE); + break; + case std_null: + si.hStdOutput = open_null_stream(GENERIC_WRITE); + break; + case std_std: + si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + break; + } + /* stderr */ + switch( info->streams[2].type ) + { case std_pipe: + si.hStdError = info->streams[2].fd[1]; + SetHandleInformation(info->streams[2].fd[0], + HANDLE_FLAG_INHERIT, FALSE); + break; + case std_null: + si.hStdError = open_null_stream(GENERIC_WRITE); + break; + case std_std: + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); + break; + } + + if ( CreateProcessW(info->exe, + info->cmdline, + NULL, /* Process security */ + NULL, /* Thread security */ + TRUE, /* Inherit handles */ + flags, /* Creation flags */ + info->envbuf.buffer, /* Environment */ + info->cwd, /* Directory */ + &si, /* Startup info */ + &pi) ) /* Process information */ + { CloseHandle(pi.hThread); + + if ( info->pipes > 0 && info->pid == 0 ) + { IOSTREAM *s; + process_context *pc = PL_malloc(sizeof(*pc)); + + DEBUG(Sdprintf("Wait on pipes\n")); + + memset(pc, 0, sizeof(*pc)); + pc->magic = PROCESS_MAGIC; + pc->handle = pi.hProcess; + + if ( info->streams[0].type == std_pipe ) + { CloseHandle(info->streams[0].fd[0]); + s = open_process_pipe(pc, 0, info->streams[0].fd[1]); + PL_unify_stream(info->streams[0].term, s); + } + if ( info->streams[1].type == std_pipe ) + { CloseHandle(info->streams[1].fd[1]); + s = open_process_pipe(pc, 1, info->streams[1].fd[0]); + PL_unify_stream(info->streams[1].term, s); + } + if ( info->streams[2].type == std_pipe ) + { CloseHandle(info->streams[2].fd[1]); + s = open_process_pipe(pc, 2, info->streams[2].fd[0]); + PL_unify_stream(info->streams[2].term, s); + } + + return TRUE; + } else if ( info->pipes > 0 ) + { IOSTREAM *s; + + if ( info->streams[0].type == std_pipe ) + { CloseHandle(info->streams[0].fd[0]); + s = Sopen_handle(info->streams[0].fd[1], "w"); + PL_unify_stream(info->streams[0].term, s); + } + if ( info->streams[1].type == std_pipe ) + { CloseHandle(info->streams[1].fd[1]); + s = Sopen_handle(info->streams[1].fd[0], "r"); + PL_unify_stream(info->streams[1].term, s); + } + if ( info->streams[2].type == std_pipe ) + { CloseHandle(info->streams[2].fd[1]); + s = Sopen_handle(info->streams[2].fd[0], "r"); + PL_unify_stream(info->streams[2].term, s); + } + } + + if ( info->pid ) + { register_process(pi.dwProcessId, pi.hProcess); + return PL_unify_integer(info->pid, pi.dwProcessId); + } + + return win_wait_success(info->exe_name, pi.hProcess); + } else + { return win_error("CreateProcess"); + } +} + +#else /*__WINDOWS__*/ + +static int +create_pipes(p_options *info) +{ int i; + + for(i=0; i<3; i++) + { p_stream *s = &info->streams[i]; + + if ( s->term ) + { if ( pipe(s->fd) ) + { assert(errno = EMFILE); + return resource_error("open_files"); + } + } + } + + return TRUE; +} + + +static int +unify_exit_status(term_t code, int status) +{ if ( WIFEXITED(status) ) + { return PL_unify_term(code, + PL_FUNCTOR, FUNCTOR_exit1, + PL_INT, (int)WEXITSTATUS(status)); + } else if ( WIFSIGNALED(status) ) + { return PL_unify_term(code, + PL_FUNCTOR, FUNCTOR_killed1, + PL_INT, (int)WTERMSIG(status)); + } else + { assert(0); + return FALSE; + } +} + + +static int +wait_for_pid(pid_t pid, term_t code, wait_options *opts) +{ pid_t p2; + int status; + + if ( opts->has_timeout && opts->timeout == 0.0 ) + { if ( (p2=waitpid(pid, &status, WNOHANG)) == pid ) + return unify_exit_status(code, status); + else if ( p2 == 0 ) + return PL_unify_atom(code, ATOM_timeout); + else + { term_t PID; + + error: + return ((PID = PL_new_term_ref()) && + PL_put_integer(PID, pid) && + pl_error(NULL, 0, "waitpid", ERR_ERRNO, + errno, "wait", "process", PID)); + } + } + + for(;;) + { if ( (p2=waitpid(pid, &status, 0)) == pid ) + return unify_exit_status(code, status); + + if ( p2 == -1 && errno == EINTR ) + { if ( PL_handle_signals() < 0 ) + return FALSE; + } else + { goto error; + } + } +} + + +static int +wait_for_process(process_context *pc) +{ for(;;) + { int status; + pid_t p2; + + if ( (p2=waitpid(pc->pid, &status, 0)) == pc->pid ) + { PL_free(pc); + return TRUE; + } + + if ( errno == EINTR && PL_handle_signals() >= 0 ) + continue; + + PL_free(pc); + return FALSE; + } +} + + +static int +wait_success(atom_t name, pid_t pid) +{ pid_t p2; + + for(;;) + { int status; + + if ( (p2=waitpid(pid, &status, 0)) == pid ) + { if ( WIFEXITED(status) && WEXITSTATUS(status) == 0 ) + { return TRUE; + } else + { term_t code, ex; + + if ( (code = PL_new_term_ref()) && + (ex = PL_new_term_ref()) && + unify_exit_status(code, status) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_process_error2, + PL_ATOM, name, + PL_TERM, code, + PL_VARIABLE) ) + return PL_raise_exception(ex); + return FALSE; + } + } + + if ( p2 == -1 && errno == EINTR ) + { if ( PL_handle_signals() < 0 ) + return FALSE; + } + } +} + + +static int +do_create_process(p_options *info) +{ int pid; + + if ( !(pid=fork()) ) /* child */ + { int fd; + int rc; + + PL_cleanup_fork(); + + if ( info->detached ) + setsid(); + + if ( info->cwd ) + { if ( chdir(info->cwd) ) + { perror(info->cwd); + exit(1); + } + } + + /* stdin */ + switch( info->streams[0].type ) + { case std_pipe: + dup2(info->streams[0].fd[0], 0); + close(info->streams[0].fd[1]); + break; + case std_null: + if ( (fd = open("/dev/null", O_RDONLY)) >= 0 ) + dup2(fd, 0); + break; + case std_std: + break; + } + /* stdout */ + switch( info->streams[1].type ) + { case std_pipe: + dup2(info->streams[1].fd[1], 1); + close(info->streams[1].fd[0]); + break; + case std_null: + if ( (fd = open("/dev/null", O_WRONLY)) >= 0 ) + dup2(fd, 1); + break; + case std_std: + break; + } + /* stderr */ + switch( info->streams[2].type ) + { case std_pipe: + dup2(info->streams[2].fd[1], 2); + close(info->streams[2].fd[0]); + break; + case std_null: + if ( (fd = open("/dev/null", O_WRONLY)) >= 0 ) + dup2(fd, 2); + break; + case std_std: + break; + } + + if ( info->envp ) + rc = execve(info->exe, info->argv, info->envp); + else + rc = execv(info->exe, info->argv); + + if ( rc ) + { perror(info->exe); + exit(1); + } + + { term_t exe = PL_new_term_ref(); + PL_put_atom_chars(exe, info->exe); + + return pl_error(NULL, 0, "execv", ERR_ERRNO, errno, "exec", "process", exe); + } + } else /* parent */ + { if ( info->pipes > 0 && info->pid == 0 ) + { IOSTREAM *s; + process_context *pc = PL_malloc(sizeof(*pc)); + + DEBUG(Sdprintf("Wait on pipes\n")); + + memset(pc, 0, sizeof(*pc)); + pc->magic = PROCESS_MAGIC; + pc->pid = pid; + + if ( info->streams[0].type == std_pipe ) + { close(info->streams[0].fd[0]); + s = open_process_pipe(pc, 0, info->streams[0].fd[1]); + PL_unify_stream(info->streams[0].term, s); + } + if ( info->streams[1].type == std_pipe ) + { close(info->streams[1].fd[1]); + s = open_process_pipe(pc, 1, info->streams[1].fd[0]); + PL_unify_stream(info->streams[1].term, s); + } + if ( info->streams[2].type == std_pipe ) + { close(info->streams[2].fd[1]); + s = open_process_pipe(pc, 2, info->streams[2].fd[0]); + PL_unify_stream(info->streams[2].term, s); + } + + return TRUE; + } else if ( info->pipes > 0 ) + { IOSTREAM *s; + + if ( info->streams[0].type == std_pipe ) + { close(info->streams[0].fd[0]); + s = Sfdopen(info->streams[0].fd[1], "w"); + PL_unify_stream(info->streams[0].term, s); + } + if ( info->streams[1].type == std_pipe ) + { close(info->streams[1].fd[1]); + s = Sfdopen(info->streams[1].fd[0], "r"); + PL_unify_stream(info->streams[1].term, s); + } + if ( info->streams[2].type == std_pipe ) + { close(info->streams[2].fd[1]); + s = Sfdopen(info->streams[2].fd[0], "r"); + PL_unify_stream(info->streams[2].term, s); + } + } + + if ( info->pid ) + return PL_unify_integer(info->pid, pid); + + return wait_success(info->exe_name, pid); + } +} + +#endif /*__WINDOWS__*/ + + + /******************************* + * BINDING * + *******************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Basic process creation interface takes + + * Exe file + * List of arguments + * standard streams % std, null, pipe(S) + * Working directory + * detached % Unix + * window % Windows +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static foreign_t +process_create(term_t exe, term_t options) +{ p_options info; + int rc = FALSE; + + memset(&info, 0, sizeof(info)); + + if ( !get_exe(exe, &info) ) + goto out; + if ( !parse_options(options, &info) ) + goto out; + if ( !create_pipes(&info) ) + goto out; + + rc = do_create_process(&info); + +out: + free_options(&info); + + return rc; +} + + +static int +get_pid(term_t pid, pid_t *p) +{ int n; + + if ( !PL_get_integer(pid, &n) ) + return type_error(pid, "integer"); + if ( n < 0 ) + return domain_error(pid, "not_less_than_zero"); + + *p = n; + return TRUE; +} + + +static foreign_t +process_wait(term_t pid, term_t code, term_t options) +{ pid_t p; + wait_options opts; + term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + term_t arg = PL_new_term_ref(); + + if ( !get_pid(pid, &p) ) + return FALSE; + + memset(&opts, 0, sizeof(opts)); + while(PL_get_list(tail, head, tail)) + { atom_t name; + int arity; + + if ( !PL_get_name_arity(head, &name, &arity) || arity != 1 ) + return type_error(head, "option"); + _PL_get_arg(1, head, arg); + if ( name == ATOM_timeout ) + { atom_t a; + + if ( !(PL_get_atom(arg, &a) && a == ATOM_infinite) ) + { if ( !PL_get_float(arg, &opts.timeout) ) + return type_error(arg, "timeout"); + opts.has_timeout = TRUE; + } + } else if ( name == ATOM_release ) + { if ( !PL_get_bool(arg, &opts.release) ) + return type_error(arg, "boolean"); + if ( opts.release == FALSE ) + return domain_error(arg, "true"); + } else + return domain_error(head, "process_wait_option"); + } + if ( !PL_get_nil(tail) ) + return type_error(tail, "list"); + + return wait_for_pid(p, code, &opts); +} + + +static foreign_t +process_kill(term_t pid, term_t signal) +{ int p; + + if ( !get_pid(pid, &p) ) + return FALSE; + +{ +#ifdef __WINDOWS__ + HANDLE h; + + if ( !(h=find_process_from_pid(p, "process_kill")) ) + return FALSE; + + if ( TerminateProcess(h, 255) ) + return TRUE; + + return win_error("TerminateProcess"); +#else /*__WINDOWS__*/ + int sig; + + if ( !PL_get_signum_ex(signal, &sig) ) + return FALSE; + + if ( kill(p, sig) == 0 ) + return TRUE; + + switch(errno) + { case EPERM: + return pl_error("process_kill", 2, NULL, ERR_PERMISSION, + pid, "kill", "process"); + case ESRCH: + return pl_error("process_kill", 2, NULL, ERR_EXISTENCE, + "process", pid); + default: + return pl_error("process_kill", 2, "kill", ERR_ERRNO, errno, "kill", "process", pid); + } +#endif /*__WINDOWS__*/ +} +} + + +#define MKATOM(n) ATOM_ ## n = PL_new_atom(#n) +#define MKFUNCTOR(n,a) FUNCTOR_ ## n ## a = PL_new_functor(PL_new_atom(#n), a) + +install_t +install_process() +{ +#ifdef __WINDOWS__ + win_init(); +#endif + + MKATOM(stdin); + MKATOM(stdout); + MKATOM(stderr); + MKATOM(std); + MKATOM(null); + MKATOM(process); + MKATOM(detached); + MKATOM(cwd); + MKATOM(env); + MKATOM(window); + MKATOM(timeout); + MKATOM(release); + MKATOM(infinite); + + MKFUNCTOR(pipe, 1); + MKFUNCTOR(error, 2); + MKFUNCTOR(type_error, 2); + MKFUNCTOR(domain_error, 2); + MKFUNCTOR(process_error, 2); + MKFUNCTOR(system_error, 2); + MKFUNCTOR(resource_error, 1); + MKFUNCTOR(exit, 1); + MKFUNCTOR(killed, 1); + + FUNCTOR_eq2 = PL_new_functor(PL_new_atom("="), 2); + + PL_register_foreign("process_create", 2, process_create, 0); + PL_register_foreign("process_wait", 3, process_wait, 0); + PL_register_foreign("process_kill", 2, process_kill, 0); +} diff --git a/packages/clib/process.pl b/packages/clib/process.pl new file mode 100644 index 000000000..0dfe35652 --- /dev/null +++ b/packages/clib/process.pl @@ -0,0 +1,333 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemak@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2008-2009, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(process, + [ process_create/3, % +Exe, +Args, +Options + process_wait/2, % +PID, -Status + process_wait/3, % +PID, -Status, +Options + process_id/1, % -PID + process_id/2, % +Process, -PID + is_process/1, % +PID + process_release/1, % +PID + process_kill/1, % +PID + process_kill/2 % +PID, -Signal + ]). +:- use_module(library(shlib)). +:- use_module(library(lists)). +:- use_module(library(option)). + +:- use_foreign_library(foreign(process)). + +/** Create processes and redirect I/O + +The module library(process) implements interaction with child processes +and unifies older interfaces such as shell/[1,2], open(pipe(command), +...) etc. This library is modelled after SICStus 4. + +The main interface is formed by process_create/3. If the process id is +requested the process must be waited for using process_wait/2. Otherwise +the process resources are reclaimed automatically. + +In addition to the predicates, this module defines a file search path +(see user:file_search_path/2 and absolute_file_name/3) named =path= that +locates files on the system's search path for executables. E.g. the +following finds the executable for =ls=: + + == + ?- absolute_file_name(path(ls), Path, [access(execute)]). + == + +*|Incompatibilities and current limitations|* + + * Where SICStus distinguishes between an internal process id and + the OS process id, this implements does not make this distinction. + This implies that is_process/1 is incomplete and unreliable. + + * SICStus only supports ISO 8859-1 (latin-1). This implementation + supports arbitrary OS multibyte interaction using the default + locale. + + * It is unclear what the detached(true) option is supposed to do. Disable + signals in the child? Use setsid() to detach from the session? The + current implementation uses setsid() + + * An extra option env([Name=Value, ...]) is added to + process_create/3. + +@tbd Implement detached option in process_create/3 +@compat SICStus 4 +*/ + + + /******************************* + * PATH HANDLING * + *******************************/ + +:- multifile + user:file_search_path/2. +:- dynamic + user:file_search_path/2. + +user:file_search_path(path, Dir) :- + getenv('PATH', Path), + ( current_prolog_flag(windows, true) + -> atomic_list_concat(Dirs, (;), Path) + ; atomic_list_concat(Dirs, :, Path) + ), + member(Dir, Dirs). + + +%% process_create(+Exe, +Args:list, +Options) is det. +% +% Create a new process running the file Exe and using arguments +% from the given list. Exe is a file specification as handed to +% absolute_file_name/3. Typically one use the =path= file alias to +% specify an executable file on the current PATH. Args is a list +% of arguments that are handed to the new process. On Unix +% systems, each element in the list becomes a seperate argument in +% the new process. In Windows, the arguments are simply +% concatenated to form the commandline. Each argument itself is +% either a primitive or a list of primitives. A primitive is +% either atomic or a term file(Spec). Using file(Spec), the system +% inserts a filename using the OS filename conventions which is +% properly quoted if needed. +% +% Options: +% +% * stdin(Spec) +% * stdout(Spec) +% * stderr(Spec) +% Bind the standard streams of the new process. Spec is one of +% the terms below. If pipe(Pipe) is used, the Prolog stream is +% a stream in text-mode using the encoding of the default +% locale. The encoding can be changed using set_stream/2. +% +% * std +% Just share with the Prolog I/O streams +% * null +% Bind to a _null_ stream. Reading from such a stream +% returns end-of-file, writing produces no output +% * pipe(-Stream) +% Attach input and/or output to a Prolog stream. +% +% * cwd(+Directory) +% Run the new process in Directory. Directory can be a +% compound specification, which is converted using +% absolute_file_name/3. +% * env(+List) +% Specify the environment for the new process. List is +% a list of Name=Value terms. Note that the current +% implementation does not pass any environment variables. +% If unspecified, the environment is inherited from the +% Prolog process. +% * process(-PID) +% Unify PID with the process id of the created process. +% * detached(+Bool) +% If =true=, detach the process from the terminal (Unix only) +% Currently mapped to setsid(); +% * window(+Bool) +% If =true=, create a window for the process (Windows only) +% +% If the user specifies the process(-PID) option, he *must* call +% process_wait/2 to reclaim the process. Without this option, the +% system will wait for completion of the process after the last +% pipe stream is closed. +% +% If the process is not waited for, it must succeed with status 0. +% If not, an process_error is raised. +% +% *|Windows notes|* +% +% On Windows this call is an interface to the CreateProcess() API. +% The commandline consists of the basename of Exe and the +% arguments formed from Args. Arguments are separated by a single +% space. If all characters satisfy iswalnum() it is unquoted. If +% the argument contains a double-quote it is quoted using single +% quotes. If both single and double quotes appear a domain_error +% is raised, otherwise double-quote are used. +% +% The CreateProcess() API has many options. Currently only the +% =CREATE_NO_WINDOW= options is supported through the +% window(+Bool) option. If omitted, the default is to use this +% option if the application has no console. Future versions are +% likely to support more window specific options and replace +% win_exec/2. +% +% *Examples* +% +% First, a very simple example that behaves the same as +% =|shell('ls -l')|=, except for error handling: +% +% == +% ?- process_create(path(ls), ['-l'], []). +% == +% +% @tbd The detach options is a no-op. +% @error process_error(Exe, Status) where Status is one of +% exit(Code) or killed(Signal). Raised if the process +% does not exit with status 0. + +process_create(Exe, Args, Options) :- + exe_options(ExeOptions), + absolute_file_name(Exe, PlProg, ExeOptions), + must_be(list, Args), + maplist(map_arg, Args, Av), + prolog_to_os_filename(PlProg, Prog), + Term =.. [Prog|Av], + expand_cwd_option(Options, Options1), + process_create(Term, Options1). + +exe_options(Options) :- + current_prolog_flag(windows, true), !, + Options = [ extensions(['',exe,com]), access(read) ]. +exe_options(Options) :- + Options = [ access(execute) ]. + +expand_cwd_option(Options0, Options) :- + select_option(cwd(Spec), Options0, Options1), !, + ( compound(Spec) + -> absolute_file_name(Spec, PlDir, [file_type(directory), access(read)]), + prolog_to_os_filename(PlDir, Dir), + Options = [cwd(Dir)|Options1] + ; exists_directory(Spec) + -> Options = Options0 + ; existence_error(directory, Spec) + ). +expand_cwd_option(Options, Options). + + +%% map_arg(+ArgIn, -Arg) is det. +% +% Map an individual argument. Primitives are either file(Spec) or +% an atomic value (atom, string, number). If ArgIn is a non-empty +% list, all elements are converted and the results are +% concatenated. + +map_arg([], []) :- !. +map_arg(List, Arg) :- + is_list(List), !, + maplist(map_arg_prim, List, Prims), + atomic_list_concat(Prims, Arg). +map_arg(Prim, Arg) :- + map_arg_prim(Prim, Arg). + +map_arg_prim(file(Spec), File) :- !, + ( compound(Spec) + -> absolute_file_name(Spec, PlFile) + ; PlFile = Spec + ), + prolog_to_os_filename(PlFile, File). +map_arg_prim(Arg, Arg). + + +%% process_id(-PID) is det. +% +% True if PID is the process id of the running Prolog process. +% +% @deprecated Use current_prolog_flag(pid, PID) + +process_id(PID) :- + current_prolog_flag(pid, PID). + +%% process_id(+Process, -PID) is det. +% +% PID is the process id of Process. Given that they are united in +% SWI-Prolog, this is a simple unify. + +process_id(PID, PID). + +%% is_process(+PID) is semidet. +% +% True if PID might be a process. Succeeds for any positive +% integer. + +is_process(PID) :- + integer(PID), + PID > 0. + +%% process_release(+PID) +% +% Release process handle. In this implementation this is the same +% as process_wait(PID, _). + +process_release(PID) :- + process_wait(PID, _). + +%% process_wait(+PID, -Status) is det. +%% process_wait(+PID, -Status, +Options) is det. +% +% True if PID completed with Status. This call normally blocks +% until the process is finished. Options: +% +% * timeout(+Timeout) +% Default: =infinite=. If this option is a number, the +% waits for a maximum of Timeout seconds and unifies Status +% with =timeout= if the process does not terminate within +% Timeout. In this case PID is _not_ invalidated. On Unix +% systems only timeout 0 and =infinite= are supported. A +% 0-value can be used to poll the status of the process. +% +% * release(+Bool) +% Do/do not release the process. We do not support this flag +% and a domain_error is raised if release(false) is provided. + +process_wait(PID, Status) :- + process_wait(PID, Status, []). + +%% process_kill(+PID) is det. +%% process_kill(+PID, +Signal) is det. +% +% Send signal to process PID. Default is =term=. Signal is an +% integer, Unix signal name (e.g. =SIGSTOP=) or the more Prolog +% friendly variation one gets after removing =SIG= and downcase +% the result: =stop=. On Windows systems, Signal is ignored and +% the process is terminated using the TerminateProcess() API. On +% Windows systems PID must be obtained from process_create/3, +% while any PID is allowed on Unix systems. +% +% @compat SICStus does not accept the prolog friendly version. We +% choose to do so for compatibility with on_signal/3. + +process_kill(PID) :- + process_kill(PID, term). + + + /******************************* + * MESSAGES * + *******************************/ + +:- multifile + prolog:error_message/3. + +prolog:error_message(process_error(File, exit(Status))) --> + [ 'Process "~w": exit status: ~w'-[File, Status] ]. +prolog:error_message(process_error(File, killed(Signal))) --> + [ 'Process "~w": killed by signal ~w'-[File, Signal] ]. diff --git a/packages/clib/prolog_server.pl b/packages/clib/prolog_server.pl new file mode 100644 index 000000000..4e096cd8c --- /dev/null +++ b/packages/clib/prolog_server.pl @@ -0,0 +1,123 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker & Steve Prior + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2007, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(prolog_server, + [ prolog_server/2 % +Port, +Options + ]). + +:- use_module(library(socket)). + +%% prolog_server(?Port, +Options) +% +% Create a TCP/IP based server on the given Port, so you can +% telnet into Prolog and run an interactive session. This library +% is intended to provide access for debugging and management of +% embedded servers. +% +% Currently defined options are: +% +% * allow(IP) +% Allow access from IP, a term of the format ip(A,B,C,D). +% Multiple of such terms can exist and access is granted +% if the peer IP address unifies to one of them. If no +% allow option is provided access is only granted from +% ip(127,0,0,1) (localhost). +% +% For example: +% +% == +% ?- prolog_server(4000, []). +% +% % telnet localhost 4000 +% Welcome to the SWI-Prolog server on thread 3 +% +% 1 ?- +% == +% +% @bug As the connection does not involve a terminal, command history +% and completion are not provided. Neither are interrupts +% (Control-C). To terminate the Prolog shell one must enter the +% command "end_of_file." + + +prolog_server(Port, Options) :- + tcp_socket(ServerSocket), + tcp_setopt(ServerSocket, reuseaddr), + tcp_bind(ServerSocket, Port), + tcp_listen(ServerSocket, 5), + thread_create(server_loop(ServerSocket, Options), _, + [ alias(prolog_server) + ]). + +server_loop(ServerSocket, Options) :- + tcp_accept(ServerSocket, Slave, Peer), + tcp_open_socket(Slave, InStream, OutStream), + tcp_host_to_address(Host, Peer), + atom_concat('client@', Host, Alias), + thread_create(service_client(InStream, OutStream, Peer, Options), + _, + [ alias(Alias) + ]), + server_loop(ServerSocket, Options). + +service_client(InStream, OutStream, Peer, Options) :- + allow(Peer, Options), !, + thread_self(Id), + set_prolog_IO(InStream, OutStream, OutStream), + set_stream(InStream, tty(true)), + format(user_error, + 'Welcome to the SWI-Prolog server on thread ~w~n~n', + [Id]), + call_cleanup(run_prolog, + ( close(InStream), + close(OutStream), + thread_detach(Id))). +service_client(InStream, OutStream, _, _):- + thread_self(Id), + format(OutStream, 'Go away!!~n', []), + close(InStream), + close(OutStream), + thread_detach(Id). + + +run_prolog :- + catch(prolog, E, + ( print_message(error, E), +% E = error(_, _), + run_prolog)). + + +allow(Peer, Options) :- + ( member(allow(Allow), Options) + *-> Peer = Allow, + ! + ; Peer = ip(127,0,0,1) + ). diff --git a/packages/clib/random.c b/packages/clib/random.c new file mode 100644 index 000000000..5eacf0633 --- /dev/null +++ b/packages/clib/random.c @@ -0,0 +1,155 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: L.Damas, V.S.Costa, Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): Universidade do Porto, University of Amsterdam + + Original code create for YAP under Artistic license. As this + license is compatible (but less restrictive than) the SWI-Prolog + license we keep the Artistic license. +*/ + + +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: random.c * +* Last rev: * +* mods: * +* comments: Random number generation * +* * +*************************************************************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Ported to SWI-Prolog by Jan Wielemaker + +To compile: + + plld -o random -shared -fpic random.c +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#include +#include +#include + +static functor_t FUNCTOR_rand3; + +static short a1 = 27314, b1 = 9213, c1 = 17773; + +static int +type_error(term_t actual, const char *expected) +{ term_t ex; + + if ( (ex = PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR_CHARS, "error", 2, + PL_FUNCTOR_CHARS, "type_error", 2, + PL_CHARS, expected, + PL_TERM, actual, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +domain_error(term_t actual, const char *expected) +{ term_t ex; + + if ( (ex = PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR_CHARS, "error", 2, + PL_FUNCTOR_CHARS, "domain_error", 2, + PL_CHARS, expected, + PL_TERM, actual, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +get_short_ex(term_t t, short *p) +{ long v; + + if ( !PL_get_long(t, &v) ) + return type_error(t, "integer"); + if ( v < SHRT_MIN || v > SHRT_MAX ) + return domain_error(t, "short integer"); + + *p = (short)v; + + return TRUE; +} + + +static int +get_short_arg_ex(int a, term_t state, short *p) +{ term_t arg = PL_new_term_ref(); + + _PL_get_arg(a, state, arg); + return get_short_ex(arg, p); +} + + +static foreign_t +p_random(term_t rnd) +{ + double fli; + long int t1, t2, t3; + + t1 = (a1 * 171) % 30269; + t2 = (b1 * 172) % 30307; + t3 = (c1 * 170) % 30323; + fli = (t1/30269.0) + (t2/30307.0) + (t3/30323.0); + a1 = (short)t1; + b1 = (short)t2; + c1 = (short)t3; + + return PL_unify_float(rnd, fli-(int)(fli)); +} + +static foreign_t +p_setrand(term_t state) +{ if ( !PL_is_functor(state, FUNCTOR_rand3) ) + return type_error(state, "rand_state"); + + if ( !get_short_arg_ex(1, state, &a1) || + !get_short_arg_ex(2, state, &b1) || + !get_short_arg_ex(3, state, &c1) ) + return FALSE; + + return TRUE; +} + +static foreign_t +p_getrand(term_t state) +{ return PL_unify_term(state, + PL_FUNCTOR, FUNCTOR_rand3, + PL_INTEGER, a1, + PL_INTEGER, b1, + PL_INTEGER, c1); +} + + +install_t +install_random() +{ FUNCTOR_rand3 = PL_new_functor(PL_new_atom("rand"), 3); + + PL_register_foreign("random", 1, p_random, 0); + PL_register_foreign("setrand", 1, p_setrand, 0); + PL_register_foreign("getrand", 1, p_getrand, 0); +} + diff --git a/packages/clib/random.pl b/packages/clib/random.pl new file mode 100644 index 000000000..32479818a --- /dev/null +++ b/packages/clib/random.pl @@ -0,0 +1,163 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: R.A. O'Keefe, V.S. Costa, L. Damas, Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): Universidade do Porto, University of Amsterdam +*/ + +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: random.yap * +* Last rev: 5/12/99 * +* mods: * +* comments: Random operations * +* * +*************************************************************************/ + +% original code from RA O'Keefe. + +% This is algorithm AS 183 from Applied Statistics. I also have a C +% version. It is really very good. It is straightforward to make a +% version which yields 15-bit random integers using only integer +% arithmetic. + +:- module(random, + [ random/1, % -float + random/3, % +Low, +High, -Random + randseq/3, % +Size, +Max, -Set + randset/3, % +Size, +Max, -List + getrand/1, % -State + setrand/1 % +State + ]). +:- use_module(library(pairs)). + +:- use_foreign_library(foreign(random)). + +/** Random numbers + +Random number generator developed as part of the DEC10 library. The +algorithm is based on AS 183 from Applied Statistics. Originally +implemented ib Prolog by Richard O'Keeke. The SWI-Prolog versions is a +translation of a C-version for YAP based on the orginal source. + +@copyright DEC10 version: Public domain, YAP: Artistic +@author R.A. O'Keefe, V.S. Costa, L. Damas, Jan Wielemaker +@see Built-in function random/1: A is random(10) +*/ + + + + /******************************* + * C PRIMITIVES * + *******************************/ + +%% random(-R:float) is det. +% +% Binds R to a new random number in [0.0,1.0). +% +% @see setrand/1, getrand/1. + +%% setrand(+State:rand(A,B,C)) is det. +%% getrand(+State:rand(A,B,C)) is det. +% +% Query/set the state of the random library. A, B and C are +% integers in the range 1..30,000. The initial state is predefined +% and can be extracted using getrand/1: +% +% == +% ?- getrand(X). +% X = rand(27314, 9213, 17773). +% == +% +% @see random/1. + + + /******************************* + * PROLOG * + *******************************/ + + +%% random(+L:int, +U:int, -R:int) is det. +%% random(+L:float, +U:float, -R:float) is det. +% +% Binds R to a random number in [L,U). If L and U are both +% integers, R is an integer, Otherwise, R is a float. Note that U +% will *never* be generated. +% +% @bug The state is only 48-bits. This is insufficient for +% generating uniformely distributed integers in a very +% large domain. + +random(L, U, R) :- + integer(L), integer(U), !, + random(X), + R is L+floor((U-L)*X). +random(L, U, R) :- + number(L), number(U), !, + random(X), + R is L+((U-L)*X). + +%% randset(+K:int, +N:int, -S:list(int)) is det. +% +% S is a sorted list of K integers in the range 1..N. +% +% @see randseq/3. + + +randset(K, N, S) :- + K >= 0, + K =< N, + randset(K, N, [], S). + + +randset(0, _, S, S) :- !. +randset(K, N, Si, So) :- + random(X), + X * N < K, !, + J is K-1, + M is N-1, + randset(J, M, [N|Si], So). +randset(K, N, Si, So) :- + M is N-1, + randset(K, M, Si, So). + + +%% randseq(+K:int, +N:int, -S:list(int)) is det. +% +% S is a list of K integers in the range 1..N. The order is +% random. +% +% @see randset/3. + + +randseq(K, N, S) :- + randseq(K, N, L, []), + keysort(L, R), + pairs_values(R, S). + +randseq(0, _, S, S) :- !. +randseq(K, N, [Y-N|Si], So) :- + random(X), + X * N < K, !, + random(Y), + J is K-1, + M is N-1, + randseq(J, M, Si, So). +randseq(K, N, Si, So) :- + M is N-1, + randseq(K, M, Si, So). + + + + diff --git a/packages/clib/readutil.c b/packages/clib/readutil.c new file mode 100644 index 000000000..1162af0b8 --- /dev/null +++ b/packages/clib/readutil.c @@ -0,0 +1,170 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2005, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +#include +#include + +#define BUFSIZE 256 + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +This library is dynamically picked up by library(readline), which falls +back to a pure Prolog implementation if this library cannot be found. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static atom_t ATOM_end_of_file; + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +read_line_to_codes(+Stream, -Codes, ?Tail) + +Read a line, upto the next '\n' from Stream. Normally the line is +returned as a difference list Codes-Tail. If EOF is encountered, the +Codes list is closed and Tail is unified with []. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static foreign_t +read_line_to_codes3(term_t stream, term_t codes, term_t tail) +{ wchar_t buf[BUFSIZE]; + wchar_t *o = buf, *e = &buf[BUFSIZE]; + IOSTREAM *s; + term_t cl = PL_copy_term_ref(codes); + int rc = FALSE; + + if ( !PL_get_stream_handle(stream, &s) ) + return FALSE; + + for(;;) + { int c = Sgetcode(s); + + if ( c == EOF ) + { if ( (s->flags & SIO_FERR) ) + goto out; /* error */ + + if ( tail == 0 && o == buf ) + { rc = PL_unify_atom(codes, ATOM_end_of_file); + goto out; + } + if ( PL_unify_wchars(cl, PL_CODE_LIST, o-buf, buf) && + (tail == 0 || PL_unify_nil(tail)) ) + rc = TRUE; + + goto out; + } + + if ( o == e ) + { if ( !PL_unify_wchars_diff(cl, cl, PL_CODE_LIST, o-buf, buf) ) + goto out; + o = buf; + } + + *o++ = c; + if ( c == '\n' ) + { if ( tail ) + { if ( PL_unify_wchars_diff(cl, cl, PL_CODE_LIST, o-buf, buf) && + PL_unify(cl, tail) ) + rc = TRUE; + } else + { o--; + if ( o>buf && o[-1] == '\r' ) + o--; + rc = PL_unify_wchars(cl, PL_CODE_LIST, o-buf, buf); + } + + goto out; + } + } + +out: + PL_release_stream(s); + return rc; +} + + +static foreign_t +read_line_to_codes2(term_t stream, term_t codes) +{ return read_line_to_codes3(stream, codes, 0); +} + + +static foreign_t +read_stream_to_codes3(term_t stream, term_t codes, term_t tail) +{ wchar_t buf[BUFSIZE]; + wchar_t *o = buf, *e = &buf[BUFSIZE]; + IOSTREAM *s; + term_t cl = PL_copy_term_ref(codes); + + if ( !PL_get_stream_handle(stream, &s) ) + return FALSE; + + for(;;) + { int c = Sgetcode(s); + + if ( c == EOF ) + { if ( !PL_release_stream(s) ) + return FALSE; /* error */ + + if ( tail ) + { if ( PL_unify_wchars_diff(cl, cl, PL_CODE_LIST, o-buf, buf) && + PL_unify(cl, tail) ) + return TRUE; + return FALSE; + } else + { return PL_unify_wchars(cl, PL_CODE_LIST, o-buf, buf); + } + } + + if ( o == e ) + { if ( !PL_unify_wchars_diff(cl, cl, PL_CODE_LIST, o-buf, buf) ) + { PL_release_stream(s); + return FALSE; + } + o = buf; + } + + *o++ = c; + } +} + + +static foreign_t +read_stream_to_codes2(term_t stream, term_t codes) +{ return read_stream_to_codes3(stream, codes, 0); +} + + +install_t +install_readutil() +{ ATOM_end_of_file = PL_new_atom("end_of_file"); + + PL_register_foreign("read_line_to_codes", 3, read_line_to_codes3, 0); + PL_register_foreign("read_line_to_codes", 2, read_line_to_codes2, 0); + PL_register_foreign("read_stream_to_codes", 3, read_stream_to_codes3, 0); + PL_register_foreign("read_stream_to_codes", 2, read_stream_to_codes2, 0); +} diff --git a/packages/clib/rlimit.c b/packages/clib/rlimit.c new file mode 100644 index 000000000..5aac7b2d3 --- /dev/null +++ b/packages/clib/rlimit.c @@ -0,0 +1,128 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include "clib.h" + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Provide an interface to the Unix system resources (getrlimit()/setrlimit()). +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#if !defined(RLIMIT_NOFILE) && defined(RLIMIT_OFILE) +#define RLIMIT_NOFILE RLIMIT_OFILE +#endif + +foreign_t +pl_rlimit(term_t what, term_t old, term_t new) +{ char *s; + int resource; + struct rlimit rlim; + + if ( PL_get_atom_chars(what, &s) ) + { if ( strcmp(s, "cpu") == 0 ) + resource = RLIMIT_CPU; + else if ( strcmp(s, "fsize") == 0 ) + resource = RLIMIT_FSIZE; + else if ( strcmp(s, "data") == 0 ) + resource = RLIMIT_DATA; + else if ( strcmp(s, "stack") == 0 ) + resource = RLIMIT_STACK; + else if ( strcmp(s, "core") == 0 ) + resource = RLIMIT_CORE; +#ifdef RLIMIT_RSS + else if ( strcmp(s, "rss") == 0 ) + resource = RLIMIT_RSS; +#endif +#ifdef RLIMIT_MEMLOCK + else if ( strcmp(s, "memlock") == 0 ) + resource = RLIMIT_MEMLOCK; +#endif +#ifdef RLIMIT_NPROC + else if ( strcmp(s, "nproc") == 0 ) + resource = RLIMIT_NPROC; +#endif +#ifdef RLIMIT_NOFILE + else if ( strcmp(s, "nofile") == 0 ) + resource = RLIMIT_NOFILE; +#endif + else + return pl_error("rlimit", 3, NULL, ERR_DOMAIN, + what, "resource"); + } else + return pl_error("rlimit", 3, NULL, ERR_TYPE, + what, "atom"); + + if ( getrlimit(resource, &rlim) == 0 ) + { int rval; + + if ( rlim.rlim_cur == RLIM_INFINITY ) + rval = PL_unify_atom_chars(old, "unlimited"); + else + rval = PL_unify_int64(old, rlim.rlim_cur); + + if ( rval ) + { int64_t n; + + if ( PL_get_int64(new, &n) ) + { + set: + if ( rlim.rlim_cur != (unsigned long) n ) + { rlim.rlim_cur = n; + if ( !setrlimit(resource, &rlim) == 0 ) + return pl_error("rlimit", 3, NULL, ERR_ERRNO, errno, "set", "resource_limit", what); + } + return TRUE; + } else if ( PL_get_atom_chars(new, &s) && strcmp(s, "unlimited") == 0 ) + { n = RLIM_INFINITY; + goto set; + } else + return pl_error("rlimit", 3, NULL, ERR_TYPE, + new, "integer_or_unlimited"); + } else + return FALSE; + } else + return pl_error("rlimit", 3, NULL, ERR_ERRNO, errno, "get", "resource_limit", what); +} + + +install_t +install_rlimit() +{ PL_register_foreign("rlimit", 3, pl_rlimit, 0); +} diff --git a/packages/clib/rlimit.pl b/packages/clib/rlimit.pl new file mode 100644 index 000000000..74f553606 --- /dev/null +++ b/packages/clib/rlimit.pl @@ -0,0 +1,51 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(clib_rlimit, + [ rlimit/3 % +Limit, -Old, +New + ]). + +% rlimit(+Limit, -Old, +New) +% +% Query and set POSIX resource limits. Provided resources are: +% +% cpu CPU time (seconds) +% fsize file-size (bytes) +% data size of data-segment (bytes) +% stack size of C-stack (bytes) +% core size of a core-dump (bytes) +% rss resident set size +% memlock locked-in-memory address space +% nproc number of processes +% nofile number of open files + +:- use_foreign_library(foreign(rlimit)). + diff --git a/packages/clib/sha.pl b/packages/clib/sha.pl new file mode 100644 index 000000000..e5ce4e116 --- /dev/null +++ b/packages/clib/sha.pl @@ -0,0 +1,75 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2007, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(crypto_hash, + [ sha_hash/3, % +Data, -Hash, +Options + sha_new_ctx/2, % -NewContext, +Options + sha_hash_ctx/4, % +OldCtx, +Data, -NewCtx, -Hash + hmac_sha/4 % +Key, +Data, -Hash, +Options + ]). +:- use_module(library(shlib)). + +:- use_foreign_library(foreign(sha4pl)). + +%% sha_hash(+Data, -Hash, +Options) is det +% +% Hash is the SHA hash of Data, The conversion is controlled +% by Options: +% +% * algorithm(+Algorithm) +% One of =sha1= (default), =sha224=, =sha256=, =sha384= or +% =sha512= +% +% @param Data is either an atom, string or code-list +% @param Hash is a packed string + +%% sha_new_ctx(-NewContext, +Options) is det +% +% NewContext is unified with the empty SHA computation context +% (which includes the Options.) It could later be passed to +% sha_hash_ctx/4. +% +% For Options, see sha_hash/3. + +%% sha_hash_ctx(+OldContext, +Data, -NewContext, -Hash) is det +% +% Hash is the SHA hash of Data. NewContext is the new SHA +% computation context, while OldContext is the old. OldContext +% may be produced by a prior invocation of either sha_new_ctx/3 or +% sha_hash_ctx/4 itself. +% +% This predicate allows a SHA function to be computed in chunks, +% which may be important while working with Metalink (RFC 5854), +% BitTorrent or similar technologies, or simply with big files. + +%% hmac_sha(+Key, +Data, -Hash, +Options) is det +% +% For Options, see sha_hash/3. diff --git a/packages/clib/sha1/README b/packages/clib/sha1/README new file mode 100644 index 000000000..02dfe8a05 --- /dev/null +++ b/packages/clib/sha1/README @@ -0,0 +1 @@ +Original source: http://fp.gladman.plus.com/cryptography_technology/sha/index.htm diff --git a/packages/clib/sha1/brg_endian.h b/packages/clib/sha1/brg_endian.h new file mode 100644 index 000000000..4f7eee0ed --- /dev/null +++ b/packages/clib/sha1/brg_endian.h @@ -0,0 +1,142 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue 20/10/2006 +*/ + +#ifndef BRG_ENDIAN_H +#define BRG_ENDIAN_H + +#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ +#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ + +/* Include files where endian defines and byteswap functions may reside */ +#if defined(__sun__) +# include +#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) +# include +#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ + defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) +# include +#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) +# if !defined( __MINGW32__ ) +# include +# if !defined( __BEOS__ ) +# include +# endif +# endif +#endif + +/* Now attempt to set the define for platform byte order using any */ +/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ +/* seem to encompass most endian symbol definitions */ + +#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) +# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) +# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( _BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( _LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) +# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) +# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +/* if the platform byte order could not be determined, then try to */ +/* set this define using common machine defines */ +#if !defined(PLATFORM_BYTE_ORDER) + +#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ + defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ + defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ + defined( vax ) || defined( vms ) || defined( VMS ) || \ + defined( __VMS ) || defined( _M_X64 ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN + +#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ + defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ + defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ + defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ + defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ + defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ + defined( THINK_C ) || defined( __VMCMS__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN + +/*** JW: __WINDOWS__ for compiling SWI-Prolog. None of the above appears to be + defined, despite the VS2005 and Platform SDK claiming _M_X64 must be + defined +***/ +#elif __WINDOWS__ /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#else +# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order +#endif + +#endif + +#endif diff --git a/packages/clib/sha1/brg_types.h b/packages/clib/sha1/brg_types.h new file mode 100644 index 000000000..55aebcc56 --- /dev/null +++ b/packages/clib/sha1/brg_types.h @@ -0,0 +1,188 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue 09/09/2006 + + The unsigned integer types defined here are of the form uint_t where + is the length of the type; for example, the unsigned 32-bit type is + 'uint_32t'. These are NOT the same as the 'C99 integer types' that are + defined in the inttypes.h and stdint.h headers since attempts to use these + types have shown that support for them is still highly variable. However, + since the latter are of the form uint_t, a regular expression search + and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') + can be used to convert the types used here to the C99 standard types. +*/ + +#ifndef BRG_TYPES_H +#define BRG_TYPES_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +#ifndef BRG_UI8 +# define BRG_UI8 +# if UCHAR_MAX == 255u + typedef unsigned char uint_8t; +# else +# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI16 +# define BRG_UI16 +# if USHRT_MAX == 65535u + typedef unsigned short uint_16t; +# else +# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h +# endif +#endif + +#ifndef BRG_UI32 +# define BRG_UI32 +# if UINT_MAX == 4294967295u +# define li_32(h) 0x##h##u + typedef unsigned int uint_32t; +# elif ULONG_MAX == 4294967295u +# define li_32(h) 0x##h##ul + typedef unsigned long uint_32t; +# elif defined( _CRAY ) +# error This code needs 32-bit data types, which Cray machines do not provide +# else +# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI64 +# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned __int64 uint_64t; +# elif defined( _MSC_VER ) +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 + typedef unsigned __int64 uint_64t; +# elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u +# if UINT_MAX == 18446744073709551615u +# define BRG_UI64 +# define li_64(h) 0x##h##u + typedef unsigned int uint_64t; +# endif +# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u +# if ULONG_MAX == 18446744073709551615ul +# define BRG_UI64 +# define li_64(h) 0x##h##ul + typedef unsigned long uint_64t; +# endif +# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u +# if ULLONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif +# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u +# if ULONG_LONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif +# endif +#endif + +#if !defined( BRG_UI64 ) + /* JW: Using inttypes appears to work better than above */ +#include +#define BRG_UI64 +#define li_64(h) 0x##h##ull + typedef uint64_t uint_64t; +#endif + +#ifndef RETURN_VALUES +# define RETURN_VALUES +# if defined( DLL_EXPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllexport ) void __stdcall +# define INT_RETURN __declspec( dllexport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllexport__ ) void +# define INT_RETURN __declspec( __dllexport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( DLL_IMPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllimport ) void __stdcall +# define INT_RETURN __declspec( dllimport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllimport__ ) void +# define INT_RETURN __declspec( __dllimport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( __WATCOMC__ ) +# define VOID_RETURN void __cdecl +# define INT_RETURN int __cdecl +# else +# define VOID_RETURN void +# define INT_RETURN int +# endif +#endif + +/* These defines are used to declare buffers in a way that allows + faster operations on longer variables to be used. In all these + defines 'size' must be a power of 2 and >= 8 + + dec_unit_type(size,x) declares a variable 'x' of length + 'size' bits + + dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize' + bytes defined as an array of variables + each of 'size' bits (bsize must be a + multiple of size / 8) + + ptr_cast(x,size) casts a pointer to a pointer to a + varaiable of length 'size' bits +*/ + +#define ui_type(size) uint_##size##t +#define dec_unit_type(size,x) typedef ui_type(size) x +#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)] +#define ptr_cast(x,size) ((ui_type(size)*)(x)) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/hmac.c b/packages/clib/sha1/hmac.c new file mode 100644 index 000000000..9f7ca0629 --- /dev/null +++ b/packages/clib/sha1/hmac.c @@ -0,0 +1,145 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of HMAC, the FIPS standard keyed hash function +*/ + +#define _ISOC99_SOURCE +#include "hmac.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* initialise the HMAC context to zero */ +void hmac_sha_begin(hmac_ctx cx[1]) +{ + memset(cx, 0, sizeof(hmac_ctx)); +} + +/* input the HMAC key (can be called multiple times) */ +int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]) +{ + if(cx->klen == HMAC_IN_DATA) /* error if further key input */ + return HMAC_BAD_MODE; /* is attempted in data mode */ + + if(cx->klen + key_len > HASH_INPUT_SIZE) /* if the key has to be hashed */ + { + if(cx->klen <= HASH_INPUT_SIZE) /* if the hash has not yet been */ + { /* started, initialise it and */ + sha_begin(cx->ctx); /* hash stored key characters */ + sha_hash(cx->key, cx->klen, cx->ctx); + } + + sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */ + } + else /* otherwise store key data */ + memcpy(cx->key + cx->klen, key, key_len); + + cx->klen += key_len; /* update the key length count */ + return HMAC_OK; +} + +/* input the HMAC data (can be called multiple times) - */ +/* note that this call terminates the key input phase */ +void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]) +{ unsigned int i; + + if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */ + { + if(cx->klen > HASH_INPUT_SIZE) /* if key is being hashed */ + { /* complete the hash and */ + sha_end(cx->key, cx->ctx); /* store the result as the */ + cx->klen = HASH_OUTPUT_SIZE; /* key and set new length */ + } + + /* pad the key if necessary */ + memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen); + + /* xor ipad into key value */ + for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) + ((uint_32t*)cx->key)[i] ^= 0x36363636; + + /* and start hash operation */ + sha_begin(cx->ctx); + sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); + + /* mark as now in data mode */ + cx->klen = HMAC_IN_DATA; + } + + /* hash the data (if any) */ + if(data_len) + sha_hash(data, data_len, cx->ctx); +} + +/* compute and output the MAC value */ +void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]) +{ unsigned char dig[HASH_OUTPUT_SIZE]; + unsigned int i; + + /* if no data has been entered perform a null data phase */ + if(cx->klen != HMAC_IN_DATA) + hmac_sha_data((const unsigned char*)0, 0, cx); + + sha_end(dig, cx->ctx); /* complete the inner hash */ + + /* set outer key value using opad and removing ipad */ + for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i) + ((uint_32t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c; + + /* perform the outer hash operation */ + sha_begin(cx->ctx); + sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx); + sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx); + sha_end(dig, cx->ctx); + + /* output the hash value */ + for(i = 0; i < mac_len; ++i) + mac[i] = dig[i]; +} + +/* 'do it all in one go' subroutine */ +void hmac_sha(const unsigned char key[], unsigned long key_len, + const unsigned char data[], unsigned long data_len, + unsigned char mac[], unsigned long mac_len) +{ hmac_ctx cx[1]; + + hmac_sha_begin(cx); + hmac_sha_key(key, key_len, cx); + hmac_sha_data(data, data_len, cx); + hmac_sha_end(mac, mac_len, cx); +} + +#if defined(__cplusplus) +} +#endif diff --git a/packages/clib/sha1/hmac.h b/packages/clib/sha1/hmac.h new file mode 100644 index 000000000..0ee4506cf --- /dev/null +++ b/packages/clib/sha1/hmac.h @@ -0,0 +1,116 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of HMAC, the FIPS standard keyed hash function +*/ + +#ifndef _HMAC_H +#define _HMAC_H + +#include + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if !defined(USE_SHA1) && !defined(USE_SHA256) +#error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm +#endif + +#ifdef USE_SHA1 + +#include "sha1.h" + +#define HASH_INPUT_SIZE SHA1_BLOCK_SIZE +#define HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE +#define sha_ctx sha1_ctx +#define sha_begin sha1_begin +#define sha_hash sha1_hash +#define sha_end sha1_end + +#define hmac_sha_begin hmac_sha1_begin +#define hmac_sha_key hmac_sha1_key +#define hmac_sha_data hmac_sha1_data +#define hmac_sha_end hmac_sha1_end +#define hmac_sha hmac_sha1 + +#endif + +#ifdef USE_SHA256 + +#include "sha2.h" + +#define HASH_INPUT_SIZE SHA256_BLOCK_SIZE +#define HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE +#define sha_ctx sha256_ctx +#define sha_begin sha256_begin +#define sha_hash sha256_hash +#define sha_end sha256_end + +#define hmac_sha_begin hmac_sha256_begin +#define hmac_sha_key hmac_sha256_key +#define hmac_sha_data hmac_sha256_data +#define hmac_sha_end hmac_sha256_end +#define hmac_sha hmac_sha256 + +#endif + +#define HMAC_OK 0 +#define HMAC_BAD_MODE -1 +#define HMAC_IN_DATA 0xffffffff + +typedef struct +{ unsigned char key[HASH_INPUT_SIZE]; + sha_ctx ctx[1]; + unsigned long klen; +} hmac_ctx; + +void hmac_sha_begin(hmac_ctx cx[1]); + +int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]); + +void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]); + +void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]); + +void hmac_sha(const unsigned char key[], unsigned long key_len, + const unsigned char data[], unsigned long data_len, + unsigned char mac[], unsigned long mac_len); +void hmac_sha1(const unsigned char key[], unsigned long key_len, + const unsigned char data[], unsigned long data_len, + unsigned char mac[], unsigned long mac_len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/pwd2key.c b/packages/clib/sha1/pwd2key.c new file mode 100644 index 000000000..91b85806d --- /dev/null +++ b/packages/clib/sha1/pwd2key.c @@ -0,0 +1,193 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of RFC2898, which specifies key derivation from + a password and a salt value. +*/ + +#include +#include "hmac.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void derive_key(const unsigned char pwd[], /* the PASSWORD */ + unsigned int pwd_len, /* and its length */ + const unsigned char salt[], /* the SALT and its */ + unsigned int salt_len, /* length */ + unsigned int iter, /* the number of iterations */ + unsigned char key[], /* space for the output key */ + unsigned int key_len)/* and its required length */ +{ + unsigned int i, j, k, n_blk; + unsigned char uu[HASH_OUTPUT_SIZE], ux[HASH_OUTPUT_SIZE]; + hmac_ctx c1[1], c2[1], c3[1]; + + /* set HMAC context (c1) for password */ + hmac_sha_begin(c1); + hmac_sha_key(pwd, pwd_len, c1); + + /* set HMAC context (c2) for password and salt */ + memcpy(c2, c1, sizeof(hmac_ctx)); + hmac_sha_data(salt, salt_len, c2); + + /* find the number of SHA blocks in the key */ + n_blk = 1 + (key_len - 1) / HASH_OUTPUT_SIZE; + + for(i = 0; i < n_blk; ++i) /* for each block in key */ + { + /* ux[] holds the running xor value */ + memset(ux, 0, HASH_OUTPUT_SIZE); + + /* set HMAC context (c3) for password and salt */ + memcpy(c3, c2, sizeof(hmac_ctx)); + + /* enter additional data for 1st block into uu */ + uu[0] = (unsigned char)((i + 1) >> 24); + uu[1] = (unsigned char)((i + 1) >> 16); + uu[2] = (unsigned char)((i + 1) >> 8); + uu[3] = (unsigned char)(i + 1); + + /* this is the key mixing iteration */ + for(j = 0, k = 4; j < iter; ++j) + { + /* add previous round data to HMAC */ + hmac_sha_data(uu, k, c3); + + /* obtain HMAC for uu[] */ + hmac_sha_end(uu, HASH_OUTPUT_SIZE, c3); + + /* xor into the running xor block */ + for(k = 0; k < HASH_OUTPUT_SIZE; ++k) + ux[k] ^= uu[k]; + + /* set HMAC context (c3) for password */ + memcpy(c3, c1, sizeof(hmac_ctx)); + } + + /* compile key blocks into the key output */ + j = 0; k = i * HASH_OUTPUT_SIZE; + while(j < HASH_OUTPUT_SIZE && k < key_len) + key[k++] = ux[j++]; + } +} + +#ifdef TEST + +#include + +struct +{ unsigned int pwd_len; + unsigned int salt_len; + unsigned int it_count; + unsigned char *pwd; + unsigned char salt[32]; + unsigned char key[32]; +} tests[] = +{ + { 8, 4, 5, (unsigned char*)"password", + { + 0x12, 0x34, 0x56, 0x78 + }, + { + 0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7, + 0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 + } + }, + { 8, 8, 5, (unsigned char*)"password", + { + 0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 + }, + { + 0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6, + 0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 + } + }, + { 8, 21, 1, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01, + 0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15 + } + }, + { 8, 21, 2, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e, + 0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d + } + }, + { 8, 21, 1200, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e, + 0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b + } + } +}; + +int main() +{ unsigned int i, j, key_len = 256; + unsigned char key[256]; + + printf("\nTest of RFC2898 Password Based Key Derivation"); + for(i = 0; i < 5; ++i) + { + derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt, + tests[i].salt_len, tests[i].it_count, key, key_len); + + printf("\ntest %i: ", i + 1); + printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good"); + for(j = 0; j < key_len && j < 64; j += 4) + { + if(j % 16 == 0) + printf("\n"); + printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]); + } + printf(j < key_len ? " ... \n" : "\n"); + } + printf("\n"); + return 0; +} + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/pwd2key.h b/packages/clib/sha1/pwd2key.h new file mode 100644 index 000000000..64ddc6cd7 --- /dev/null +++ b/packages/clib/sha1/pwd2key.h @@ -0,0 +1,57 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of RFC2898, which specifies key derivation from + a password and a salt value. +*/ + +#ifndef PWD2KEY_H +#define PWD2KEY_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void derive_key( + const unsigned char pwd[], /* the PASSWORD, and */ + unsigned int pwd_len, /* its length */ + const unsigned char salt[], /* the SALT and its */ + unsigned int salt_len, /* length */ + unsigned int iter, /* the number of iterations */ + unsigned char key[], /* space for the output key */ + unsigned int key_len); /* and its required length */ + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/sha1.c b/packages/clib/sha1/sha1.c new file mode 100644 index 000000000..bb5474287 --- /dev/null +++ b/packages/clib/sha1/sha1.c @@ -0,0 +1,258 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 + + This is a byte oriented version of SHA1 that operates on arrays of bytes + stored in memory. +*/ + +#include /* for memcpy() etc. */ + +#include "sha1.h" +#include "brg_endian.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#pragma intrinsic(memcpy) +#endif + +#if 0 && defined(_MSC_VER) +#define rotl32 _lrotl +#define rotr32 _lrotr +#else +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +#endif + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ + { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } +#else +#define bsw_32(p,n) +#endif + +#define SHA1_MASK (SHA1_BLOCK_SIZE - 1) + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Discovered by Rich Schroeppel and Colin Plumb */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* Compile 64 bytes of hash data into SHA1 context. Note */ +/* that this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream will go in */ +/* this buffer to the high end of 32-bit words on BOTH big */ +/* and little endian systems */ + +#ifdef ARRAY +#define q(v,n) v[n] +#else +#define q(v,n) v##n +#endif + +#define one_cycle(v,a,b,c,d,e,f,k,h) \ + q(v,e) += rotr32(q(v,a),27) + \ + f(q(v,b),q(v,c),q(v,d)) + k + h; \ + q(v,b) = rotr32(q(v,b), 2) + +#define five_cycle(v,f,k,i) \ + one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \ + one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \ + one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \ + one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \ + one_cycle(v, 1,2,3,4,0, f,k,hf(i+4)) + +VOID_RETURN sha1_compile(sha1_ctx ctx[1]) +{ uint_32t *w = ctx->wbuf; + +#ifdef ARRAY + uint_32t v[5]; + memcpy(v, ctx->hash, 5 * sizeof(uint_32t)); +#else + uint_32t v0, v1, v2, v3, v4; + v0 = ctx->hash[0]; v1 = ctx->hash[1]; + v2 = ctx->hash[2]; v3 = ctx->hash[3]; + v4 = ctx->hash[4]; +#endif + +#define hf(i) w[i] + + five_cycle(v, ch, 0x5a827999, 0); + five_cycle(v, ch, 0x5a827999, 5); + five_cycle(v, ch, 0x5a827999, 10); + one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \ + +#undef hf +#define hf(i) (w[(i) & 15] = rotl32( \ + w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \ + ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1)) + + one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16)); + one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17)); + one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18)); + one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19)); + + five_cycle(v, parity, 0x6ed9eba1, 20); + five_cycle(v, parity, 0x6ed9eba1, 25); + five_cycle(v, parity, 0x6ed9eba1, 30); + five_cycle(v, parity, 0x6ed9eba1, 35); + + five_cycle(v, maj, 0x8f1bbcdc, 40); + five_cycle(v, maj, 0x8f1bbcdc, 45); + five_cycle(v, maj, 0x8f1bbcdc, 50); + five_cycle(v, maj, 0x8f1bbcdc, 55); + + five_cycle(v, parity, 0xca62c1d6, 60); + five_cycle(v, parity, 0xca62c1d6, 65); + five_cycle(v, parity, 0xca62c1d6, 70); + five_cycle(v, parity, 0xca62c1d6, 75); + +#ifdef ARRAY + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; +#else + ctx->hash[0] += v0; ctx->hash[1] += v1; + ctx->hash[2] += v2; ctx->hash[3] += v3; + ctx->hash[4] += v4; +#endif +} + +VOID_RETURN sha1_begin(sha1_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + ctx->hash[0] = 0x67452301; + ctx->hash[1] = 0xefcdab89; + ctx->hash[2] = 0x98badcfe; + ctx->hash[3] = 0x10325476; + ctx->hash[4] = 0xc3d2e1f0; +} + +/* SHA1 hash data in an array of bytes into hash buffer and */ +/* call the hash_compile function as required. */ + +VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) +{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK), + space = SHA1_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks if possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0; + bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2); + sha1_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA1 final padding and digest calculation */ + +VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]) +{ uint_32t i = (uint_32t)(ctx->count[0] & SHA1_MASK); + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_32(ctx->wbuf, (i + 3) >> 2); + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3); + ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space, pad and empty the buffer */ + if(i > SHA1_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha1_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + sha1_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < SHA1_DIGEST_SIZE; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha1_ctx cx[1]; + + sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); +} + +#if defined(__cplusplus) +} +#endif diff --git a/packages/clib/sha1/sha1.h b/packages/clib/sha1/sha1.h new file mode 100644 index 000000000..65ee6d39e --- /dev/null +++ b/packages/clib/sha1/sha1.h @@ -0,0 +1,73 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 +*/ + +#ifndef _SHA1_H +#define _SHA1_H + +#include +#include "brg_types.h" + +#define SHA1_BLOCK_SIZE 64 +#define SHA1_DIGEST_SIZE 20 + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* type to hold the SHA256 context */ + +typedef struct +{ uint_32t count[2]; + uint_32t hash[5]; + uint_32t wbuf[16]; +} sha1_ctx; + +/* Note that these prototypes are the same for both bit and */ +/* byte oriented implementations. However the length fields */ +/* are in bytes or bits as appropriate for the version used */ +/* and bit sequences are input as arrays of bytes in which */ +/* bit sequences run from the most to the least significant */ +/* end of each byte */ + +VOID_RETURN sha1_compile(sha1_ctx ctx[1]); + +VOID_RETURN sha1_begin(sha1_ctx ctx[1]); +VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]); +VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]); +VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/sha1b.c b/packages/clib/sha1/sha1b.c new file mode 100644 index 000000000..2063af60a --- /dev/null +++ b/packages/clib/sha1/sha1b.c @@ -0,0 +1,287 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 + + This is a bit oriented version of SHA1 that operates on arrays of bytes + stored in memory. +*/ + +#include /* for memcpy() etc. */ + +#include "sha1.h" +#include "brg_endian.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#pragma intrinsic(memcpy) +#endif + +#if 0 && defined(_MSC_VER) +#define rotl32 _lrotl +#define rotr32 _lrotr +#else +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +#endif + +#if !defined(bswap_32) +#define bswap_32(x) (rotr32((x), 24) & 0x00ff00ff | rotr32((x), 8) & 0xff00ff00) +#endif + +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ + { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } +#else +#define bsw_32(p,n) +#endif + +#define SHA1_MASK (SHA1_BLOCK_SIZE - 1) + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Discovered by Rich Schroeppel and Colin Plumb */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* Compile 64 bytes of hash data into SHA1 context. Note */ +/* that this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream in this buffer */ +/* will go to the high end of 32-bit words on BOTH big and */ +/* little endian systems */ + +#ifdef ARRAY +#define q(n) v[n] +#else +#define q(n) v##n +#endif + +#define one_cycle(a,b,c,d,e,f,k,h) \ + q(e) += rotr32(q(a),27) + f(q(b),q(c),q(d)) + k + h;\ + q(b) = rotr32(q(b), 2) + +#define five_cycle(f,k,i) \ + one_cycle(0,1,2,3,4, f,k,hf(i )); \ + one_cycle(4,0,1,2,3, f,k,hf(i+1)); \ + one_cycle(3,4,0,1,2, f,k,hf(i+2)); \ + one_cycle(2,3,4,0,1, f,k,hf(i+3)); \ + one_cycle(1,2,3,4,0, f,k,hf(i+4)) + +VOID_RETURN sha1_compile(sha1_ctx ctx[1]) +{ uint_32t *w = ctx->wbuf; + +#ifdef ARRAY + uint_32t v[5]; + memcpy(v, ctx->hash, 5 * sizeof(uint_32t)); +#else + uint_32t v0, v1, v2, v3, v4; + v0 = ctx->hash[0]; v1 = ctx->hash[1]; + v2 = ctx->hash[2]; v3 = ctx->hash[3]; + v4 = ctx->hash[4]; +#endif + +#define hf(i) w[i] + + five_cycle(ch, 0x5a827999, 0); + five_cycle(ch, 0x5a827999, 5); + five_cycle(ch, 0x5a827999, 10); + one_cycle(0,1,2,3,4, ch, 0x5a827999, hf(15)); \ + +#undef hf +#define hf(i) \ + (w[(i) & 15] = rotl32(w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \ + ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1)) + + one_cycle(4,0,1,2,3, ch, 0x5a827999, hf(16)); + one_cycle(3,4,0,1,2, ch, 0x5a827999, hf(17)); + one_cycle(2,3,4,0,1, ch, 0x5a827999, hf(18)); + one_cycle(1,2,3,4,0, ch, 0x5a827999, hf(19)); + + five_cycle(parity, 0x6ed9eba1, 20); + five_cycle(parity, 0x6ed9eba1, 25); + five_cycle(parity, 0x6ed9eba1, 30); + five_cycle(parity, 0x6ed9eba1, 35); + + five_cycle(maj, 0x8f1bbcdc, 40); + five_cycle(maj, 0x8f1bbcdc, 45); + five_cycle(maj, 0x8f1bbcdc, 50); + five_cycle(maj, 0x8f1bbcdc, 55); + + five_cycle(parity, 0xca62c1d6, 60); + five_cycle(parity, 0xca62c1d6, 65); + five_cycle(parity, 0xca62c1d6, 70); + five_cycle(parity, 0xca62c1d6, 75); + +#ifdef ARRAY + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; +#else + ctx->hash[0] += v0; ctx->hash[1] += v1; + ctx->hash[2] += v2; ctx->hash[3] += v3; + ctx->hash[4] += v4; +#endif +} + +VOID_RETURN sha1_begin(sha1_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + ctx->hash[0] = 0x67452301; + ctx->hash[1] = 0xefcdab89; + ctx->hash[2] = 0x98badcfe; + ctx->hash[3] = 0x10325476; + ctx->hash[4] = 0xc3d2e1f0; +} + +/* SHA1 hash data in an array of bytes into hash buffer and */ +/* call the hash_compile function as required. */ + +VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) +{ uint_32t pos = (uint_32t)((ctx->count[0] >> 3) & SHA1_MASK), + ofs = (ctx->count[0] & 7); + const unsigned char *sp = data; + unsigned char *w = (unsigned char*)ctx->wbuf; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + if(ofs) /* if not on a byte boundary */ + { + if(ofs + len < 8) /* if no added bytes are needed */ + { + w[pos] |= (*sp >> ofs); + } + else /* otherwise and add bytes */ + { unsigned char part = w[pos]; + + while((int)(ofs + (len -= 8)) >= 0) + { + w[pos++] = part | (*sp >> ofs); + part = *sp++ << (8 - ofs); + if(pos == SHA1_BLOCK_SIZE) + { + bsw_32(w, SHA1_BLOCK_SIZE >> 2); + sha1_compile(ctx); pos = 0; + } + } + + w[pos] = part; + } + } + else /* data is byte aligned */ + { uint_32t space = SHA1_BLOCK_SIZE - pos; + + while((int)(len - 8 * space) >= 0) + { + len -= 8 * space; + memcpy(w + pos, sp, space); + sp += space; + space = SHA1_BLOCK_SIZE; + bsw_32(w, SHA1_BLOCK_SIZE >> 2); + sha1_compile(ctx); pos = 0; + } + memcpy(w + pos, sp, (len + 7) >> 3); + } +} + +/* SHA1 final padding and digest calculation */ + +VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]) +{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA1_MASK), m1; + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_32(ctx->wbuf, (i + 4) >> 2); + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + m1 = (unsigned char)0x80 >> (ctx->count[0] & 7); + ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3)); + ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3)); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space, pad and empty the buffer */ + if(i > SHA1_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha1_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = ctx->count[1]; + ctx->wbuf[15] = ctx->count[0]; + sha1_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < SHA1_DIGEST_SIZE; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha1_ctx cx[1]; + + sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); +} + +#if defined(__cplusplus) +} +#endif diff --git a/packages/clib/sha1/sha2.c b/packages/clib/sha1/sha2.c new file mode 100644 index 000000000..681a1b662 --- /dev/null +++ b/packages/clib/sha1/sha2.c @@ -0,0 +1,773 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 + + This is a byte oriented version of SHA2 that operates on arrays of bytes + stored in memory. This code implements sha256, sha384 and sha512 but the + latter two functions rely on efficient 64-bit integer operations that + may not be very efficient on 32-bit machines + + The sha256 functions use a type 'sha256_ctx' to hold details of the + current hash state and uses the following three calls: + + void sha256_begin(sha256_ctx ctx[1]) + void sha256_hash(const unsigned char data[], + unsigned long len, sha256_ctx ctx[1]) + void sha_end1(unsigned char hval[], sha256_ctx ctx[1]) + + The first subroutine initialises a hash computation by setting up the + context in the sha256_ctx context. The second subroutine hashes 8-bit + bytes from array data[] into the hash state withinh sha256_ctx context, + the number of bytes to be hashed being given by the the unsigned long + integer len. The third subroutine completes the hash calculation and + places the resulting digest value in the array of 8-bit bytes hval[]. + + The sha384 and sha512 functions are similar and use the interfaces: + + void sha384_begin(sha384_ctx ctx[1]); + void sha384_hash(const unsigned char data[], + unsigned long len, sha384_ctx ctx[1]); + void sha384_end(unsigned char hval[], sha384_ctx ctx[1]); + + void sha512_begin(sha512_ctx ctx[1]); + void sha512_hash(const unsigned char data[], + unsigned long len, sha512_ctx ctx[1]); + void sha512_end(unsigned char hval[], sha512_ctx ctx[1]); + + In addition there is a function sha2 that can be used to call all these + functions using a call with a hash length parameter as follows: + + int sha2_begin(unsigned long len, sha2_ctx ctx[1]); + void sha2_hash(const unsigned char data[], + unsigned long len, sha2_ctx ctx[1]); + void sha2_end(unsigned char hval[], sha2_ctx ctx[1]); + + My thanks to Erik Andersen for testing this code + on big-endian systems and for his assistance with corrections +*/ + +#if 0 +#define UNROLL_SHA2 /* for SHA2 loop unroll */ +#endif + +#define _ISOC99_SOURCE +#include /* for memcpy() etc. */ + +#include "sha2.h" +#include "brg_endian.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#pragma intrinsic(memcpy) +#endif + +#if 0 && defined(_MSC_VER) +#define rotl32 _lrotl +#define rotr32 _lrotr +#else +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +#endif + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* round transforms for SHA256 and SHA512 compression functions */ + +#define vf(n,i) v[(n - i) & 7] + +#define hf(i) (p[i & 15] += \ + g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15])) + +#define v_cycle(i,j) \ + vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \ + + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \ + vf(3,i) += vf(7,i); \ + vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)) + +#if defined(SHA_224) || defined(SHA_256) + +#define SHA256_MASK (SHA256_BLOCK_SIZE - 1) + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ + { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } +#else +#define bsw_32(p,n) +#endif + +#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) +#define k_0 k256 + +/* rotated SHA256 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define q(n) v##n + +#define one_cycle(a,b,c,d,e,f,g,h,k,w) \ + q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \ + q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c)) + +/* SHA256 mixing data */ + +const uint_32t k256[64] = +{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul, + 0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul, + 0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul, + 0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul, + 0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul, + 0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul, + 0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul, + 0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul, + 0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul, + 0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul, + 0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul, + 0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul, + 0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul, + 0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul, + 0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul, + 0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul, +}; + +/* Compile 64 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +VOID_RETURN sha256_compile(sha256_ctx ctx[1]) +{ +#if !defined(UNROLL_SHA2) + + uint_32t j, *p = ctx->wbuf, v[8]; + + memcpy(v, ctx->hash, 8 * sizeof(uint_32t)); + + for(j = 0; j < 64; j += 16) + { + v_cycle( 0, j); v_cycle( 1, j); + v_cycle( 2, j); v_cycle( 3, j); + v_cycle( 4, j); v_cycle( 5, j); + v_cycle( 6, j); v_cycle( 7, j); + v_cycle( 8, j); v_cycle( 9, j); + v_cycle(10, j); v_cycle(11, j); + v_cycle(12, j); v_cycle(13, j); + v_cycle(14, j); v_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; + ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; + +#else + + uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7; + + v0 = ctx->hash[0]; v1 = ctx->hash[1]; + v2 = ctx->hash[2]; v3 = ctx->hash[3]; + v4 = ctx->hash[4]; v5 = ctx->hash[5]; + v6 = ctx->hash[6]; v7 = ctx->hash[7]; + + one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]); + one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]); + one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]); + one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]); + one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]); + one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]); + one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]); + one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]); + one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]); + one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]); + one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]); + one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]); + one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]); + one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]); + one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]); + one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]); + + one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15)); + + one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15)); + + one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15)); + + ctx->hash[0] += v0; ctx->hash[1] += v1; + ctx->hash[2] += v2; ctx->hash[3] += v3; + ctx->hash[4] += v4; ctx->hash[5] += v5; + ctx->hash[6] += v6; ctx->hash[7] += v7; +#endif +} + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]) +{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK), + space = SHA256_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks while possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0; + bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2) + sha256_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA256 Final padding and digest calculation */ + +static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen) +{ uint_32t i = (uint_32t)(ctx->count[0] & SHA256_MASK); + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_32(ctx->wbuf, (i + 3) >> 2) + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3); + ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if(i > SHA256_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha256_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + sha256_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* mislaigned for 32-bit words */ + for(i = 0; i < hlen; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +#endif + +#if defined(SHA_224) + +const uint_32t i224[8] = +{ + 0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul, + 0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul +}; + +VOID_RETURN sha224_begin(sha224_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i224, 8 * sizeof(uint_32t)); +} + +VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]) +{ + sha_end1(hval, ctx, SHA224_DIGEST_SIZE); +} + +VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha224_ctx cx[1]; + + sha224_begin(cx); + sha224_hash(data, len, cx); + sha_end1(hval, cx, SHA224_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_256) + +const uint_32t i256[8] = +{ + 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, + 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul +}; + +VOID_RETURN sha256_begin(sha256_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i256, 8 * sizeof(uint_32t)); +} + +VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]) +{ + sha_end1(hval, ctx, SHA256_DIGEST_SIZE); +} + +VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha256_ctx cx[1]; + + sha256_begin(cx); + sha256_hash(data, len, cx); + sha_end1(hval, cx, SHA256_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_384) || defined(SHA_512) + +#define SHA512_MASK (SHA512_BLOCK_SIZE - 1) + +#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) + +#if !defined(bswap_64) +#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32))) +#endif + +#if defined(SWAP_BYTES) +#define bsw_64(p,n) \ + { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); } +#else +#define bsw_64(p,n) +#endif + +/* SHA512 mixing function definitions */ + +#ifdef s_0 +# undef s_0 +# undef s_1 +# undef g_0 +# undef g_1 +# undef k_0 +#endif + +#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) +#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) +#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7)) +#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6)) +#define k_0 k512 + +/* SHA384/SHA512 mixing data */ + +const uint_64t k512[80] = +{ + li_64(428a2f98d728ae22), li_64(7137449123ef65cd), + li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc), + li_64(3956c25bf348b538), li_64(59f111f1b605d019), + li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118), + li_64(d807aa98a3030242), li_64(12835b0145706fbe), + li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2), + li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1), + li_64(9bdc06a725c71235), li_64(c19bf174cf692694), + li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3), + li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65), + li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483), + li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5), + li_64(983e5152ee66dfab), li_64(a831c66d2db43210), + li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4), + li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725), + li_64(06ca6351e003826f), li_64(142929670a0e6e70), + li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926), + li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df), + li_64(650a73548baf63de), li_64(766a0abb3c77b2a8), + li_64(81c2c92e47edaee6), li_64(92722c851482353b), + li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001), + li_64(c24b8b70d0f89791), li_64(c76c51a30654be30), + li_64(d192e819d6ef5218), li_64(d69906245565a910), + li_64(f40e35855771202a), li_64(106aa07032bbd1b8), + li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53), + li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8), + li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb), + li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3), + li_64(748f82ee5defb2fc), li_64(78a5636f43172f60), + li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec), + li_64(90befffa23631e28), li_64(a4506cebde82bde9), + li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b), + li_64(ca273eceea26619c), li_64(d186b8c721c0c207), + li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178), + li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6), + li_64(113f9804bef90dae), li_64(1b710b35131c471b), + li_64(28db77f523047d84), li_64(32caab7b40c72493), + li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c), + li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a), + li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817) +}; + +/* Compile 128 bytes of hash data into SHA384/512 digest */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +VOID_RETURN sha512_compile(sha512_ctx ctx[1]) +{ uint_64t v[8], *p = ctx->wbuf; + uint_32t j; + + memcpy(v, ctx->hash, 8 * sizeof(uint_64t)); + + for(j = 0; j < 80; j += 16) + { + v_cycle( 0, j); v_cycle( 1, j); + v_cycle( 2, j); v_cycle( 3, j); + v_cycle( 4, j); v_cycle( 5, j); + v_cycle( 6, j); v_cycle( 7, j); + v_cycle( 8, j); v_cycle( 9, j); + v_cycle(10, j); v_cycle(11, j); + v_cycle(12, j); v_cycle(13, j); + v_cycle(14, j); v_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; + ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; +} + +/* Compile 128 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream placed in this */ +/* buffer will now go to the high end of words on BOTH big */ +/* and little endian systems */ + +VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]) +{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK), + space = SHA512_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks while possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0; + bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3); + sha512_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA384/512 Final padding and digest calculation */ + +static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen) +{ uint_32t i = (uint_32t)(ctx->count[0] & SHA512_MASK); + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_64(ctx->wbuf, (i + 7) >> 3); + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7); + ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7); + + /* we need 17 or more empty byte positions, one for the padding */ + /* byte (above) and sixteen for the length count. If there is */ + /* not enough space pad and empty the buffer */ + if(i > SHA512_BLOCK_SIZE - 17) + { + if(i < 120) ctx->wbuf[15] = 0; + sha512_compile(ctx); + i = 0; + } + else + i = (i >> 3) + 1; + + while(i < 14) + ctx->wbuf[i++] = 0; + + /* the following 64-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 64-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61); + ctx->wbuf[15] = ctx->count[0] << 3; + sha512_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < hlen; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7))); +} + +#endif + +#if defined(SHA_384) + +/* SHA384 initialisation data */ + +const uint_64t i384[80] = +{ + li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507), + li_64(9159015a3070dd17), li_64(152fecd8f70e5939), + li_64(67332667ffc00b31), li_64(8eb44a8768581511), + li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4) +}; + +VOID_RETURN sha384_begin(sha384_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i384, 8 * sizeof(uint_64t)); +} + +VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]) +{ + sha_end2(hval, ctx, SHA384_DIGEST_SIZE); +} + +VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha384_ctx cx[1]; + + sha384_begin(cx); + sha384_hash(data, len, cx); + sha_end2(hval, cx, SHA384_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_512) + +/* SHA512 initialisation data */ + +const uint_64t i512[80] = +{ + li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b), + li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1), + li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f), + li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179) +}; + +VOID_RETURN sha512_begin(sha512_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i512, 8 * sizeof(uint_64t)); +} + +VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]) +{ + sha_end2(hval, ctx, SHA512_DIGEST_SIZE); +} + +VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha512_ctx cx[1]; + + sha512_begin(cx); + sha512_hash(data, len, cx); + sha_end2(hval, cx, SHA512_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_2) + +#define CTX_224(x) ((x)->uu->ctx256) +#define CTX_256(x) ((x)->uu->ctx256) +#define CTX_384(x) ((x)->uu->ctx512) +#define CTX_512(x) ((x)->uu->ctx512) + +/* SHA2 initialisation */ + +INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1]) +{ + switch(len) + { +#if defined(SHA_224) + case 224: + case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; + memcpy(CTX_256(ctx)->hash, i224, 32); + ctx->sha2_len = 28; return EXIT_SUCCESS; +#endif +#if defined(SHA_256) + case 256: + case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; + memcpy(CTX_256(ctx)->hash, i256, 32); + ctx->sha2_len = 32; return EXIT_SUCCESS; +#endif +#if defined(SHA_384) + case 384: + case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0; + memcpy(CTX_384(ctx)->hash, i384, 64); + ctx->sha2_len = 48; return EXIT_SUCCESS; +#endif +#if defined(SHA_512) + case 512: + case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0; + memcpy(CTX_512(ctx)->hash, i512, 64); + ctx->sha2_len = 64; return EXIT_SUCCESS; +#endif + default: return EXIT_FAILURE; + } +} + +VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { +#if defined(SHA_224) + case 28: sha224_hash(data, len, CTX_224(ctx)); return; +#endif +#if defined(SHA_256) + case 32: sha256_hash(data, len, CTX_256(ctx)); return; +#endif +#if defined(SHA_384) + case 48: sha384_hash(data, len, CTX_384(ctx)); return; +#endif +#if defined(SHA_512) + case 64: sha512_hash(data, len, CTX_512(ctx)); return; +#endif + } +} + +VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { +#if defined(SHA_224) + case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return; +#endif +#if defined(SHA_256) + case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return; +#endif +#if defined(SHA_384) + case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return; +#endif +#if defined(SHA_512) + case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return; +#endif + } +} + +INT_RETURN sha2(unsigned char hval[], unsigned long size, + const unsigned char data[], unsigned long len) +{ sha2_ctx cx[1]; + + if(sha2_begin(size, cx) == EXIT_SUCCESS) + { + sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS; + } + else + return EXIT_FAILURE; +} + +#endif + +#if defined(__cplusplus) +} +#endif diff --git a/packages/clib/sha1/sha2.h b/packages/clib/sha1/sha2.h new file mode 100644 index 000000000..6ab8907c1 --- /dev/null +++ b/packages/clib/sha1/sha2.h @@ -0,0 +1,151 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 +*/ + +#ifndef _SHA2_H +#define _SHA2_H + +#include + +#define SHA_64BIT + +/* define the hash functions that you need */ +#define SHA_2 /* for dynamic hash length */ +#define SHA_224 +#define SHA_256 +#ifdef SHA_64BIT +# define SHA_384 +# define SHA_512 +# define NEED_UINT_64T +#endif + +#include "brg_types.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Note that the following function prototypes are the same */ +/* for both the bit and byte oriented implementations. But */ +/* the length fields are in bytes or bits as is appropriate */ +/* for the version used. Bit sequences are arrays of bytes */ +/* in which bit sequence indexes increase from the most to */ +/* the least significant end of each byte */ + +#define SHA224_DIGEST_SIZE 28 +#define SHA224_BLOCK_SIZE 64 +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 + +/* type to hold the SHA256 (and SHA224) context */ + +typedef struct +{ uint_32t count[2]; + uint_32t hash[8]; + uint_32t wbuf[16]; +} sha256_ctx; + +typedef sha256_ctx sha224_ctx; + +VOID_RETURN sha256_compile(sha256_ctx ctx[1]); + +VOID_RETURN sha224_begin(sha224_ctx ctx[1]); +#define sha224_hash sha256_hash +VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]); +VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len); + +VOID_RETURN sha256_begin(sha256_ctx ctx[1]); +VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]); +VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]); +VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len); + +#ifndef SHA_64BIT + +typedef struct +{ union + { sha256_ctx ctx256[1]; + } uu[1]; + uint_32t sha2_len; +} sha2_ctx; + +#define SHA2_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE + +#else + +#define SHA384_DIGEST_SIZE 48 +#define SHA384_BLOCK_SIZE 128 +#define SHA512_DIGEST_SIZE 64 +#define SHA512_BLOCK_SIZE 128 +#define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +/* type to hold the SHA384 (and SHA512) context */ + +typedef struct +{ uint_64t count[2]; + uint_64t hash[8]; + uint_64t wbuf[16]; +} sha512_ctx; + +typedef sha512_ctx sha384_ctx; + +typedef struct +{ union + { sha256_ctx ctx256[1]; + sha512_ctx ctx512[1]; + } uu[1]; + uint_32t sha2_len; +} sha2_ctx; + +VOID_RETURN sha512_compile(sha512_ctx ctx[1]); + +VOID_RETURN sha384_begin(sha384_ctx ctx[1]); +#define sha384_hash sha512_hash +VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]); +VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len); + +VOID_RETURN sha512_begin(sha512_ctx ctx[1]); +VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]); +VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]); +VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len); + +INT_RETURN sha2_begin(unsigned long size, sha2_ctx ctx[1]); +VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]); +VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]); +INT_RETURN sha2(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/packages/clib/sha1/sha2b.c b/packages/clib/sha1/sha2b.c new file mode 100644 index 000000000..e0aafc931 --- /dev/null +++ b/packages/clib/sha1/sha2b.c @@ -0,0 +1,833 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 01/08/2005 + + This is a bit oriented version of SHA2 that operates on arrays of bytes + stored in memory. This code implements sha256, sha384 and sha512 but the + latter two functions rely on efficient 64-bit integer operations that + may not be very efficient on 32-bit machines + + The sha256 functions use a type 'sha256_ctx' to hold details of the + current hash state and uses the following three calls: + + void sha256_begin(sha256_ctx ctx[1]) + void sha256_hash(const unsigned char data[], + unsigned long len, sha256_ctx ctx[1]) + void sha_end1(unsigned char hval[], sha256_ctx ctx[1]) + + The first subroutine initialises a hash computation by setting up the + context in the sha256_ctx context. The second subroutine hashes 8-bit + bytes from array data[] into the hash state withinh sha256_ctx context, + the number of bytes to be hashed being given by the the unsigned long + integer len. The third subroutine completes the hash calculation and + places the resulting digest value in the array of 8-bit bytes hval[]. + + The sha384 and sha512 functions are similar and use the interfaces: + + void sha384_begin(sha384_ctx ctx[1]); + void sha384_hash(const unsigned char data[], + unsigned long len, sha384_ctx ctx[1]); + void sha384_end(unsigned char hval[], sha384_ctx ctx[1]); + + void sha512_begin(sha512_ctx ctx[1]); + void sha512_hash(const unsigned char data[], + unsigned long len, sha512_ctx ctx[1]); + void sha512_end(unsigned char hval[], sha512_ctx ctx[1]); + + In addition there is a function sha2 that can be used to call all these + functions using a call with a hash length parameter as follows: + + int sha2_begin(unsigned long len, sha2_ctx ctx[1]); + void sha2_hash(const unsigned char data[], + unsigned long len, sha2_ctx ctx[1]); + void sha2_end(unsigned char hval[], sha2_ctx ctx[1]); + + My thanks to Erik Andersen for testing this code + on big-endian systems and for his assistance with corrections +*/ + +#if 1 +#define UNROLL_SHA2 /* for SHA2 loop unroll */ +#endif + +#include /* for memcpy() etc. */ + +#include "sha2.h" +#include "brg_endian.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#pragma intrinsic(memcpy) +#endif + +#if 0 && defined(_MSC_VER) +#define rotl32 _lrotl +#define rotr32 _lrotr +#else +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +#endif + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* round transforms for SHA256 and SHA512 compression functions */ + +#define vf(n,i) v[(n - i) & 7] + +#define hf(i) (p[i & 15] += \ + g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15])) + +#define v_cycle(i,j) \ + vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \ + + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \ + vf(3,i) += vf(7,i); \ + vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)) + +#if defined(SHA_224) || defined(SHA_256) + +#define SHA256_MASK (SHA256_BLOCK_SIZE - 1) + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ + { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); } +#else +#define bsw_32(p,n) +#endif + +#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) +#define k_0 k256 + +/* rotated SHA256 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define q(n) v##n + +#define one_cycle(a,b,c,d,e,f,g,h,k,w) \ + q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \ + q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c)) + +/* SHA256 mixing data */ + +const uint_32t k256[64] = +{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul, + 0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul, + 0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul, + 0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul, + 0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul, + 0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul, + 0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul, + 0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul, + 0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul, + 0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul, + 0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul, + 0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul, + 0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul, + 0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul, + 0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul, + 0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul, +}; + +/* Compile 64 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +VOID_RETURN sha256_compile(sha256_ctx ctx[1]) +{ +#if !defined(UNROLL_SHA2) + + uint_32t j, *p = ctx->wbuf, v[8]; + + memcpy(v, ctx->hash, 8 * sizeof(uint_32t)); + + for(j = 0; j < 64; j += 16) + { + v_cycle( 0, j); v_cycle( 1, j); + v_cycle( 2, j); v_cycle( 3, j); + v_cycle( 4, j); v_cycle( 5, j); + v_cycle( 6, j); v_cycle( 7, j); + v_cycle( 8, j); v_cycle( 9, j); + v_cycle(10, j); v_cycle(11, j); + v_cycle(12, j); v_cycle(13, j); + v_cycle(14, j); v_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; + ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; + +#else + + uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7; + + v0 = ctx->hash[0]; v1 = ctx->hash[1]; + v2 = ctx->hash[2]; v3 = ctx->hash[3]; + v4 = ctx->hash[4]; v5 = ctx->hash[5]; + v6 = ctx->hash[6]; v7 = ctx->hash[7]; + + one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]); + one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]); + one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]); + one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]); + one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]); + one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]); + one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]); + one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]); + one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]); + one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]); + one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]); + one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]); + one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]); + one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]); + one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]); + one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]); + + one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15)); + + one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15)); + + one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0)); + one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1)); + one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2)); + one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3)); + one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4)); + one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5)); + one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6)); + one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7)); + one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8)); + one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9)); + one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10)); + one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11)); + one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12)); + one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13)); + one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14)); + one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15)); + + ctx->hash[0] += v0; ctx->hash[1] += v1; + ctx->hash[2] += v2; ctx->hash[3] += v3; + ctx->hash[4] += v4; ctx->hash[5] += v5; + ctx->hash[6] += v6; ctx->hash[7] += v7; +#endif +} + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]) +{ uint_32t pos = (uint_32t)((ctx->count[0] >> 3) & SHA256_MASK), + ofs = (ctx->count[0] & 7); + const unsigned char *sp = data; + unsigned char *w = (unsigned char*)ctx->wbuf; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + if(ofs) /* if not on a byte boundary */ + { + if(ofs + len < 8) /* if no added bytes are needed */ + { + w[pos] |= (*sp >> ofs); + } + else /* otherwise and add bytes */ + { unsigned char part = w[pos]; + + while((int)(ofs + (len -= 8)) >= 0) + { + w[pos++] = part | (*sp >> ofs); + part = *sp++ << (8 - ofs); + if(pos == SHA256_BLOCK_SIZE) + { + bsw_32(w, SHA256_BLOCK_SIZE >> 2); + sha256_compile(ctx); pos = 0; + } + } + + w[pos] = part; + } + } + else /* data is byte aligned */ + { uint_32t space = SHA256_BLOCK_SIZE - pos; + + while((int)(len - 8 * space) >= 0) + { + len -= 8 * space; + memcpy(w + pos, sp, space); + sp += space; + space = SHA256_BLOCK_SIZE; + bsw_32(w, SHA256_BLOCK_SIZE >> 2); + sha256_compile(ctx); pos = 0; + } + memcpy(w + pos, sp, (len + 7) >> 3); + } +} + +/* SHA256 Final padding and digest calculation */ + +static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen) +{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA256_MASK), m1; + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_32(ctx->wbuf, (i + 4) >> 2) + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + m1 = (unsigned char)0x80 >> (ctx->count[0] & 7); + ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3)); + ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3)); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if(i > SHA256_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha256_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = ctx->count[1]; + ctx->wbuf[15] = ctx->count[0]; + sha256_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* mislaigned for 32-bit words */ + for(i = 0; i < hlen; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +#endif + +#if defined(SHA_224) + +const uint_32t i224[8] = +{ + 0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul, + 0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul +}; + +VOID_RETURN sha224_begin(sha224_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i224, 8 * sizeof(uint_32t)); +} + +VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]) +{ + sha_end1(hval, ctx, SHA224_DIGEST_SIZE); +} + +VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha224_ctx cx[1]; + + sha224_begin(cx); + sha224_hash(data, len, cx); + sha_end1(hval, cx, SHA224_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_256) + +const uint_32t i256[8] = +{ + 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, + 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul +}; + +VOID_RETURN sha256_begin(sha256_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i256, 8 * sizeof(uint_32t)); +} + +VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]) +{ + sha_end1(hval, ctx, SHA256_DIGEST_SIZE); +} + +VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha256_ctx cx[1]; + + sha256_begin(cx); + sha256_hash(data, len, cx); + sha_end1(hval, cx, SHA256_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_384) || defined(SHA_512) + +#define SHA512_MASK (SHA512_BLOCK_SIZE - 1) + +#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) + +#if !defined(bswap_64) +#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32))) +#endif + +#if defined(SWAP_BYTES) +#define bsw_64(p,n) \ + { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); } +#else +#define bsw_64(p,n) +#endif + +/* SHA512 mixing function definitions */ + +#ifdef s_0 +# undef s_0 +# undef s_1 +# undef g_0 +# undef g_1 +# undef k_0 +#endif + +#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) +#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) +#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7)) +#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6)) +#define k_0 k512 + +/* SHA384/SHA512 mixing data */ + +const uint_64t k512[80] = +{ + li_64(428a2f98d728ae22), li_64(7137449123ef65cd), + li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc), + li_64(3956c25bf348b538), li_64(59f111f1b605d019), + li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118), + li_64(d807aa98a3030242), li_64(12835b0145706fbe), + li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2), + li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1), + li_64(9bdc06a725c71235), li_64(c19bf174cf692694), + li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3), + li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65), + li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483), + li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5), + li_64(983e5152ee66dfab), li_64(a831c66d2db43210), + li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4), + li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725), + li_64(06ca6351e003826f), li_64(142929670a0e6e70), + li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926), + li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df), + li_64(650a73548baf63de), li_64(766a0abb3c77b2a8), + li_64(81c2c92e47edaee6), li_64(92722c851482353b), + li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001), + li_64(c24b8b70d0f89791), li_64(c76c51a30654be30), + li_64(d192e819d6ef5218), li_64(d69906245565a910), + li_64(f40e35855771202a), li_64(106aa07032bbd1b8), + li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53), + li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8), + li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb), + li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3), + li_64(748f82ee5defb2fc), li_64(78a5636f43172f60), + li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec), + li_64(90befffa23631e28), li_64(a4506cebde82bde9), + li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b), + li_64(ca273eceea26619c), li_64(d186b8c721c0c207), + li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178), + li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6), + li_64(113f9804bef90dae), li_64(1b710b35131c471b), + li_64(28db77f523047d84), li_64(32caab7b40c72493), + li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c), + li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a), + li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817) +}; + +/* Compile 128 bytes of hash data into SHA384/512 digest */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +VOID_RETURN sha512_compile(sha512_ctx ctx[1]) +{ uint_64t v[8], *p = ctx->wbuf; + uint_32t j; + + memcpy(v, ctx->hash, 8 * sizeof(uint_64t)); + + for(j = 0; j < 80; j += 16) + { + v_cycle( 0, j); v_cycle( 1, j); + v_cycle( 2, j); v_cycle( 3, j); + v_cycle( 4, j); v_cycle( 5, j); + v_cycle( 6, j); v_cycle( 7, j); + v_cycle( 8, j); v_cycle( 9, j); + v_cycle(10, j); v_cycle(11, j); + v_cycle(12, j); v_cycle(13, j); + v_cycle(14, j); v_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; + ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; + ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; +} + +/* Compile 128 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream placed in this */ +/* buffer will now go to the high end of words on BOTH big */ +/* and little endian systems */ + +VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]) +{ uint_32t pos = (uint_32t)(ctx->count[0] >> 3) & SHA512_MASK, + ofs = (uint_32t)(ctx->count[0] & 7); + const unsigned char *sp = data; + unsigned char *w = (unsigned char*)ctx->wbuf; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + if(ofs) /* if not on a byte boundary */ + { + if(ofs + len < 8) /* if no added bytes are needed */ + { + w[pos] |= (*sp >> ofs); + } + else /* otherwise and add bytes */ + { unsigned char part = w[pos]; + + while((int)(ofs + (len -= 8)) >= 0) + { + w[pos++] = part | (*sp >> ofs); + part = *sp++ << (8 - ofs); + if(pos == SHA512_BLOCK_SIZE) + { + bsw_64(w, SHA512_BLOCK_SIZE >> 3); + sha512_compile(ctx); pos = 0; + } + } + + w[pos] = part; + } + } + else /* data is byte aligned */ + { uint_32t space = SHA512_BLOCK_SIZE - pos; + + while((int)(len - 8 * space) >= 0) + { + len -= 8 * space; + memcpy(w + pos, sp, space); + sp += space; + space = SHA512_BLOCK_SIZE; + bsw_64(w, SHA512_BLOCK_SIZE >> 3); + sha512_compile(ctx); pos = 0; + } + memcpy(w + pos, sp, (len + 7) >> 3); + } +} + +/* SHA384/512 Final padding and digest calculation */ + +static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen) +{ uint_32t i = (uint_32t)((ctx->count[0] >> 3) & SHA512_MASK); + uint_64t m1; + + /* put bytes in the buffer in an order in which references to */ + /* 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + bsw_64(ctx->wbuf, (i + 8) >> 3); + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. Note that */ + /* we can always add the first padding byte here because the */ + /* buffer always has at least one empty slot */ + m1 = (unsigned char)0x80 >> (ctx->count[0] & 7); + ctx->wbuf[i >> 3] &= ((li_64(ffffffffffffff00) | (~m1 + 1)) << 8 * (~i & 7)); + ctx->wbuf[i >> 3] |= (m1 << 8 * (~i & 7)); + + /* we need 17 or more empty byte positions, one for the padding */ + /* byte (above) and sixteen for the length count. If there is */ + /* not enough space pad and empty the buffer */ + if(i > SHA512_BLOCK_SIZE - 17) + { + if(i < 120) ctx->wbuf[15] = 0; + sha512_compile(ctx); + i = 0; + } + else + i = (i >> 3) + 1; + + while(i < 14) + ctx->wbuf[i++] = 0; + + /* the following 64-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 64-bit */ + /* word values. */ + ctx->wbuf[14] = ctx->count[1]; + ctx->wbuf[15] = ctx->count[0]; + sha512_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < hlen; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7))); +} + +#endif + +#if defined(SHA_384) + +/* SHA384 initialisation data */ + +const uint_64t i384[80] = +{ + li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507), + li_64(9159015a3070dd17), li_64(152fecd8f70e5939), + li_64(67332667ffc00b31), li_64(8eb44a8768581511), + li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4) +}; + +VOID_RETURN sha384_begin(sha384_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i384, 8 * sizeof(uint_64t)); +} + +VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]) +{ + sha_end2(hval, ctx, SHA384_DIGEST_SIZE); +} + +VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha384_ctx cx[1]; + + sha384_begin(cx); + sha384_hash(data, len, cx); + sha_end2(hval, cx, SHA384_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_512) + +/* SHA512 initialisation data */ + +const uint_64t i512[80] = +{ + li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b), + li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1), + li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f), + li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179) +}; + +VOID_RETURN sha512_begin(sha512_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i512, 8 * sizeof(uint_64t)); +} + +VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]) +{ + sha_end2(hval, ctx, SHA512_DIGEST_SIZE); +} + +VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha512_ctx cx[1]; + + sha512_begin(cx); + sha512_hash(data, len, cx); + sha_end2(hval, cx, SHA512_DIGEST_SIZE); +} + +#endif + +#if defined(SHA_2) + +#define CTX_224(x) ((x)->uu->ctx256) +#define CTX_256(x) ((x)->uu->ctx256) +#define CTX_384(x) ((x)->uu->ctx512) +#define CTX_512(x) ((x)->uu->ctx512) + +/* SHA2 initialisation */ + +INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1]) +{ + switch(len) + { +#if defined(SHA_224) + case 224: + case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; + memcpy(CTX_256(ctx)->hash, i224, 32); + ctx->sha2_len = 28; return EXIT_SUCCESS; +#endif +#if defined(SHA_256) + case 256: + case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; + memcpy(CTX_256(ctx)->hash, i256, 32); + ctx->sha2_len = 32; return EXIT_SUCCESS; +#endif +#if defined(SHA_384) + case 384: + case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0; + memcpy(CTX_384(ctx)->hash, i384, 64); + ctx->sha2_len = 48; return EXIT_SUCCESS; +#endif +#if defined(SHA_512) + case 512: + case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0; + memcpy(CTX_512(ctx)->hash, i512, 64); + ctx->sha2_len = 64; return EXIT_SUCCESS; +#endif + default: return EXIT_FAILURE; + } +} + +VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { +#if defined(SHA_224) + case 28: sha224_hash(data, len, CTX_224(ctx)); return; +#endif +#if defined(SHA_256) + case 32: sha256_hash(data, len, CTX_256(ctx)); return; +#endif +#if defined(SHA_384) + case 48: sha384_hash(data, len, CTX_384(ctx)); return; +#endif +#if defined(SHA_512) + case 64: sha512_hash(data, len, CTX_512(ctx)); return; +#endif + } +} + +VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { +#if defined(SHA_224) + case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return; +#endif +#if defined(SHA_256) + case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return; +#endif +#if defined(SHA_384) + case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return; +#endif +#if defined(SHA_512) + case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return; +#endif + } +} + +INT_RETURN sha2(unsigned char hval[], unsigned long size, + const unsigned char data[], unsigned long len) +{ sha2_ctx cx[1]; + + if(sha2_begin(size, cx) == EXIT_SUCCESS) + { + sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS; + } + else + return EXIT_FAILURE; +} + +#endif + +#if defined(__cplusplus) +} +#endif diff --git a/packages/clib/sha1/shasum.c b/packages/clib/sha1/shasum.c new file mode 100644 index 000000000..b6a175129 --- /dev/null +++ b/packages/clib/sha1/shasum.c @@ -0,0 +1,62 @@ + +#include +#include +#include + +#include "sha2.h" + +#define BUF_SIZE 16384 + +int main(int argc, char *argv[]) +{ FILE *inf; + sha256_ctx ctx[1]; + unsigned char buf[BUF_SIZE], hval[SHA256_DIGEST_SIZE]; + int i, len, is_console; + + if(argc != 2) + { + printf("\nusage: shasum filename\n"); + exit(0); + } + + if(is_console = (!strcmp(argv[1], "con") || !strcmp(argv[1], "CON"))) + { + if(!(inf = fopen(argv[1], "r"))) + { + printf("\n%s not found\n", argv[1]); + exit(0); + } + } + else if(!(inf = fopen(argv[1], "rb"))) + { + printf("\n%s not found\n", argv[1]); + exit(0); + } + + sha256_begin(ctx); + do + { + len = (int)fread(buf, 1, BUF_SIZE, inf); + i = len; + if(is_console) + { + i = 0; + while(i < len && buf[i] != '\x1a') + ++i; + } + if(i) + sha256_hash(buf, i, ctx); + } + while + (len && i == len); + + fclose(inf); + sha256_end(hval, ctx); + + printf("\n"); + for(i = 0; i < SHA256_DIGEST_SIZE; ++i) + printf("%02x", hval[i]); + printf("\n"); + + return 0; +} diff --git a/packages/clib/sha4pl.c b/packages/clib/sha4pl.c new file mode 100644 index 000000000..f87eec687 --- /dev/null +++ b/packages/clib/sha4pl.c @@ -0,0 +1,271 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _ISOC99_SOURCE +#define USE_SHA256 1 + +#include +#include "error.h" +#include "sha1/sha1.h" +#include "sha1/sha2.h" +#include "sha1/hmac.h" +#include + +static atom_t ATOM_sha1; +static atom_t ATOM_sha224; +static atom_t ATOM_sha256; +static atom_t ATOM_sha384; +static atom_t ATOM_sha512; +static atom_t ATOM_algorithm; + +typedef enum +{ ALGORITHM_SHA1, + ALGORITHM_SHA224, + ALGORITHM_SHA256, + ALGORITHM_SHA384, + ALGORITHM_SHA512 +} sha_algorithm; + + +typedef struct +{ sha_algorithm algorithm; + size_t digest_size; + term_t algorithm_term; +} optval; + +#define CONTEXT_MAGIC (~ 0x53484163L) + +struct context +{ int magic; + optval opts; + union { + sha1_ctx sha1; + sha2_ctx sha2; + } context; +}; + +static int +sha_options(term_t options, optval *result) +{ term_t opts = PL_copy_term_ref(options); + term_t opt = PL_new_term_ref(); + + /* defaults */ + memset(result, 0, sizeof(*result)); + result->algorithm = ALGORITHM_SHA1; + result->digest_size = SHA1_DIGEST_SIZE; + + while(PL_get_list(opts, opt, opts)) + { atom_t aname; + int arity; + + if ( PL_get_name_arity(opt, &aname, &arity) && arity == 1 ) + { term_t a = PL_new_term_ref(); + + _PL_get_arg(1, opt, a); + + if ( aname == ATOM_algorithm ) + { atom_t a_algorithm; + + result->algorithm_term = a; + if ( !PL_get_atom(a, &a_algorithm) ) + return pl_error(NULL, 0, NULL, ERR_TYPE, a, "algorithm"); + if ( a_algorithm == ATOM_sha1 ) + { result->algorithm = ALGORITHM_SHA1; + result->digest_size = SHA1_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha224 ) + { result->algorithm = ALGORITHM_SHA224; + result->digest_size = SHA224_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha256 ) + { result->algorithm = ALGORITHM_SHA256; + result->digest_size = SHA256_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha384 ) + { result->algorithm = ALGORITHM_SHA384; + result->digest_size = SHA384_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha512 ) + { result->algorithm = ALGORITHM_SHA512; + result->digest_size = SHA512_DIGEST_SIZE; + } else + return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "algorithm"); + } + } else + { return pl_error(NULL, 0, NULL, ERR_TYPE, opt, "option"); + } + } + + if ( !PL_get_nil(opts) ) + return pl_error("sha_hash", 1, NULL, ERR_TYPE, opts, "list"); + + return TRUE; +} + + + + +static foreign_t +pl_sha_hash(term_t from, term_t hash, term_t options) +{ char *data; + size_t datalen; + optval opts; + unsigned char hval[SHA2_MAX_DIGEST_SIZE]; + + if ( !sha_options(options, &opts) ) + return FALSE; + + if ( !PL_get_nchars(from, &datalen, &data, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( opts.algorithm == ALGORITHM_SHA1 ) + { sha1((unsigned char*)hval, + (unsigned char*)data, (unsigned long)datalen); + } else + { sha2((unsigned char*)hval, (unsigned long) opts.digest_size, + (unsigned char*)data, (unsigned long)datalen); + } + + return PL_unify_list_ncodes(hash, opts.digest_size, (char*)hval); +} + + +static foreign_t +pl_sha_new_ctx(term_t ctx, term_t options) +{ struct context c; + optval *op = &(c.opts); + + if ( !sha_options(options, op) ) + return FALSE; + + c.magic = CONTEXT_MAGIC; + + if ( op->algorithm == ALGORITHM_SHA1 ) + { sha1_begin(&(c.context.sha1)); + } else + { sha2_begin((unsigned long) op->digest_size, &(c.context.sha2)); + } + + /* NB: the context size depends on the digest size */ + /* (e. g., sha512_ctx is twice as long as sha256_ctx) */ + /* so there're extra data. It will do no harm, though. */ + /* . */ + return PL_unify_string_nchars(ctx, sizeof(c), (char*)&c); +} + + +static foreign_t +pl_sha_hash_ctx(term_t old_ctx, term_t from, term_t new_ctx, term_t hash) +{ char *data; + size_t datalen; + struct context *cp; + size_t clen; + unsigned char hval[SHA2_MAX_DIGEST_SIZE]; + + if ( !PL_get_nchars(from, &datalen, &data, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( !PL_get_string_chars(old_ctx, (char **)&cp, &clen) ) + return FALSE; + + if ( clen != sizeof (*cp) + || cp->magic != CONTEXT_MAGIC ) { + return pl_error(NULL, 0, "Invalid OldContext passed", + ERR_DOMAIN, old_ctx, "algorithm"); + } + + if ( cp->opts.algorithm == ALGORITHM_SHA1 ) + { sha1_ctx *c1p = &(cp->context.sha1); + sha1_hash((unsigned char*)data, (unsigned long)datalen, c1p); + if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) ) + return FALSE; + sha1_end((unsigned char *)hval, c1p); + } else + { sha2_ctx *c1p = &(cp->context.sha2); + sha2_hash((unsigned char*)data, (unsigned long)datalen, c1p); + if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) ) + return FALSE; + sha2_end((unsigned char *)hval, c1p); + } + + /* . */ + return PL_unify_list_ncodes(hash, cp->opts.digest_size, (char*)hval); +} + + +static foreign_t +pl_hmac_sha(term_t key, term_t data, term_t mac, term_t options) +{ char *sdata, *skey; + size_t datalen, keylen; + optval opts; + unsigned char digest[SHA2_MAX_DIGEST_SIZE]; + + if ( !PL_get_nchars(key, &keylen, &skey, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + if ( !PL_get_nchars(data, &datalen, &sdata, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( !sha_options(options, &opts) ) + return FALSE; + + switch(opts.algorithm) + { case ALGORITHM_SHA1: + hmac_sha1((unsigned char*)skey, (unsigned long)keylen, + (unsigned char*)sdata, (unsigned long)datalen, + digest, (unsigned long)opts.digest_size); + break; + case ALGORITHM_SHA256: + hmac_sha256((unsigned char*)skey, (unsigned long)keylen, + (unsigned char*)sdata, (unsigned long)datalen, + digest, (unsigned long)opts.digest_size); + break; + default: + return pl_error(NULL, 0, "HMAC-SHA only for SHA-1 and SHA-256", + ERR_DOMAIN, opts.algorithm_term, "algorithm"); + } + + return PL_unify_list_ncodes(mac, opts.digest_size, (char*)digest); +} + + +#define MKATOM(n) ATOM_ ## n = PL_new_atom(#n); + +install_t +install_sha4pl() +{ MKATOM(sha1); /* =160 */ + MKATOM(sha224); + MKATOM(sha256); + MKATOM(sha384); + MKATOM(sha512); + MKATOM(algorithm); + + PL_register_foreign("sha_hash", 3, pl_sha_hash, 0); + PL_register_foreign("sha_new_ctx", 2, pl_sha_new_ctx, 0); + PL_register_foreign("sha_hash_ctx", 4, pl_sha_hash_ctx, 0); + PL_register_foreign("hmac_sha", 4, pl_hmac_sha, 0); +} diff --git a/packages/clib/sha4pl.c~ b/packages/clib/sha4pl.c~ new file mode 100644 index 000000000..f87eec687 --- /dev/null +++ b/packages/clib/sha4pl.c~ @@ -0,0 +1,271 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _ISOC99_SOURCE +#define USE_SHA256 1 + +#include +#include "error.h" +#include "sha1/sha1.h" +#include "sha1/sha2.h" +#include "sha1/hmac.h" +#include + +static atom_t ATOM_sha1; +static atom_t ATOM_sha224; +static atom_t ATOM_sha256; +static atom_t ATOM_sha384; +static atom_t ATOM_sha512; +static atom_t ATOM_algorithm; + +typedef enum +{ ALGORITHM_SHA1, + ALGORITHM_SHA224, + ALGORITHM_SHA256, + ALGORITHM_SHA384, + ALGORITHM_SHA512 +} sha_algorithm; + + +typedef struct +{ sha_algorithm algorithm; + size_t digest_size; + term_t algorithm_term; +} optval; + +#define CONTEXT_MAGIC (~ 0x53484163L) + +struct context +{ int magic; + optval opts; + union { + sha1_ctx sha1; + sha2_ctx sha2; + } context; +}; + +static int +sha_options(term_t options, optval *result) +{ term_t opts = PL_copy_term_ref(options); + term_t opt = PL_new_term_ref(); + + /* defaults */ + memset(result, 0, sizeof(*result)); + result->algorithm = ALGORITHM_SHA1; + result->digest_size = SHA1_DIGEST_SIZE; + + while(PL_get_list(opts, opt, opts)) + { atom_t aname; + int arity; + + if ( PL_get_name_arity(opt, &aname, &arity) && arity == 1 ) + { term_t a = PL_new_term_ref(); + + _PL_get_arg(1, opt, a); + + if ( aname == ATOM_algorithm ) + { atom_t a_algorithm; + + result->algorithm_term = a; + if ( !PL_get_atom(a, &a_algorithm) ) + return pl_error(NULL, 0, NULL, ERR_TYPE, a, "algorithm"); + if ( a_algorithm == ATOM_sha1 ) + { result->algorithm = ALGORITHM_SHA1; + result->digest_size = SHA1_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha224 ) + { result->algorithm = ALGORITHM_SHA224; + result->digest_size = SHA224_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha256 ) + { result->algorithm = ALGORITHM_SHA256; + result->digest_size = SHA256_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha384 ) + { result->algorithm = ALGORITHM_SHA384; + result->digest_size = SHA384_DIGEST_SIZE; + } else if ( a_algorithm == ATOM_sha512 ) + { result->algorithm = ALGORITHM_SHA512; + result->digest_size = SHA512_DIGEST_SIZE; + } else + return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "algorithm"); + } + } else + { return pl_error(NULL, 0, NULL, ERR_TYPE, opt, "option"); + } + } + + if ( !PL_get_nil(opts) ) + return pl_error("sha_hash", 1, NULL, ERR_TYPE, opts, "list"); + + return TRUE; +} + + + + +static foreign_t +pl_sha_hash(term_t from, term_t hash, term_t options) +{ char *data; + size_t datalen; + optval opts; + unsigned char hval[SHA2_MAX_DIGEST_SIZE]; + + if ( !sha_options(options, &opts) ) + return FALSE; + + if ( !PL_get_nchars(from, &datalen, &data, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( opts.algorithm == ALGORITHM_SHA1 ) + { sha1((unsigned char*)hval, + (unsigned char*)data, (unsigned long)datalen); + } else + { sha2((unsigned char*)hval, (unsigned long) opts.digest_size, + (unsigned char*)data, (unsigned long)datalen); + } + + return PL_unify_list_ncodes(hash, opts.digest_size, (char*)hval); +} + + +static foreign_t +pl_sha_new_ctx(term_t ctx, term_t options) +{ struct context c; + optval *op = &(c.opts); + + if ( !sha_options(options, op) ) + return FALSE; + + c.magic = CONTEXT_MAGIC; + + if ( op->algorithm == ALGORITHM_SHA1 ) + { sha1_begin(&(c.context.sha1)); + } else + { sha2_begin((unsigned long) op->digest_size, &(c.context.sha2)); + } + + /* NB: the context size depends on the digest size */ + /* (e. g., sha512_ctx is twice as long as sha256_ctx) */ + /* so there're extra data. It will do no harm, though. */ + /* . */ + return PL_unify_string_nchars(ctx, sizeof(c), (char*)&c); +} + + +static foreign_t +pl_sha_hash_ctx(term_t old_ctx, term_t from, term_t new_ctx, term_t hash) +{ char *data; + size_t datalen; + struct context *cp; + size_t clen; + unsigned char hval[SHA2_MAX_DIGEST_SIZE]; + + if ( !PL_get_nchars(from, &datalen, &data, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( !PL_get_string_chars(old_ctx, (char **)&cp, &clen) ) + return FALSE; + + if ( clen != sizeof (*cp) + || cp->magic != CONTEXT_MAGIC ) { + return pl_error(NULL, 0, "Invalid OldContext passed", + ERR_DOMAIN, old_ctx, "algorithm"); + } + + if ( cp->opts.algorithm == ALGORITHM_SHA1 ) + { sha1_ctx *c1p = &(cp->context.sha1); + sha1_hash((unsigned char*)data, (unsigned long)datalen, c1p); + if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) ) + return FALSE; + sha1_end((unsigned char *)hval, c1p); + } else + { sha2_ctx *c1p = &(cp->context.sha2); + sha2_hash((unsigned char*)data, (unsigned long)datalen, c1p); + if ( !PL_unify_string_nchars(new_ctx, sizeof(*cp), (char*)cp) ) + return FALSE; + sha2_end((unsigned char *)hval, c1p); + } + + /* . */ + return PL_unify_list_ncodes(hash, cp->opts.digest_size, (char*)hval); +} + + +static foreign_t +pl_hmac_sha(term_t key, term_t data, term_t mac, term_t options) +{ char *sdata, *skey; + size_t datalen, keylen; + optval opts; + unsigned char digest[SHA2_MAX_DIGEST_SIZE]; + + if ( !PL_get_nchars(key, &keylen, &skey, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + if ( !PL_get_nchars(data, &datalen, &sdata, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + return FALSE; + + if ( !sha_options(options, &opts) ) + return FALSE; + + switch(opts.algorithm) + { case ALGORITHM_SHA1: + hmac_sha1((unsigned char*)skey, (unsigned long)keylen, + (unsigned char*)sdata, (unsigned long)datalen, + digest, (unsigned long)opts.digest_size); + break; + case ALGORITHM_SHA256: + hmac_sha256((unsigned char*)skey, (unsigned long)keylen, + (unsigned char*)sdata, (unsigned long)datalen, + digest, (unsigned long)opts.digest_size); + break; + default: + return pl_error(NULL, 0, "HMAC-SHA only for SHA-1 and SHA-256", + ERR_DOMAIN, opts.algorithm_term, "algorithm"); + } + + return PL_unify_list_ncodes(mac, opts.digest_size, (char*)digest); +} + + +#define MKATOM(n) ATOM_ ## n = PL_new_atom(#n); + +install_t +install_sha4pl() +{ MKATOM(sha1); /* =160 */ + MKATOM(sha224); + MKATOM(sha256); + MKATOM(sha384); + MKATOM(sha512); + MKATOM(algorithm); + + PL_register_foreign("sha_hash", 3, pl_sha_hash, 0); + PL_register_foreign("sha_new_ctx", 2, pl_sha_new_ctx, 0); + PL_register_foreign("sha_hash_ctx", 4, pl_sha_hash_ctx, 0); + PL_register_foreign("hmac_sha", 4, pl_hmac_sha, 0); +} diff --git a/packages/clib/sockcommon.c b/packages/clib/sockcommon.c new file mode 100644 index 000000000..0994e8816 --- /dev/null +++ b/packages/clib/sockcommon.c @@ -0,0 +1,180 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2000-2008, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Shared stuff between the normal socket interface and the TIPC one. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + + /******************************* + * IO-STREAM STUFF * + *******************************/ + +#define fdFromHandle(p) ((nbio_sock_t)((long)(p))) + +static ssize_t +tcp_read_handle(void *handle, char *buf, size_t bufSize) +{ nbio_sock_t sock = fdFromHandle(handle); + + return nbio_read(sock, buf, bufSize); +} + + +static ssize_t +tcp_write_handle(void *handle, char *buf, size_t bufSize) +{ nbio_sock_t sock = fdFromHandle(handle); + + return nbio_write(sock, buf, bufSize); +} + + +static long +tcp_seek_null(void *handle, long offset, int whence) +{ return -1; +} + + +static int +tcp_close_input_handle(void *handle) +{ nbio_sock_t socket = fdFromHandle(handle); + + return nbio_close_input(socket); +} + + +static int +tcp_close_output_handle(void *handle) +{ nbio_sock_t socket = fdFromHandle(handle); + + return nbio_close_output(socket); +} + + +static int +tcp_control(void *handle, int action, void *arg) +{ nbio_sock_t socket = fdFromHandle(handle); + + switch(action) + { case SIO_GETFILENO: + { SOCKET fd = nbio_fd(socket); + SOCKET *fdp = arg; + *fdp = fd; + return 0; + } + case SIO_LASTERROR: + { const char *s; + + if ( (s=nbio_last_error(socket)) ) + { const char **sp = arg; + *sp = s; + return 0; + } + + return -1; + } + case SIO_SETENCODING: + case SIO_FLUSHOUTPUT: + return 0; + default: + return -1; + } +} + + +static IOFUNCTIONS readFunctions = +{ tcp_read_handle, + tcp_write_handle, + tcp_seek_null, + tcp_close_input_handle, + tcp_control +}; + + +static IOFUNCTIONS writeFunctions = +{ tcp_read_handle, + tcp_write_handle, + tcp_seek_null, + tcp_close_output_handle, + tcp_control +}; + + +static foreign_t +pl_open_socket(term_t Socket, term_t Read, term_t Write) +{ IOSTREAM *in, *out; + int socket; + void *handle; + + if ( !tcp_get_socket(Socket, &socket) ) + return FALSE; + handle = (void *)(long)socket; + + in = Snew(handle, SIO_INPUT|SIO_RECORDPOS|SIO_FBUF, &readFunctions); + in->encoding = ENC_OCTET; + if ( !PL_open_stream(Read, in) ) + return FALSE; + nbio_setopt(socket, TCP_INSTREAM, in); + + if ( !(nbio_get_flags(socket) & PLSOCK_LISTEN) ) + { out = Snew(handle, SIO_OUTPUT|SIO_RECORDPOS|SIO_FBUF, &writeFunctions); + out->encoding = ENC_OCTET; + if ( !PL_open_stream(Write, out) ) + return FALSE; + nbio_setopt(socket, TCP_OUTSTREAM, out); + } + + return TRUE; +} + + +static foreign_t +pl_listen(term_t Sock, term_t BackLog) +{ int socket; + int backlog; + + if ( !tcp_get_socket(Sock, &socket) ) + return FALSE; + + if ( !PL_get_integer(BackLog, &backlog) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, -1, BackLog, "integer"); + + if ( nbio_listen(socket, backlog) < 0 ) + return FALSE; + + return TRUE; +} + + +static foreign_t +pl_close_socket(term_t socket) +{ int sock; + + if ( !tcp_get_socket(socket, &sock) ) + return FALSE; + + if ( nbio_closesocket(sock) < 0 ) + return nbio_error(errno, TCP_ERRNO);; + + return TRUE; +} diff --git a/packages/clib/socket.c b/packages/clib/socket.c new file mode 100644 index 000000000..099bed7de --- /dev/null +++ b/packages/clib/socket.c @@ -0,0 +1,648 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define O_DEBUG 1 + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# if HAVE_ALLOCA_H +# include +# endif +#endif + +#ifdef __CYGWIN__ +#undef HAVE_H_ERRNO +#endif + +#include "nonblockio.h" + +#include +#include "clib.h" +#include "error.h" + +#include +#include +#include +#include +#include +#include +#ifdef __WINDOWS__ +#include +#endif + +static atom_t ATOM_reuseaddr; /* "reuseaddr" */ +static atom_t ATOM_broadcast; /* "broadcast" */ +static atom_t ATOM_nodelay; /* "nodelay" */ +static atom_t ATOM_dispatch; /* "dispatch" */ +static atom_t ATOM_nonblock; /* "nonblock" */ +static atom_t ATOM_infinite; /* "infinite" */ +static atom_t ATOM_as; /* "as" */ +static atom_t ATOM_atom; /* "atom" */ +static atom_t ATOM_string; /* "string" */ +static atom_t ATOM_codes; /* "codes" */ + +static functor_t FUNCTOR_socket1; /* $socket(Id) */ + + + /******************************* + * CONVERSION * + *******************************/ + +NBIO_EXPORT(int) +tcp_get_socket(term_t Socket, int *id) +{ IOSTREAM *s; + int socket; + + if ( PL_is_functor(Socket, FUNCTOR_socket1) ) + { term_t a = PL_new_term_ref(); + + _PL_get_arg(1, Socket, a); + if ( PL_get_integer(a, id) ) + return TRUE; + } + + if ( PL_get_stream_handle(Socket, &s) ) + { socket = (int)(intptr_t)s->handle; + + *id = socket; + return TRUE; + } + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, -1, Socket, "socket"); +} + + +static int +tcp_unify_socket(term_t Socket, int id) +{ return PL_unify_term(Socket, + PL_FUNCTOR, FUNCTOR_socket1, + IntArg(id)); +} + + +static foreign_t +pl_host_to_address(term_t Host, term_t Ip) +{ struct in_addr ip; + struct hostent *host; + char *host_name; + + if ( PL_get_atom_chars(Host, &host_name) ) + { if ( (host = gethostbyname(host_name)) ) + { if ( sizeof(ip) == host->h_length ) + { memcpy(&ip, host->h_addr, host->h_length); + return nbio_unify_ip4(Ip, ntohl(ip.s_addr)); + } else + return PL_warning("tcp_host_to_address/2: length mismatch in address"); + } else + return nbio_error(h_errno, TCP_HERRNO); + } else if ( nbio_get_ip(Ip, &ip) ) + { if ( (host = gethostbyaddr((char *)&ip, sizeof(ip), AF_INET)) ) + return PL_unify_atom_chars(Host, host->h_name); + else + return nbio_error(h_errno, TCP_HERRNO); + } + + return FALSE; +} + + +static foreign_t +pl_setopt(term_t Socket, term_t opt) +{ int socket; + atom_t a; + int arity; + + if ( !tcp_get_socket(Socket, &socket) ) + return FALSE; + + if ( PL_get_name_arity(opt, &a, &arity) ) + { if ( a == ATOM_reuseaddr && arity == 0 ) + { if ( nbio_setopt(socket, TCP_REUSEADDR, TRUE) == 0 ) + return TRUE; + + return FALSE; + } else if ( a == ATOM_nodelay && arity <= 1 ) + { int enable, rc; + + if ( arity == 0 ) + { enable = TRUE; + } else /*if ( arity == 1 )*/ + { term_t a = PL_new_term_ref(); + + _PL_get_arg(1, opt, a); + if ( !PL_get_bool(a, &enable) ) + return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "boolean"); + } + + if ( (rc=nbio_setopt(socket, TCP_NO_DELAY, enable) == 0) ) + return TRUE; + if ( rc == -2 ) + goto not_implemented; + + return FALSE; + } else if ( a == ATOM_broadcast && arity == 0 ) + { if ( nbio_setopt(socket, UDP_BROADCAST, TRUE) == 0 ) + return TRUE; + + return FALSE; + } else if ( a == ATOM_dispatch && arity == 1 ) + { int val; + term_t a1 = PL_new_term_ref(); + + if ( PL_get_arg(1, opt, a1) && PL_get_bool(a1, &val) ) + { if ( nbio_setopt(socket, TCP_DISPATCH, val) == 0 ) + return TRUE; + return FALSE; + } + } else if ( a == ATOM_nonblock && arity == 0 ) + { if ( nbio_setopt(socket, TCP_NONBLOCK) == 0 ) + return TRUE; + return FALSE; + } + } + +not_implemented: + return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option"); +} + + +#include "sockcommon.c" + + /******************************* + * UDP SOCKETS * + *******************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +udp_receive(+Socket, -String, -From, +Options) +udp_send(+String, +String, +To, +Options) + +From/To are of the format : +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#define UDP_MAXDATA 4096 + +static int +unify_address(term_t t, struct sockaddr_in *addr) +{ term_t av = PL_new_term_refs(2); + + if ( !nbio_unify_ip4(av+0, ntohl(addr->sin_addr.s_addr)) || + !PL_unify_integer(av+1, ntohs(addr->sin_port)) ) + return FALSE; + + return PL_unify_term(t, PL_FUNCTOR_CHARS, ":", 2, + PL_TERM, av+0, + PL_TERM, av+1); +} + + + +static foreign_t +udp_receive(term_t Socket, term_t Data, term_t From, term_t options) +{ struct sockaddr_in sockaddr; +#ifdef __WINDOWS__ + int alen = sizeof(sockaddr); +#else + socklen_t alen = sizeof(sockaddr); +#endif + int socket; + int flags = 0; + char buf[UDP_MAXDATA]; + ssize_t n; + int as = PL_STRING; + + if ( !PL_get_nil(options) ) + { term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + term_t arg = PL_new_term_ref(); + + while(PL_get_list(tail, head, tail)) + { atom_t name; + int arity; + + if ( PL_get_name_arity(head, &name, &arity) && arity == 1 ) + { _PL_get_arg(1, head, arg); + + if ( name == ATOM_as ) + { atom_t a; + + if ( !PL_get_atom(arg, &a) ) + return pl_error(NULL, 0, NULL, ERR_TYPE, head, "atom"); + if ( a == ATOM_atom ) + as = PL_ATOM; + else if ( a == ATOM_codes ) + as = PL_CODE_LIST; + else if ( a == ATOM_string ) + as = PL_STRING; + else + return pl_error(NULL, 0, NULL, ERR_DOMAIN, arg, "as_option"); + } + + } else + return pl_error(NULL, 0, NULL, ERR_TYPE, head, "option"); + } + if ( !PL_get_nil(tail) ) + return pl_error(NULL, 0, NULL, ERR_TYPE, tail, "list"); + } + + + if ( !tcp_get_socket(Socket, &socket) || + !nbio_get_sockaddr(From, &sockaddr) ) + return FALSE; + + if ( (n=nbio_recvfrom(socket, buf, sizeof(buf), flags, + (struct sockaddr*)&sockaddr, &alen)) == -1 ) + return nbio_error(errno, TCP_ERRNO); + + if ( !PL_unify_chars(Data, as, n, buf) ) + return FALSE; + + return unify_address(From, &sockaddr); +} + + +static foreign_t +udp_send(term_t Socket, term_t Data, term_t To, term_t Options) +{ struct sockaddr_in sockaddr; +#ifdef __WINDOWS__ + int alen = sizeof(sockaddr); +#else + int alen = sizeof(sockaddr); +#endif + int socket; + int flags = 0L; + char *data; + size_t dlen; + ssize_t n; + + if ( !PL_get_nchars(Data, &dlen, &data, CVT_ALL|CVT_EXCEPTION) ) + return FALSE; + + if ( !tcp_get_socket(Socket, &socket) || + !nbio_get_sockaddr(To, &sockaddr) ) + return FALSE; + + if ( (n=nbio_sendto(socket, data, + (int)dlen, + flags, + (struct sockaddr*)&sockaddr, alen)) == -1 ) + return nbio_error(errno, TCP_ERRNO); + + return TRUE; +} + + /******************************* + * PROLOG CONNECTION * + *******************************/ + + +static foreign_t +create_socket(term_t socket, int type) +{ int sock; + + sock = nbio_socket(AF_INET, type, 0); + if ( sock < 0 ) + return FALSE; + + return tcp_unify_socket(socket, sock); +} + + +static foreign_t +tcp_socket(term_t socket) +{ return create_socket(socket, SOCK_STREAM); +} + + +static foreign_t +udp_socket(term_t socket) +{ return create_socket(socket, SOCK_DGRAM); +} + + +static foreign_t +pl_connect(term_t Socket, term_t Address) +{ int sock; + struct sockaddr_in sockaddr; + + if ( !tcp_get_socket(Socket, &sock) || + !nbio_get_sockaddr(Address, &sockaddr) ) + return FALSE; + + if ( nbio_connect(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == 0 ) + return TRUE; + + return FALSE; +} + + +static foreign_t +pl_bind(term_t Socket, term_t Address) +{ struct sockaddr_in sockaddr; + int socket; + + memset(&sockaddr, 0, sizeof(sockaddr)); + + if ( !tcp_get_socket(Socket, &socket) || + !nbio_get_sockaddr(Address, &sockaddr) ) + return FALSE; + + if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0 ) + return FALSE; + + if ( PL_is_variable(Address) ) + { SOCKET fd = nbio_fd(socket); + struct sockaddr_in addr; +#ifdef __WINDOWS__ + int len = sizeof(addr); +#else + socklen_t len = sizeof(addr); +#endif + + if ( getsockname(fd, (struct sockaddr *) &addr, &len) ) + return nbio_error(errno, TCP_ERRNO); + return PL_unify_integer(Address, ntohs(addr.sin_port)); + } + + return TRUE; +} + + +static foreign_t +pl_accept(term_t Master, term_t Slave, term_t Peer) +{ int master, slave; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + + if ( !tcp_get_socket(Master, &master) ) + return FALSE; + + if ( (slave = nbio_accept(master, (struct sockaddr*)&addr, &addrlen)) < 0 ) + return FALSE; + /* TBD: close on failure */ + if ( nbio_unify_ip4(Peer, ntohl(addr.sin_addr.s_addr)) && + tcp_unify_socket(Slave, slave) ) + return TRUE; + + return FALSE; +} + + + +static foreign_t +pl_gethostname(term_t name) +{ static atom_t hname; + + if ( !hname ) + { char buf[256]; + + if ( gethostname(buf, sizeof(buf)) == 0 ) + { struct hostent *he; + + if ( (he = gethostbyname(buf)) ) + hname = PL_new_atom(he->h_name); + else + hname = PL_new_atom(buf); + } else + { return nbio_error(h_errno, TCP_HERRNO); + } + } + + return PL_unify_atom(name, hname); +} + + + /******************************* + * SELECT * + *******************************/ + +typedef struct fdentry +{ int fd; + term_t stream; + struct fdentry *next; +} fdentry; + + +static term_t +findmap(fdentry *map, int fd) +{ for( ; map; map = map->next ) + { if ( map->fd == fd ) + return map->stream; + } + assert(0); + return 0; +} + + +static int +is_socket_stream(IOSTREAM *s) +{ if ( s->functions == &readFunctions /* || + s->functions == &writeFunctions */ ) + return TRUE; + + return FALSE; +} + + +static foreign_t +tcp_select(term_t Streams, term_t Available, term_t timeout) +{ fd_set fds; + struct timeval t, *to; + double time; + int n, max = 0, ret, min = 1000000; + fdentry *map = NULL; + term_t head = PL_new_term_ref(); + term_t streams = PL_copy_term_ref(Streams); + term_t available = PL_copy_term_ref(Available); + term_t ahead = PL_new_term_ref(); + int from_buffer = 0; + atom_t a; + + FD_ZERO(&fds); + while( PL_get_list(streams, head, streams) ) + { IOSTREAM *s; +#ifdef __WINDOWS__ + nbio_sock_t fd; +#else + int fd; +#endif + fdentry *e; + + if ( !PL_get_stream_handle(head, &s) ) + return FALSE; + +#ifdef __WINDOWS__ + fd = fdFromHandle(s->handle); +#else + fd = Sfileno(s); +#endif + + PL_release_stream(s); + if ( fd < 0 || !is_socket_stream(s) ) + { return pl_error("tcp_select", 3, NULL, ERR_DOMAIN, + head, "socket_stream"); + } + /* check for input in buffer */ + if ( s->bufp < s->limitp ) + { if ( !PL_unify_list(available, ahead, available) || + !PL_unify(ahead, head) ) + return FALSE; + from_buffer++; + } + + e = alloca(sizeof(*e)); + e->fd = fd; + e->stream = PL_copy_term_ref(head); + e->next = map; + map = e; + +#ifdef __WINDOWS__ + FD_SET((SOCKET)fd, &fds); +#else + FD_SET(fd, &fds); +#endif + + if ( fd > max ) + max = fd; + if( fd < min ) + min = fd; + } + if ( !PL_get_nil(streams) ) + return pl_error("tcp_select", 3, NULL, ERR_TYPE, Streams, "list"); + + if ( from_buffer > 0 ) + return PL_unify_nil(available); + + if ( PL_get_atom(timeout, &a) && a == ATOM_infinite ) + { to = NULL; + } else + { if ( !PL_get_float(timeout, &time) ) + return pl_error("tcp_select", 3, NULL, + ERR_TYPE, timeout, "number"); + + if ( time >= 0.0 ) + { t.tv_sec = (int)time; + t.tv_usec = ((int)(time * 1000000) % 1000000); + } else + { t.tv_sec = 0; + t.tv_usec = 0; + } + to = &t; + } + + while( (ret=nbio_select(max+1, &fds, NULL, NULL, to)) == -1 && + errno == EINTR ) + { fdentry *e; + + if ( PL_handle_signals() < 0 ) + return FALSE; /* exception */ + + FD_ZERO(&fds); /* EINTR may leave fds undefined */ + for(e=map; e; e=e->next) /* so we rebuild it to be safe */ + { FD_SET((SOCKET)e->fd, &fds); + } + } + + switch(ret) + { case -1: + return pl_error("tcp_select", 3, NULL, ERR_ERRNO, errno, "select", "streams", Streams); + + case 0: /* Timeout */ + break; + + default: /* Something happened -> check fds */ + for(n=min; n <= max; n++) + { if ( FD_ISSET(n, &fds) ) + { if ( !PL_unify_list(available, ahead, available) || + !PL_unify(ahead, findmap(map, n)) ) + return FALSE; + } + } + break; + } + + return PL_unify_nil(available); +} + + +#ifdef O_DEBUG +static foreign_t +pl_debug(term_t val) +{ int dbg; + + if ( PL_get_integer(val, &dbg) ) + { nbio_debug(dbg); + return TRUE; + } + + return FALSE; +} +#endif + +install_t +install_socket() +{ nbio_init("socket"); + + ATOM_reuseaddr = PL_new_atom("reuseaddr"); + ATOM_broadcast = PL_new_atom("broadcast"); + ATOM_nodelay = PL_new_atom("nodelay"); + ATOM_dispatch = PL_new_atom("dispatch"); + ATOM_nonblock = PL_new_atom("nonblock"); + ATOM_infinite = PL_new_atom("infinite"); + ATOM_as = PL_new_atom("as"); + ATOM_atom = PL_new_atom("atom"); + ATOM_string = PL_new_atom("string"); + ATOM_codes = PL_new_atom("codes"); + + FUNCTOR_socket1 = PL_new_functor(PL_new_atom("$socket"), 1); + +#ifdef O_DEBUG + PL_register_foreign_in_module("user", "tcp_debug", 1, pl_debug, 0); +#endif + PL_register_foreign("tcp_accept", 3, pl_accept, 0); + PL_register_foreign("tcp_bind", 2, pl_bind, 0); + PL_register_foreign("tcp_connect", 2, pl_connect, 0); + PL_register_foreign("tcp_listen", 2, pl_listen, 0); + PL_register_foreign("tcp_open_socket", 3, pl_open_socket, 0); + PL_register_foreign("tcp_socket", 1, tcp_socket, 0); + PL_register_foreign("tcp_close_socket", 1, pl_close_socket, 0); + PL_register_foreign("tcp_setopt", 2, pl_setopt, 0); + PL_register_foreign("tcp_host_to_address", 2, pl_host_to_address, 0); + PL_register_foreign("gethostname", 1, pl_gethostname, 0); + PL_register_foreign("tcp_select", 3, tcp_select, 0); + + PL_register_foreign("udp_socket", 1, udp_socket, 0); + PL_register_foreign("udp_receive", 4, udp_receive, 0); + PL_register_foreign("udp_send", 4, udp_send, 0); +} + + +install_t +uninstall_socket() +{ nbio_cleanup(); +} diff --git a/packages/clib/socket.pl b/packages/clib/socket.pl new file mode 100644 index 000000000..7d3fc76be --- /dev/null +++ b/packages/clib/socket.pl @@ -0,0 +1,117 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(socket, + [ tcp_socket/1, % -Socket + tcp_close_socket/1, % +Socket + tcp_open_socket/3, % +Socket, -Read, -Write + tcp_connect/2, % +Socket, +Address + tcp_connect/4, % +Socket, +Address, -Read, -Write) + tcp_bind/2, % +Socket, +Address + tcp_accept/3, % +Master, -Slave, -PeerName + tcp_listen/2, % +Socket, +BackLog + tcp_fcntl/3, % +Socket, +Command, ?Arg + tcp_setopt/2, % +Socket, +Option + tcp_host_to_address/2, % ?HostName, ?Ip-nr + tcp_select/3, % +Inputs, -Ready, +Timeout + gethostname/1, % -HostName + + udp_socket/1, % -Socket + udp_receive/4, % +Socket, -Data, -Sender, +Options + udp_send/4 % +Socket, +Data, +Sender, +Options + ]). +:- use_module(library(shlib)). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +These predicates are documented in the source-distribution of the package +`clib'. See also the SWI-Prolog home-page at http://www.swi-prolog.org +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +:- use_foreign_library(foreign(socket), install_socket). + + + /******************************* + * HOOKABLE CONNECT * + *******************************/ + +%% tcp_connect(+Socket, +Address, -Read, -Write) is det. +% +% Connect a (client) socket to Address and return a bi-directional +% connection through the stream-handles Read and Write. This +% predicate may be hooked by defining socket:tcp_connect_hook/4 +% with the same signature. Hooking can be used to deal with proxy +% connections. E.g., +% +% == +% :- multifile socket:tcp_connect_hook/4. +% +% socket:tcp_connect_hook(Socket, Address, Read, Write) :- +% proxy(ProxyAdress), +% tcp_connect(Socket, ProxyAdress), +% tcp_open_socket(Socket, Read, Write), +% proxy_connect(Address, Read, Write). +% == + +:- multifile + tcp_connect_hook/4. + +tcp_connect(Socket, Address, Read, Write) :- + tcp_connect_hook(Socket, Address, Read, Write), !. +tcp_connect(Socket, Address, Read, Write) :- + tcp_connect(Socket, Address), + tcp_open_socket(Socket, Read, Write). + + + /******************************* + * COMPATIBILITY * + *******************************/ + +tcp_fcntl(Socket, setfl, nonblock) :- !, + tcp_setopt(Socket, nonblock). + + + /******************************* + * HANDLE MESSAGES * + *******************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +The C-layer generates exceptions of the following format, where Message +is extracted from the operating system. + + error(socket_error(Message), _) +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- multifile + prolog:message/3. + +prolog:message(error(socket_error(Message), _)) --> + [ 'Socket error: ~w'-[Message] ]. diff --git a/packages/clib/streaminfo.c b/packages/clib/streaminfo.c new file mode 100644 index 000000000..5368046c8 --- /dev/null +++ b/packages/clib/streaminfo.c @@ -0,0 +1,109 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2009, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "error.h" +#include + +static int +print_byte(int value) +{ if ( isgraph(value) || isspace(value) ) + { Sdprintf("%c", value); + } else + { Sdprintf("\\\\%02x", value); + } + + return 0; +} + +static int +print_buffer(const char *data, size_t len) +{ size_t i; + + Sdprintf("----------------\n"); + for(i=0; i 10 ) + { Sdprintf("<%d 0-bytes>", zeros); + } + i += zeros; + } else + { print_byte(data[i]&0xff); + } + } + if ( data[len-1] != '\n' ) + Sdprintf("\n"); + Sdprintf("----------------\n"); + + return 0; +} + + +static foreign_t +stream_info(term_t stream) +{ IOSTREAM *s; + + if ( !PL_get_stream_handle(stream, &s) ) + { return pl_error("stream_info", 2, NULL, ERR_ARGTYPE, 1, + stream, "stream"); + } + + if ( (s->flags & SIO_INPUT) ) + { if ( s->buffer ) + { if ( s->bufp > s->buffer ) + { Sdprintf("Processed input:\n"); + print_buffer(s->buffer, s->bufp-s->buffer); + } + + if ( s->bufp < s->limitp ) + { Sdprintf("Unprocessed input:\n"); + print_buffer(s->bufp, s->limitp-s->bufp); + } + } + } else if ( (s->flags & SIO_OUTPUT) ) + { if ( s->buffer ) + { if ( s->bufp > s->buffer ) + { Sdprintf("Buffered output:\n"); + print_buffer(s->buffer, s->bufp-s->buffer); + } + + if ( s->bufp < s->limitp ) + { Sdprintf("Possibly sent output (or junk):\n"); + print_buffer(s->bufp, s->limitp-s->bufp); + } + } + } + + return PL_release_stream(s); +} + +install_t +install_streaminfo() +{ PL_register_foreign("$stream_info", 1, stream_info, 0); +} diff --git a/packages/clib/streaminfo.pl b/packages/clib/streaminfo.pl new file mode 100644 index 000000000..02f6d7c8c --- /dev/null +++ b/packages/clib/streaminfo.pl @@ -0,0 +1,85 @@ +/* Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2009, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(stream_info, + [ stream_info/1 % +Stream + ]). + +:- use_foreign_library(foreign(streaminfo)). + +%% stream_info(+Stream) is det. +% +% Print detailed information about a stream or a file-number to +% the error output. The output of this command is meant for +% experts and requires knowledge about the implementation of +% streams. It has been added to diagnose leaking streams in +% web-servers. For example, on linux systems we can examine +% process file-descriptors using +% +% == +% % ls -l /proc//fd +% == +% +% If now (say) descriptor 15 is open where it should not be, we +% can this command to find the associated Prolog streams and print +% as mush as possible information about the stream. +% +% == +% ?- stream_info(15). +% == +% +% @param Stream A stream-handle, alias name or (integer) system +% file handle. + +stream_info(Stream) :- + is_stream(Stream), !, + forall(stream_property(Stream, P), + print_property(P)), + nl, + catch('$stream_info'(Stream), E, true), + ( nonvar(E) + -> format('~w:~t~25|~q~n', ['pending exception', E]) + ; true + ). +stream_info(FileNo) :- + integer(FileNo), !, + findall(S, stream_property(S, file_no(FileNo)), Streams), + length(Streams, Len), + format('File no ~w is connected to ~d streams~n', [FileNo, Len]), + forall(member(Stream, Streams), + ( format('****************~nStream ~p:~n', [Stream]), + stream_info(Stream))). + +print_property(P) :- + P =.. [Name,Value], !, + format('~w:~t~25|~q~n', [Name, Value]). +print_property(input) :- !. +print_property(output) :- !. +print_property(P) :- + format('~p~n', [P]). diff --git a/packages/clib/streampool.pl b/packages/clib/streampool.pl new file mode 100644 index 000000000..31d8718fd --- /dev/null +++ b/packages/clib/streampool.pl @@ -0,0 +1,120 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(stream_pool, + [ add_stream_to_pool/2, % +Stream, :Goal + delete_stream_from_pool/1, % +Stream + close_stream_pool/0, + dispatch_stream_pool/1, % +TimeOut + stream_pool_main_loop/0 + ]). +%:- use_module(library(quintus)). + +:- meta_predicate + add_stream_to_pool(+, :). + +:- volatile + pool/2. % sockets don't survive a saved-state +:- dynamic + pool/2. % Stream, Action + +% add_stream_to_pool(+Stream :Goal) +% +% Call Goal whenever there is input on Stream. + +add_stream_to_pool(Stream, Action) :- + strip_module(Action, Module, Plain), + register_stream(Stream, Module:Plain). + +register_stream(Stream, Goal) :- + assert(pool(Stream, Goal)). + +% delete_stream_from_pool(+Stream) +% +% Retract stream from the pool + +delete_stream_from_pool(Stream) :- + retractall(pool(Stream, _)). + +% close_stream_pool + +close_stream_pool :- + ( retract(pool(Stream, _)), + close(Stream, [force(true)]), + fail + ; true + ). + +% dispatch_stream_pool(+TimeOut) +% +% Wait for input on one or more streams and handle that. Wait for +% at most TimeOut seconds (0 means infinite). + +dispatch_stream_pool(Timeout) :- + findall(S, pool(S, _), Pool), + catch(wait_for_input(Pool, Ready, Timeout), E, true), + debug(tcp, 'Select ~w --> ~w (E=~w)', [Pool, Ready, E]), + ( var(E) + -> actions(Ready) + ; E = error(existence_error(stream, Stream), _) + -> delete_stream_from_pool(Stream) + ). + +actions([]). +actions([H|T]) :- + action(H), + actions(T). + +action(Stream) :- + pool(Stream, Action), + ( catch(Action, E, true) + -> ( var(E) + -> true + ; print_message(error, E) + ) + ; print_message(warning, + goal_failed(Action, stream_pool)) + ). + +% stream_pool_main_loop +% +% Keep handling input from the streams in the pool until they have +% all died away. + +stream_pool_main_loop :- + pool(_, _), !, + ( current_prolog_flag(windows, true) + -> dispatch_stream_pool(1) % so we can break out easily + ; dispatch_stream_pool(0) + ), + stream_pool_main_loop. +stream_pool_main_loop. + diff --git a/packages/clib/streampool.pl~ b/packages/clib/streampool.pl~ new file mode 100644 index 000000000..799ef8568 --- /dev/null +++ b/packages/clib/streampool.pl~ @@ -0,0 +1,120 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(stream_pool, + [ add_stream_to_pool/2, % +Stream, :Goal + delete_stream_from_pool/1, % +Stream + close_stream_pool/0, + dispatch_stream_pool/1, % +TimeOut + stream_pool_main_loop/0 + ]). +:- use_module(library(quintus)). + +:- meta_predicate + add_stream_to_pool(+, :). + +:- volatile + pool/2. % sockets don't survive a saved-state +:- dynamic + pool/2. % Stream, Action + +% add_stream_to_pool(+Stream :Goal) +% +% Call Goal whenever there is input on Stream. + +add_stream_to_pool(Stream, Action) :- + strip_module(Action, Module, Plain), + register_stream(Stream, Module:Plain). + +register_stream(Stream, Goal) :- + assert(pool(Stream, Goal)). + +% delete_stream_from_pool(+Stream) +% +% Retract stream from the pool + +delete_stream_from_pool(Stream) :- + retractall(pool(Stream, _)). + +% close_stream_pool + +close_stream_pool :- + ( retract(pool(Stream, _)), + close(Stream, [force(true)]), + fail + ; true + ). + +% dispatch_stream_pool(+TimeOut) +% +% Wait for input on one or more streams and handle that. Wait for +% at most TimeOut seconds (0 means infinite). + +dispatch_stream_pool(Timeout) :- + findall(S, pool(S, _), Pool), + catch(wait_for_input(Pool, Ready, Timeout), E, true), + debug(tcp, 'Select ~w --> ~w (E=~w)', [Pool, Ready, E]), + ( var(E) + -> actions(Ready) + ; E = error(existence_error(stream, Stream), _) + -> delete_stream_from_pool(Stream) + ). + +actions([]). +actions([H|T]) :- + action(H), + actions(T). + +action(Stream) :- + pool(Stream, Action), + ( catch(Action, E, true) + -> ( var(E) + -> true + ; print_message(error, E) + ) + ; print_message(warning, + goal_failed(Action, stream_pool)) + ). + +% stream_pool_main_loop +% +% Keep handling input from the streams in the pool until they have +% all died away. + +stream_pool_main_loop :- + pool(_, _), !, + ( current_prolog_flag(windows, true) + -> dispatch_stream_pool(1) % so we can break out easily + ; dispatch_stream_pool(0) + ), + stream_pool_main_loop. +stream_pool_main_loop. + diff --git a/packages/clib/stresssocket.pl b/packages/clib/stresssocket.pl new file mode 100644 index 000000000..16ce9be7a --- /dev/null +++ b/packages/clib/stresssocket.pl @@ -0,0 +1,419 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Stress-testing sockets, message queues and threads. These elements are +the most important and complicated parts of multi-threaded servers and +require intensive testing. This program performs the following steps for +each test: + + * Create a server consisting of an accepting thread and 5 workers. + * Run the tests from test_def. + * Destroy the server + +For simple tests, get yourself a free machine and run + + ?- forever. + +It creates a logfile named -forever.txt +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +:- asserta(user:file_search_path(foreign, '.')). +:- use_module(socket). +:- use_module(library(debug)). + +:- dynamic + on_thread/2, + port/1, + worker/1. + +:- discontiguous + test_impl/1. + + /******************************* + * FOREVER * + *******************************/ + +forever :- + forever(_). + +forever(Test) :- + gethostname(Host), + atomic_list_concat([Host, -, 'forever.txt'], Log), + protocol(Log), + between(1, 10000000, N), + get_time(T), + convert_time(T, S), + format('***** TEST RUN ~w ***** [~w]~n', [N, S]), + test(Test), + fail. +forever(_). % takes very long + + /******************************* + * TOPLEVEL * + *******************************/ + +test :- + test(_). + +test(T) :- + create_server(5), + ( test_def(T, Test), + ( Test = concurrent(Times, Threads, CTest) + -> run(concurrent(Times, Threads, test_impl(CTest))) + ; run(test_impl(Test)) + ), + fail + ; true + ), + stop_server. + +test_def(s1, echo(100)). +test_def(s2, big(100000)). +test_def(s3, big(10000, 10)). +test_def(s5, timeout). +test_def(s6, nohost). +test_def(s7, noport). +test_def(c1, concurrent(10, 3, echo(100))). +test_def(c1, concurrent(10, 3, big(10000))). + + + /******************************* + * SERVER * + *******************************/ + +create_server :- + create_server(5). + +create_server(Workers) :- + thread_create(server(Workers), _, [alias(server)]), + thread_get_message(ready), + debug(tcp, 'Server started', []). + +stop_server :- + forall(worker(_), client(exit, _)), + debug(tcp, 'Workers exited, prepare to join server', []), + connect, % make accept return + thread_join(server). + +server(Workers) :- + create_pool(Workers), + tcp_socket(Socket), + tcp_bind(Socket, Port), + assert(port(Port)), + tcp_listen(Socket, 5), + debug(tcp, 'Server ready on port ~w', [Port]), + thread_send_message(main, ready), + repeat, + tcp_accept(Socket, Client, _Peer), + debug(connect, 'Connection from ~w', [_Peer]), + ( worker(_) + -> thread_send_message(queue, Client), + fail + ; !, + tcp_close_socket(Client) + ), + debug(tcp, 'All workers have gone, stopping', []), + stop_pool, + tcp_close_socket(Socket), + retract(port(Port)). + +create_pool(Number) :- + message_queue_create(queue), + forall(between(1, Number, _), + ( thread_create(work(queue), Id, []), + assert(worker(Id)) + )). + + +stop_pool :- + forall(worker(_), + thread_send_message(queue, stop)), + forall(retract(worker(Id)), + thread_join(Id)), + message_queue_destroy(queue), + debug(tcp, 'Pool stopped', []). + +work(Queue) :- + repeat, + thread_get_message(Queue, Socket), + handle(Socket, Data), + Data == exit, !. + +handle(Client, Data) :- + tcp_open_socket(Client, In, Out), + read(In, Data), +% open_null_stream(Null), +% copy_stream_data(In, Null), +% close(Null), + close(In), + thread_self(Me), + debug(data, '~p: Received ~W', [Me, Data, [max_depth(10)]]), + ( debugging(thread) + -> assert(on_thread(Me, Data)) + ; true + ), + do_work(Data, Answer), + writeq(Out, Answer), + write(Out, '.\n'), + debug(data, 'Sent ~W', [Answer, [max_depth(10)]]), + flush_output(Out), + close(Out). + +thread_join(Id) :- + thread_join(Id, Status), + ( Status == true + -> true + ; format('WRONG join-status for ~w: ~w~n', [Id, Status]) + ). + + +do_work(exit, true) :- !, + thread_self(Me), + debug(tcp, 'Exit worker ~w', [Me]), + thread_detach(Me), + retract(worker(Me)). +do_work(echo(Data), Data) :- !. +do_work(sleep(Time), true) :- !, + sleep(Time). + + + /******************************* + * CLIENT * + *******************************/ + +host(localhost). + +client(Term, Reply) :- + client(Term, Reply, 0). +client(Term, Reply, TimeOut) :- + host(Host), + port(Port), + client(Host, Port, TimeOut, Term, Reply). +client(Host, Port, Timeout, Term, Reply) :- + tcp_socket(Socket), + tcp_connect(Socket, Host:Port), + tcp_open_socket(Socket, In, Out), + send_output(Term, Out), + close(Out), + ( Timeout == 0 + -> true + ; set_stream(In, timeout(Timeout)) + ), + call_cleanup(read(In, Reply), close(In)), + debug(data, 'Reply = ~W', [Reply, [max_depth(10)]]). + +send_output(List, Out) :- + is_list(List), !, + send_list_output(List, Out). +send_output(Term, Out) :- + send_term(Term, Out). + +send_term(Term, Out) :- + writeq(Out, Term), + write(Out, '.\n'). + +send_list_output([], _). +send_list_output([H|T], Out) :- + send_term(H, Out), + send_list_output(T, Out). + +echo(Term) :- + client(echo(Term), Reply), + assertion(Term =@= Reply). + +connect :- + host(Host), + port(Port), + tcp_socket(Socket), + tcp_connect(Socket, Host:Port), + tcp_close_socket(Socket). + + + /******************************* + * TESTS * + *******************************/ + +% echo(Times) +% +% Send a lot of short messages to the server + +test_impl(echo(Times)) :- !, + forall(between(1, Times, N), + echo(N)). + +% big(Size) +% +% Send a list of 1...Size to the server + +test_impl(big(Size)) :- + findall(X, between(1, Size, X), L), + echo(L). + +% big(Size, Times) +% +% Send Times lists of 1...Size to the server + +test_impl(big(Size, Times)) :- + findall(X, between(1, Size, X), L), + forall(between(1, Times, _), + echo(L)). + +test_impl(timeout) :- + catch(client(sleep(2), _Reply, 1), E, true), + assertion(E = error(timeout_error(read, '$stream'(_)), _G285)). + + + /******************************* + * RUN * + *******************************/ + +:- meta_predicate + run(:). + +run(Goal) :- + debug(run, ' ** Run ~p ...', [Goal]), + call_cleanup(Goal, E, cleanup(Goal, E)). + +cleanup(Goal, E) :- + debug(run, ' ** Finished ~p: ~p', [Goal, E]). + + + /******************************* + * SPECIAL TESTS * + *******************************/ + +test_impl(nohost) :- + tcp_socket(S), + catch(tcp_connect(S, 'foo.bar':80), E, true), + tcp_close_socket(S), + assertion(E =@= error(socket_error('Host not found'), _)). + +test_impl(noport) :- + tcp_socket(S), + catch(call_with_time_limit(5, tcp_connect(S, localhost:4321)), + E, true), + tcp_close_socket(S), + assertion(E = error(socket_error(_), _)). + + + /******************************* + * DISTRIBUTION * + *******************************/ + +on_threads :- + ( bagof(D, on_thread(Id, D), Ds), + length(Ds, L), + format('Thread ~w handled ~w~n', [Id, L]), + fail + ; true + ). + +clean :- + retractall(on_thread(_, _)). + + + /******************************* + * CONCUR * + *******************************/ + +:- meta_predicate + concurrent(+, +, :), + ok(:). + +% concurrent(+Times, +Threads, :Goal) +% +% Run Goal Times times concurrent in Threads + +concurrent(Times, 1, Goal) :- !, + forall(between(1, Times, _), + ok(Goal)). +concurrent(Times, Threads, Goal) :- + strip_module(Goal, M, G), + message_queue_create(Done), + message_queue_create(Queue), + create_workers(Threads, M, Queue, Done), + forall(between(1, Times, _), + thread_send_message(Queue, goal(G))), + debug(concurrent, 'Waiting for ~w replies', [Times]), + wait_n(Times, Done), + forall(between(1, Threads, _), + thread_send_message(Queue, done)), + debug(concurrent, 'Waiting for ~w threads', [Threads]), + wait_n(Threads, Done), + message_queue_destroy(Queue), + message_queue_destroy(Done), + debug(concurrent, 'All done', []). + +wait_n(0, _) :- !. +wait_n(N, Queue) :- + thread_get_message(Queue, done), + N2 is N - 1, + wait_n(N2, Queue). + +create_workers(N, Module, Queue, Done) :- + N > 0, !, + thread_create(worker(Module, Queue, Done), + _, + [ detached(true) + ]), + N2 is N - 1, + create_workers(N2, Module, Queue, Done). +create_workers(_, _, _, _). + + +worker(Module, Queue, Done) :- + thread_get_message(Queue, Message), + ( Message = goal(Goal) + -> ok(Module:Goal), + thread_send_message(Done, done), + worker(Module, Queue, Done) + ; thread_send_message(Done, done) + ). + +ok(Goal) :- + ( catch(Goal, E, true) + -> ( var(E) + -> true + ; print_message(error, E) + ) + ; print_message(warning, failed(Goal)) + ). + + /******************************* + * DEBUG * + *******************************/ + +%:- interactor. +:- debug(tcp). +%:- debug(data). +:- debug(run). +:- debug(concurrent). diff --git a/packages/clib/test.pl b/packages/clib/test.pl new file mode 100644 index 000000000..71f26f152 --- /dev/null +++ b/packages/clib/test.pl @@ -0,0 +1,186 @@ +:- module(test_nlp, + [ run_tests/0, + run_tests/1 + ]). + +:- asserta(user:file_search_path(foreign, '.')). +:- asserta(user:file_search_path(library, '.')). +:- asserta(user:file_search_path(library, '../plunit')). + +:- use_module(library(plunit)). +:- use_module(library(crypt)). +:- use_module(library(sha)). + +:- begin_tests(crypt). + +test(default, []) :- + Passwd = "My password", + crypt(Passwd, E), + ground(E), + crypt(Passwd, E). +test(md5, []) :- + Passwd = "My password", + append("$1$", _, E), + crypt(Passwd, E), + ground(E), + crypt(Passwd, E). + +:- end_tests(crypt). + + +:- begin_tests(sha). + +test(sha1, [true(Hash=[136, 67, 215, 249, 36, 22, 33, 29, + 233, 235, 185, 99, 255, 76, 226, + 129, 37, 147, 40, 120])]) :- + sha_hash(foobar, Hash, []). +test(sha1, [true(Hash=[136, 67, 215, 249, 36, 22, 33, 29, + 233, 235, 185, 99, 255, 76, 226, + 129, 37, 147, 40, 120])]) :- + sha_hash(foobar, Hash, [algorithm(sha1)]). +test(sha256, [true(Hash=[195, 171, 143, 241, 55, 32, 232, 173, + 144, 71, 221, 57, 70, 107, 60, 137, + 116, 229, 146, 194, 250, 56, 61, 74, + 57, 96, 113, 76, 174, 240, 196, 242])]) :- + sha_hash(foobar, Hash, [algorithm(sha256)]). +test(hmac, [true(Hash=[16, 65, 82, 197, 191, 220, 160, 123, + 198, 51, 238, 189, 70, 25, 159, 2, + 85, 201, 244, 157])]) :- + hmac_sha(key, data, Hash, [algorithm(sha1)]). +test(hmac, [true(Hash=[80, 49, 254, 61, 152, 156, 109, 21, + 55, 160, 19, 250, 110, 115, 157, 162, + 52, 99, 253, 174, 195, 183, 1, 55, 216, + 40, 227, 106, 206, 34, 27, 208])]) :- + hmac_sha(key, data, Hash, [algorithm(sha256)]). + +:- end_tests(sha). + + +:- begin_tests(wiki_sha). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Test-cases from http://en.wikipedia.org/wiki/SHA-1 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +%% hash_to_atom(+Hash, -Atom) +% +% Translates a hash into representation used in Wikipedia page on +% SHA-1 hashes. + +hash_to_atom(Hash, Atom) :- + phrase(hash_to_ascii(Hash), Codes), + atom_codes(Atom, Codes). + +hash_to_ascii([]) --> + []. +hash_to_ascii([B1,B2,B3,B4|T]) --> + hex_byte(B1), + hex_byte(B2), + hex_byte(B3), + hex_byte(B4), + ( { T == [] } + -> [] + ; " ", + hash_to_ascii(T) + ). + +hex_byte(Byte) --> + { High is (Byte>>4) /\ 0xf, + Low is Byte /\ 0xf + }, + hex(High), + hex(Low). + +hex(Digit) --> + { code_type(Code, xdigit(Digit)) + }, + [Code]. + +test(sha1, [true(Atom='2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12')]) :- + sha_hash("The quick brown fox jumps over the lazy dog", Hash, [algorithm(sha1)]), + hash_to_atom(Hash, Atom). +test(sha1, [true(Atom='da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709')]) :- + sha_hash('', Hash, [algorithm(sha1)]), + hash_to_atom(Hash, Atom). +test(sha256, [true(Atom='d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592')]) :- + sha_hash("The quick brown fox jumps over the lazy dog", Hash, [algorithm(sha256)]), + hash_to_atom(Hash, Atom). +test(sha256, [true(Atom='e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855')]) :- + sha_hash('', Hash, [algorithm(sha256)]), + hash_to_atom(Hash, Atom). +test(sha512, [true(Atom='07e547d9 586f6a73 f73fbac0 435ed769 51218fb7 d0c8d788 a309d785 436bbb64 \ + 2e93a252 a954f239 12547d1e 8a3b5ed6 e1bfd709 7821233f a0538f3d b854fee6')]) :- + sha_hash("The quick brown fox jumps over the lazy dog", Hash, [algorithm(sha512)]), + hash_to_atom(Hash, Atom). +test(sha512, [true(Atom='cf83e135 7eefb8bd f1542850 d66d8007 d620e405 0b5715dc 83f4a921 d36ce9ce \ + 47d0d13c 5d85f2b0 ff8318d2 877eec2f 63b931bd 47417a81 a538327a f927da3e')]) :- + sha_hash('', Hash, [algorithm(sha512)]), + hash_to_atom(Hash, Atom). + +:- end_tests(wiki_sha). + + +:- begin_tests(rfc2202, [condition(current_prolog_flag(bounded, false))]). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +HMAC SHA-1 from http://www.ipa.go.jp/security/rfc/RFC2202EN.html +HMAC SHA-2 from http://www.faqs.org/rfcs/rfc4231.html +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +%% btwoc(+Integer, -Bytes) is det. +%% btwoc(-Integer, +Bytes) is det. +% +% Translate between a big integer and and its representation in +% bytes. The first bit is always 0, as Integer is nonneg. + +btwoc(Int, Bytes) :- + integer(Int), !, + int_to_bytes(Int, Bytes). +btwoc(Int, Bytes) :- + is_list(Bytes), + bytes_to_int(Bytes, Int). + +int_to_bytes(Int, Bytes) :- + int_to_bytes(Int, [], Bytes). + +int_to_bytes(Int, Bytes0, [Int|Bytes0]) :- + Int < 128, !. +int_to_bytes(Int, Bytes0, Bytes) :- + Last is Int /\ 0xff, + Int1 is Int >> 8, + int_to_bytes(Int1, [Last|Bytes0], Bytes). + + +bytes_to_int([B|T], Int) :- + bytes_to_int(T, B, Int). + +bytes_to_int([], Int, Int). +bytes_to_int([B|T], Int0, Int) :- + Int1 is (Int0<<8)+B, + bytes_to_int(T, Int1, Int). + + +%% rdf_hmac(+Key:int, +Data:list(code), -Digest:int, +Alogrithm) + +rdf_hmac(Key, Data, Digest, SHA) :- + btwoc(Key, KeyCodes), + hmac_sha(KeyCodes, Data, DigestCodes, [algorithm(SHA)]), + btwoc(Digest, DigestCodes). + +test(hmac_sha1_1, [true(Digest=0xb617318655057264e28bc0b6fb378c8ef146be00)]) :- + rdf_hmac(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, + "Hi There", + Digest, + sha1). +test(hmac_sha256_1, [true(Digest=0xb0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7)]) :- + rdf_hmac(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, + "Hi There", + Digest, + sha256). +test(hmac_sha256_2, [true(Digest=0x5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843)]) :- + rdf_hmac(0x4a656665, + "what do ya want for nothing?", + Digest, + sha256). + +:- end_tests(rfc2202). diff --git a/packages/clib/test_cgi.pl b/packages/clib/test_cgi.pl new file mode 100644 index 000000000..95d7253f2 --- /dev/null +++ b/packages/clib/test_cgi.pl @@ -0,0 +1,79 @@ +/* Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2009, VU University, Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(test_cgi, [test_cgi/0]). + +:- asserta(user:file_search_path(foreign, '.')). +:- asserta(user:file_search_path(library, '.')). +:- asserta(user:file_search_path(library, '../plunit')). + +:- use_module(library(plunit)). +:- use_module(cgi). +:- use_module(uri). + +test_cgi :- + run_tests([ cgi + ]). + +trip(FormIn, FormOut) :- + uri_query_components(String, FormIn), + setenv('QUERY_STRING', String), + cgi_get_form(FormOut). + +n_list_of(0, _, []) :- !. +n_list_of(I, H, [H|T]) :- + I2 is I - 1, + n_list_of(I2, H, T). + +:- begin_tests(cgi). + +test(atom, In == Out) :- + In = [name(value)], + trip(In, Out). +test(atom, In == Out) :- + numlist(32, 126, Chars), + n_list_of(10, Chars, ListOfStrings), + append(ListOfStrings, AllChars), + atom_codes(Value, AllChars), + In = [name(Value)], + trip(In, Out). +test(unicode, In == Out) :- + numlist(32, 1100, Chars), + atom_codes(Value, Chars), + In = [name(Value)], + trip(In, Out). +test(integer, In == Out) :- + In = [age(2394395340490340)], + trip(In, Out). +test(float, In == Out) :- + In = [age(42.0)], + trip(In, Out). + +:- end_tests(cgi). + diff --git a/packages/clib/test_memfile.pl b/packages/clib/test_memfile.pl new file mode 100644 index 000000000..ec2fa779f --- /dev/null +++ b/packages/clib/test_memfile.pl @@ -0,0 +1,208 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(test_memfile, + [ test_memfile/0 + ]). +:- asserta(user:file_search_path(foreign, '.')). + +:- use_module(memfile). +:- use_module(library(utf8)). + + + /******************************* + * ACTION * + *******************************/ + +wr_atom(Atom) :- + new_memory_file(H), + open_memory_file(H, write, Out), + write(Out, Atom), + close(Out), + memory_file_to_atom(H, A2), + size_memory_file(H, Size), + atom_length(Atom, Size), + A2 == Atom. + +writemem(simple-1) :- + wr_atom('Hello World'). +writemem(wide-1) :- + atom_codes(Atom, [97,98,1080,1081]), + wr_atom(Atom). + + + /******************************* + * ACCESS ATOM * + *******************************/ + +rd_atom(Atom) :- + atom_to_memory_file(Atom, File), + open_memory_file(File, read, In), + read_to_codes(In, Codes), + close(In), + atom_codes(Atom, Codes). + + +read_to_codes(In, Codes) :- + get_code(In, C0), + read_to_codes(C0, In, Codes). + +read_to_codes(-1, _, []). +read_to_codes(C0, In, [C0|T]) :- + get_code(In, C1), + read_to_codes(C1, In, T). + +mematom(simple-1) :- + rd_atom('Hello World'). +mematom(wide-1) :- + atom_codes(Atom, [97,98,1080,1081]), + rd_atom(Atom). + + + /******************************* + * POSITION * + *******************************/ + +position(pos-1) :- + new_memory_file(MF), + open_memory_file(MF, write, Out), + format(Out, '~s', [[97, 254, 500]]), + close(Out), + size_memory_file(MF, CodeSize), + open_memory_file(MF, read, In), + get_code(In, _), + get_code(In, _), + utf8_position_memory_file(MF, Here, Size), + CodeSize == 3, % size in characters + Here == 3, + Size == 5. + + + /******************************* + * ENCODING * + *******************************/ + +encoding(enc-1) :- % Encode to UTF-8 + String = [97, 254, 500], + new_memory_file(MF), + open_memory_file(MF, write, Out, [encoding(utf8)]), + format(Out, '~s', [String]), + close(Out), + open_memory_file(MF, read, In, [encoding(octet)]), + read_stream_to_codes(In, Codes), + close(In), + free_memory_file(MF), + phrase(utf8_codes(String), Codes). + + + /******************************* + * TEST MAIN-LOOP * + *******************************/ + +testset(writemem). +testset(mematom). +testset(position). +testset(encoding). + +:- dynamic + failed/1, + blocked/2. + +test_memfile :- + retractall(failed(_)), + retractall(blocked(_,_)), + forall(testset(Set), runtest(Set)), + report_blocked, + report_failed. + +report_blocked :- + findall(Head-Reason, blocked(Head, Reason), L), + ( L \== [] + -> format('~nThe following tests are blocked:~n', []), + ( member(Head-Reason, L), + format(' ~p~t~40|~w~n', [Head, Reason]), + fail + ; true + ) + ; true + ). +report_failed :- + findall(X, failed(X), L), + length(L, Len), + ( Len > 0 + -> format('~n*** ~w tests failed ***~n', [Len]), + fail + ; format('~nAll tests passed~n', []) + ). + +runtest(Name) :- + format('Running test set "~w" ', [Name]), + flush, + functor(Head, Name, 1), + nth_clause(Head, _N, R), + clause(Head, _, R), + ( catch(Head, Except, true) + -> ( var(Except) + -> put(.), flush + ; Except = blocked(Reason) + -> assert(blocked(Head, Reason)), + put(!), flush + ; test_failed(R, Except) + ) + ; test_failed(R, fail) + ), + fail. +runtest(_) :- + format(' done.~n'). + +test_failed(R, Except) :- + clause(ClHead, _, R), + plain_head(ClHead, Head), + functor(Head, Name, 1), + arg(1, Head, TestName), + clause_property(R, line_count(Line)), + clause_property(R, file(File)), + ( Except == failed + -> format('~N~w:~d: Test ~w(~w) failed~n', + [File, Line, Name, TestName]) + ; message_to_string(Except, Error), + format('~N~w:~d: Test ~w(~w):~n~t~8|ERROR: ~w~n', + [File, Line, Name, TestName, Error]) + ), + assert(failed(Head)). + +plain_head(_M:Head, Head) :- !. +plain_head(Head, Head). + + +blocked(Reason) :- + throw(blocked(Reason)). + diff --git a/packages/clib/test_process.pl b/packages/clib/test_process.pl new file mode 100644 index 000000000..d13b55721 --- /dev/null +++ b/packages/clib/test_process.pl @@ -0,0 +1,113 @@ +:- module(test_process, + [ test_process/0 + ]). + +:- asserta(user:file_search_path(foreign, '.')). +:- asserta(user:file_search_path(library, '.')). +:- asserta(user:file_search_path(library, '../plunit')). + +:- use_module(library(plunit)). +:- use_module(library(readutil)). +:- use_module(process). + +test_process :- + run_tests([ process_create, + process_wait + ]). + +read_process(In, Text) :- + read_stream_to_codes(In, Codes), + close(In), + atom_codes(Text, Codes). + +:- begin_tests(process_create, [sto(rational_trees)]). + +test(echo, true) :- + process_create(path(true), [], []). +test(null_input, Codes == []) :- + process_create(path(cat), [], [stdin(null), stdout(pipe(Out))]), + read_stream_to_codes(Out, Codes), + close(Out). +test(null_output, true) :- + process_create(path(sh), + ['-c', 'echo THIS IS AN ERROR'], + [stdout(null)]). +test(null_error, true) :- + process_create(path(sh), + ['-c', 'echo "THIS IS AN ERROR" 1>&2'], + [stderr(null)]). +test(read_error, X == 'error\n') :- + process_create(path(sh), + ['-c', 'echo "error" 1>&2'], + [stderr(pipe(Out))]), + read_process(Out, X). +test(echo, X == 'hello\n') :- + process_create(path(sh), + ['-c', 'echo hello'], + [ stdout(pipe(Out)) + ]), + read_process(Out, X). +test(lwr, X == 'HELLO') :- + process_create(path(tr), ['a-z', 'A-Z'], + [ stdin(pipe(In)), + stdout(pipe(Out)) + ]), + format(In, hello, []), + close(In), + read_process(Out, X). +test(cwd, [true, condition(\+current_prolog_flag(windows, true))]) :- + tmp_dir(Tmp), + process_create(path(pwd), [], + [ stdout(pipe(Out)), + cwd(Tmp) + ]), + read_process(Out, CWD0), + normalize_space(atom(CWD), CWD0), + same_file(CWD, Tmp). +test(cwd, [true, condition(current_prolog_flag(windows, true))]) :- + tmp_dir(Tmp), + getenv('COMSPEC', Shell), + process_create(Shell, ['/c', cd], + [ stdout(pipe(Out)), + cwd(Tmp) + ]), + read_process(Out, CWD0), + normalize_space(atom(CWD), CWD0), + same_file(CWD, Tmp). + +tmp_dir(Dir) :- + getenv('TEMP', Dir), !. +tmp_dir('/tmp'). + +:- end_tests(process_create). + + +:- begin_tests(process_wait, [sto(rational_trees)]). + +test(wait_ok, X == exit(0)) :- + process_create(path(sh), ['-c', 'exit 0'], [process(PID)]), + process_wait(PID, X). +test(wait_ok, X == exit(42)) :- + process_create(path(sh), ['-c', 'exit 42'], [process(PID)]), + process_wait(PID, X). +test(kill_ok, [ X == killed(9), + condition(\+current_prolog_flag(windows, true))]) :- + process_create(path(sleep), [2], [process(PID)]), + process_kill(PID, 9), + process_wait(PID, X). +test(kill_ok, [ X = exit(_), + condition(current_prolog_flag(windows, true))]) :- + process_create(path(sleep), [2], [process(PID)]), + process_kill(PID, 9), + process_wait(PID, X). +test(wait_timeout, [ X = timeout ]) :- + process_create(path(sleep), [2], [process(PID)]), + ( current_prolog_flag(windows, true) + -> TMO = 0.1 + ; TMO = 0 + ), + process_wait(PID, X, [timeout(TMO)]), + process_kill(PID, 9), + process_wait(PID, _). + +:- end_tests(process_wait). diff --git a/packages/clib/test_readutil.pl b/packages/clib/test_readutil.pl new file mode 100644 index 000000000..d9ef97a23 --- /dev/null +++ b/packages/clib/test_readutil.pl @@ -0,0 +1,52 @@ +/* Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2008, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(test_readutil, + [ test_readutil/0 + ]). + +:- asserta(user:file_search_path(foreign, '.')). +:- asserta(user:file_search_path(library, '.')). +:- asserta(user:file_search_path(library, '../plunit')). + +:- use_module(library(plunit)). +:- use_module(library(readutil)). + +test_readutil :- + run_tests([ read_line_to_codes + ]). + +:- begin_tests(read_line_to_codes). + +test(eof, [condition(access_file('/dev/null', read)), X == end_of_file]) :- + open('/dev/null', read, In), + call_cleanup(read_line_to_codes(In, X), close(In)). + +:- end_tests(read_line_to_codes). + diff --git a/packages/clib/test_socket.pl b/packages/clib/test_socket.pl new file mode 100644 index 000000000..33613d76d --- /dev/null +++ b/packages/clib/test_socket.pl @@ -0,0 +1,300 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(test_socket, + [ test_socket/0, + server/1, % +Port + client/1 % +Address + ]). + +%:- asserta(user:file_search_path(foreign, '.')). + +:- use_module(library(socket)). +%:- use_module(user:socket). % debugging +:- use_module(streampool). +:- use_module(library(debug)). + +test_socket :- + test_udp, + test_tcp. + +test_tcp :- + make_server(Port, Socket), + thread_create(run_server(Socket), Server, []), + client(localhost:Port), + thread_join(Server, Status), + ( Status == true + -> true + ; format(user_error, 'Server exit-status: ~w~n', [Status]), + fail + ). + + + /******************************* + * SERVER * + *******************************/ + +server(Port) :- + make_server(Port, Socket), + run_server(Socket). + +run_server(Socket) :- + writeln(before_main), + tcp_open_socket(Socket, In, _Out), + add_stream_to_pool(In, accept(Socket)), + stream_pool_main_loop. + +make_server(Port, Socket) :- + tcp_socket(Socket), + tcp_bind(Socket, Port), + tcp_listen(Socket, 5). + +accept(Socket) :- + tcp_accept(Socket, Slave, Peer), + debug(connection, 'connect(~p)', [Peer]), + tcp_open_socket(Slave, In, Out), + add_stream_to_pool(In, client(In, Out, Peer)). + +client(In, Out, Peer) :- + read(In, Term), + ( Term == end_of_file + -> debug(connection, 'close(~p)', [Peer]), + close(In), + close(Out) + ; ( catch(action(Term, In, Out), E, true) + -> ( var(E) + -> true + ; tcp_send(Out, exception(E)) + ) + ; tcp_send(Out, no) + ) + ). + + /******************************* + * ACTION * + *******************************/ + +action(echo(X), _In, Out) :- + tcp_send(Out, X). +action(wait(X), _In, Out) :- + sleep(X), + tcp_send(Out, yes). +action(slow_read, In, Out) :- + sleep(2), + read(In, Term), + tcp_send(Out, Term). +action(quit, _In, Out) :- + close_stream_pool, + tcp_send(Out, quitted). + + + /******************************* + * CLIENT SIDE * + *******************************/ + +:- dynamic + client/2. + +client(Address) :- + tcp_socket(S), + tcp_connect(S, Address), + tcp_open_socket(S, In, Out), + asserta(client(In, Out)), + test, + retract(client(In, Out)), + close(Out), + close(In). + +echo(echo-1) :- + X = 'Hello World', + client(In, Out), + tcp_send(Out, echo(X)), + tcp_reply(In, X). +echo(echo-2) :- + findall(A, between(0, 100000, A), X), + client(In, Out), + tcp_send(Out, echo(X)), + tcp_reply(In, X). + +slow(slow-1) :- + client(In, Out), + tcp_send(Out, wait(2)), + tcp_reply(In, yes). +slow(slow-1) :- + client(In, Out), + tcp_send(Out, slow_read), + findall(A, between(0, 100000, A), X), + tcp_send(Out, X), + tcp_reply(In, X). + +quit(quit-1) :- + client(In, Out), + tcp_send(Out, quit), + tcp_reply(In, quitted). + + + /******************************* + * UTIL * + *******************************/ + +tcp_send(Out, Term) :- + format(Out, '~q.~n', [Term]), + flush_output(Out). + +tcp_reply(In, Reply) :- + read(In, Term), + reply(Term, In, Reply). + +reply(exception(E), _, _) :- + throw(E). +reply(T, _, T). + + /******************************* + * UDP * + *******************************/ + +receive_loop(Socket, Queue) :- + repeat, + udp_receive(Socket, Data, From, [as(atom)]), + thread_send_message(Queue, got(Data, From)), + writeln(before_main:Data:done), + Data == quit, !, + tcp_close_socket(Socket). + +receiver(Port, ThreadId) :- + thread_self(Me), + udp_socket(S), + tcp_bind(S, Port), + thread_create(receive_loop(S, Me), ThreadId, []). + +test_udp :- + format(user_error, 'Running test set "udp"', []), + ( catch(run_udp, E, true) + -> ( var(E) + -> format(user_error, ' . done~n', []) + ; print_message(error, E) + ) + ; format(user_error, 'FAILED~n', []) + ). + +run_udp :- + receiver(Port, ThreadId), + udp_socket(S), + udp_send(S, 'hello world', localhost:Port, []), + thread_get_message(got(X, _)), + udp_send(S, 'quit', localhost:Port, []), + thread_get_message(got(Q, _)), + thread_join(ThreadId, Exit), + writeln(done), + tcp_close_socket(S), + assertion(X=='hello world'), + assertion(Q=='quit'), + assertion(Exit==true), !. + + + /******************************* + * TEST MAIN-LOOP * + *******************************/ + +testset(echo). +testset(slow). +testset(quit). + +:- dynamic + failed/1, + blocked/2. + +test :- + retractall(failed(_)), + retractall(blocked(_,_)), + forall(testset(Set), runtest(Set)), + report_blocked, + report_failed. + +report_blocked :- + findall(Head-Reason, blocked(Head, Reason), L), + ( L \== [] + -> format('~nThe following tests are blocked:~n', []), + ( member(Head-Reason, L), + format(' ~p~t~40|~w~n', [Head, Reason]), + fail + ; true + ) + ; true + ). +report_failed :- + findall(X, failed(X), L), + length(L, Len), + ( Len > 0 + -> format('~n*** ~w tests failed ***~n', [Len]), + fail + ; format('~nAll tests passed~n', []) + ). + +runtest(Name) :- + format('Running test set "~w" ', [Name]), + flush, + functor(Head, Name, 1), + nth_clause(Head, _N, R), + clause(Head, _, R), + ( catch(Head, Except, true) + -> ( var(Except) + -> put(.), flush + ; Except = blocked(Reason) + -> assert(blocked(Head, Reason)), + put(!), flush + ; test_failed(R, Except) + ) + ; test_failed(R, fail) + ), + fail. +runtest(_) :- + format(' done.~n'). + +test_failed(R, Except) :- + clause(Head, _, R), + functor(Head, Name, 1), + arg(1, Head, TestName), + clause_property(R, line_count(Line)), + clause_property(R, file(File)), + ( Except == failed + -> format('~N~w:~d: Test ~w(~w) failed~n', + [File, Line, Name, TestName]) + ; message_to_string(Except, Error), + format('~N~w:~d: Test ~w(~w):~n~t~8|ERROR: ~w~n', + [File, Line, Name, TestName, Error]) + ), + assert(failed(Head)). + +blocked(Reason) :- + throw(blocked(Reason)). + + diff --git a/packages/clib/test_socket.pl~ b/packages/clib/test_socket.pl~ new file mode 100644 index 000000000..4d9396557 --- /dev/null +++ b/packages/clib/test_socket.pl~ @@ -0,0 +1,297 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(test_socket, + [ test_socket/0, + server/1, % +Port + client/1 % +Address + ]). + +%:- asserta(user:file_search_path(foreign, '.')). + +:- use_module(library(socket)). +%:- use_module(user:socket). % debugging +:- use_module(streampool). +:- use_module(library(debug)). + +test_socket :- + test_udp, + test_tcp. + +test_tcp :- + make_server(Port, Socket), + thread_create(run_server(Socket), Server, []), + client(localhost:Port), + thread_join(Server, Status), + ( Status == true + -> true + ; format(user_error, 'Server exit-status: ~w~n', [Status]), + fail + ). + + + /******************************* + * SERVER * + *******************************/ + +server(Port) :- + make_server(Port, Socket), + run_server(Socket). + +run_server(Socket) :- + tcp_open_socket(Socket, In, _Out), + add_stream_to_pool(In, accept(Socket)), + stream_pool_main_loop. + +make_server(Port, Socket) :- + tcp_socket(Socket), + tcp_bind(Socket, Port), + tcp_listen(Socket, 5). + +accept(Socket) :- + tcp_accept(Socket, Slave, Peer), + debug(connection, 'connect(~p)', [Peer]), + tcp_open_socket(Slave, In, Out), + add_stream_to_pool(In, client(In, Out, Peer)). + +client(In, Out, Peer) :- + read(In, Term), + ( Term == end_of_file + -> debug(connection, 'close(~p)', [Peer]), + close(In), + close(Out) + ; ( catch(action(Term, In, Out), E, true) + -> ( var(E) + -> true + ; tcp_send(Out, exception(E)) + ) + ; tcp_send(Out, no) + ) + ). + + /******************************* + * ACTION * + *******************************/ + +action(echo(X), _In, Out) :- + tcp_send(Out, X). +action(wait(X), _In, Out) :- + sleep(X), + tcp_send(Out, yes). +action(slow_read, In, Out) :- + sleep(2), + read(In, Term), + tcp_send(Out, Term). +action(quit, _In, Out) :- + close_stream_pool, + tcp_send(Out, quitted). + + + /******************************* + * CLIENT SIDE * + *******************************/ + +:- dynamic + client/2. + +client(Address) :- + tcp_socket(S), + tcp_connect(S, Address), + tcp_open_socket(S, In, Out), + asserta(client(In, Out)), + test, + retract(client(In, Out)), + close(Out), + close(In). + +echo(echo-1) :- + X = 'Hello World', + client(In, Out), + tcp_send(Out, echo(X)), + tcp_reply(In, X). +echo(echo-2) :- + findall(A, between(0, 100000, A), X), + client(In, Out), + tcp_send(Out, echo(X)), + tcp_reply(In, X). + +slow(slow-1) :- + client(In, Out), + tcp_send(Out, wait(2)), + tcp_reply(In, yes). +slow(slow-1) :- + client(In, Out), + tcp_send(Out, slow_read), + findall(A, between(0, 100000, A), X), + tcp_send(Out, X), + tcp_reply(In, X). + +quit(quit-1) :- + client(In, Out), + tcp_send(Out, quit), + tcp_reply(In, quitted). + + + /******************************* + * UTIL * + *******************************/ + +tcp_send(Out, Term) :- + format(Out, '~q.~n', [Term]), + flush_output(Out). + +tcp_reply(In, Reply) :- + read(In, Term), + reply(Term, In, Reply). + +reply(exception(E), _, _) :- + throw(E). +reply(T, _, T). + + /******************************* + * UDP * + *******************************/ + +receive_loop(Socket, Queue) :- + repeat, + udp_receive(Socket, Data, From, [as(atom)]), + thread_send_message(Queue, got(Data, From)), + Data == quit, !, + tcp_close_socket(Socket). + +receiver(Port, ThreadId) :- + thread_self(Me), + udp_socket(S), + tcp_bind(S, Port), + thread_create(receive_loop(S, Me), ThreadId, []). + +test_udp :- + format(user_error, 'Running test set "udp"', []), + ( catch(run_udp, E, true) + -> ( var(E) + -> format(user_error, ' . done~n', []) + ; print_message(error, E) + ) + ; format(user_error, 'FAILED~n', []) + ). + +run_udp :- + receiver(Port, ThreadId), + udp_socket(S), + udp_send(S, 'hello world', localhost:Port, []), + thread_get_message(got(X, _)), + udp_send(S, 'quit', localhost:Port, []), + thread_get_message(got(Q, _)), + thread_join(ThreadId, Exit), + tcp_close_socket(S), + assertion(X=='hello world'), + assertion(Q=='quit'), + assertion(Exit==true), !. + + + /******************************* + * TEST MAIN-LOOP * + *******************************/ + +testset(echo). +testset(slow). +testset(quit). + +:- dynamic + failed/1, + blocked/2. + +test :- + retractall(failed(_)), + retractall(blocked(_,_)), + forall(testset(Set), runtest(Set)), + report_blocked, + report_failed. + +report_blocked :- + findall(Head-Reason, blocked(Head, Reason), L), + ( L \== [] + -> format('~nThe following tests are blocked:~n', []), + ( member(Head-Reason, L), + format(' ~p~t~40|~w~n', [Head, Reason]), + fail + ; true + ) + ; true + ). +report_failed :- + findall(X, failed(X), L), + length(L, Len), + ( Len > 0 + -> format('~n*** ~w tests failed ***~n', [Len]), + fail + ; format('~nAll tests passed~n', []) + ). + +runtest(Name) :- + format('Running test set "~w" ', [Name]), + flush, + functor(Head, Name, 1), + nth_clause(Head, _N, R), + clause(Head, _, R), + ( catch(Head, Except, true) + -> ( var(Except) + -> put(.), flush + ; Except = blocked(Reason) + -> assert(blocked(Head, Reason)), + put(!), flush + ; test_failed(R, Except) + ) + ; test_failed(R, fail) + ), + fail. +runtest(_) :- + format(' done.~n'). + +test_failed(R, Except) :- + clause(Head, _, R), + functor(Head, Name, 1), + arg(1, Head, TestName), + clause_property(R, line_count(Line)), + clause_property(R, file(File)), + ( Except == failed + -> format('~N~w:~d: Test ~w(~w) failed~n', + [File, Line, Name, TestName]) + ; message_to_string(Except, Error), + format('~N~w:~d: Test ~w(~w):~n~t~8|ERROR: ~w~n', + [File, Line, Name, TestName, Error]) + ), + assert(failed(Head)). + +blocked(Reason) :- + throw(blocked(Reason)). + + diff --git a/packages/clib/test_time.pl b/packages/clib/test_time.pl new file mode 100644 index 000000000..af084275d --- /dev/null +++ b/packages/clib/test_time.pl @@ -0,0 +1,121 @@ +:- module(test_time, + [ test_time/0, + list_alarms/0 + ]). + +:- use_module(library(debug)). +:- use_module(library(plunit)). + +:- asserta(file_search_path(foreign, '.')). +:- [time]. + +dbg :- + time:time_debug(1). + +test_time :- + run_tests([ time + ]). + +:- begin_tests(time). + +test(bg) :- + bg(4). +test(flood) :- + flood_test. + +:- end_tests(time). + + + /******************************* + * MULTI-THREAD TIMEOUT * + *******************************/ + +bg(N) :- + findall(Id, (between(1, N, _), + thread_create(t(100, 0.05), Id, [])), + IDS), + join_all(IDS). + +join_all([]). +join_all([H|T]) :- + thread_join(H, Status), + assertion(Status == true), + join_all(T). + + +t(N, Time) :- + thread_create(worker, Worker, []), + t(N, Time, Worker), + thread_send_message(Worker, done), + thread_join(Worker, Status), + assertion(Status == true). + +t(0, _, _) :- !. +t(N, Time, Worker) :- + thread_self(Me), + thread_send_message(Worker, work(Time, Me)), + thread_get_message(done(E)), + assertion(E == time_limit_exceeded), + N2 is N - 1, + t(N2, Time, Worker). + +worker :- + thread_get_message(Msg), + ( Msg = work(N, Sender) + -> thread_self(Me), + debug(work, '[~w] Start working ~w sec', [Me, N]), + r(N, E), + thread_send_message(Sender, done(E)), + worker + ; true + ). + +r(N, E) :- + catch(call_with_time_limit(N, (repeat, fail)), + E, true). + +w(N) :- + alarm(N, writeln(hello), Id), + writeln(Id). + + + /******************************* + * FLOODING * + *******************************/ + +:- dynamic + x/1. + +flood_test :- + retractall(x(_)), + forall(between(1, 100, X), + alarm(1, got(X), _, + [ remove(true) + ])), + get_time(Now), + repeat, + get_time(End), + End - Now > 2, !, + ( forall(between(1, 100, X), x(X)) + -> retractall(x(_)) + ; forall(between(1, 100, X), + ( x(X) + -> true + ; format('Failed: ~D~n', [X]) + )) + ). + +got(X) :- + assert(x(X)). + + + /******************************* + * DEBUG * + *******************************/ + +list_alarms :- + ( current_alarm(At, Callable, Id, Status), + format('~p ~p ~p ~p~n', [At, Callable, Id, Status]), + fail + ; true + ). diff --git a/packages/clib/test_uri.pl b/packages/clib/test_uri.pl new file mode 100644 index 000000000..76bfcd45f --- /dev/null +++ b/packages/clib/test_uri.pl @@ -0,0 +1,129 @@ +:- module(test_uri, + [ test_uri/0 + ]). + +:- asserta(user:file_search_path(library, '../plunit')). +:- asserta(user:file_search_path(library, '.')). +:- asserta(user:file_search_path(foreign, '.')). + +:- use_module(library(uri)). +:- use_module(library(debug)). +:- use_module(library(plunit)). + +test_uri :- + run_tests([ uri, + iri, + uri_authority, + uri_query, + uri_encode + ]). + +trip_uri_iri(IRI, X) :- + uri_iri(URI, IRI), + uri_iri(URI, X). + +resolve(In, Out) :- + uri_resolve(In, 'http://a/b/c/d;p?q', Out). + +:- begin_tests(uri). + +test(unicode_trip, X == IRI) :- + IRI = 'http://a.b/\u041a', + trip_uri_iri(IRI, X). +test(unicode_uri, IRI == URI) :- + URI = 'http://a.b/\u041a', + uri_iri(URI, IRI). +test(latin_uri, IRI == URI) :- + URI = 'http://a.b/\u00a8', + uri_iri(URI, IRI). + +test(resolve, URI == 'g:h') :- resolve('g:h', URI). +test(resolve, URI == 'http://a/b/c/g') :- resolve('g', URI). +test(resolve, URI == 'http://a/b/c/g') :- resolve('./g', URI). +test(resolve, URI == 'http://a/b/c/g/') :- resolve('g/', URI). +test(resolve, URI == 'http://a/g') :- resolve('/g', URI). +test(resolve, URI == 'http://g') :- resolve('//g', URI). +test(resolve, URI == 'http://a/b/c/d;p?y') :- resolve('?y', URI). +test(resolve, URI == 'http://a/b/c/g?y') :- resolve('g?y', URI). +test(resolve, URI == 'http://a/b/c/d;p?q#s') :- resolve('#s', URI). +test(resolve, URI == 'http://a/b/c/g#s') :- resolve('g#s', URI). +test(resolve, URI == 'http://a/b/c/g?y#s') :- resolve('g?y#s', URI). +test(resolve, URI == 'http://a/b/c/;x') :- resolve(';x', URI). +test(resolve, URI == 'http://a/b/c/g;x') :- resolve('g;x', URI). +test(resolve, URI == 'http://a/b/c/g;x?y#s') :- resolve('g;x?y#s', URI). +test(resolve, URI == 'http://a/b/c/d;p?q') :- resolve('', URI). +test(resolve, URI == 'http://a/b/c/') :- resolve('.', URI). +test(resolve, URI == 'http://a/b/c/') :- resolve('./', URI). +test(resolve, URI == 'http://a/b/') :- resolve('..', URI). +test(resolve, URI == 'http://a/b/') :- resolve('../', URI). +test(resolve, URI == 'http://a/b/g') :- resolve('../g', URI). +test(resolve, URI == 'http://a/') :- resolve('../..', URI). +test(resolve, URI == 'http://a/') :- resolve('../../', URI). +test(resolve, URI == 'http://a/g') :- resolve('../../g', URI). + +:- end_tests(uri). + +:- begin_tests(iri). + +test(normalise_uri, NormalURI == 'example://a/b/c/%7Bfoo%7D') :- + uri_normalized('eXAMPLE://a/./b/../b/%63/%7bfoo%7d', NormalURI). +test(normalise_iri, NormalIRI == 'example://a/b/c/%7Bfoo%7D') :- + uri_normalized_iri('eXAMPLE://a/./b/../b/%63/%7bfoo%7d', NormalIRI). +test(normalise_iri, NormalIRI == 'http://a.b/a%3F?x') :- % 3F = '?' + uri_normalized_iri('http://a.b/a%3f?x', NormalIRI). + +:- end_tests(iri). + +:- begin_tests(uri_query). + +test(break, Q == [a=b,c=d]) :- + uri_query_components('a=b&c=d', Q). +test(construct, QS == 'a=b&c=d') :- + uri_query_components(QS, [a=b,c=d]). +test(encode, Q == [name=Value]) :- + numlist(1, 1050, VL), + atom_codes(Value, VL), + uri_query_components(QS, [name=Value]), + uri_query_components(QS, Q). + +:- end_tests(uri_query). + +:- begin_tests(uri_authority). + +test(break, [User,Host,Port] == [jan,'swi-prolog.org', 3040]) :- + uri_authority_components('jan@swi-prolog.org:3040', C), + uri_authority_data(user, C, User), + uri_authority_data(host, C, Host), + uri_authority_data(port, C, Port). +test(break, [User,Pwd,Host,Port] == [jan,xxx,'swi-prolog.org', 3040]) :- + uri_authority_components('jan:xxx@swi-prolog.org:3040', C), + uri_authority_data(user, C, User), + uri_authority_data(password, C, Pwd), + uri_authority_data(host, C, Host), + uri_authority_data(port, C, Port). +test(construct, Auth == 'jan@swi-prolog.org:3040') :- + uri_authority_data(user, C, jan), + uri_authority_data(host, C, 'swi-prolog.org'), + uri_authority_data(port, C, 3040), + uri_authority_components(Auth, C). + +:- end_tests(uri_authority). + +:- begin_tests(uri_encode). + +test(query, X == '%3D%26') :- + uri_encoded(query_value, '=&', X). +test(query, X == 'a%2Bb') :- + uri_encoded(query_value, 'a+b', X). +test(query, X == 'a b') :- + uri_encoded(query_value, X, 'a+b'). +test(path, X == 'a+b') :- + uri_encoded(path, 'a+b', X). +test(path, X == 'a+b') :- + uri_encoded(path, X, 'a+b'). +test(path, X == '=&') :- + uri_encoded(path, '=&', X). +test(path, X == '/a%20b%3F') :- + uri_encoded(path, '/a b?', X). + +:- end_tests(uri_encode). diff --git a/packages/clib/testrlimit.pl b/packages/clib/testrlimit.pl new file mode 100644 index 000000000..d4f0dca70 --- /dev/null +++ b/packages/clib/testrlimit.pl @@ -0,0 +1,8 @@ +test :- + rlimit(cpu, _, 2), + on_signal(xcpu, _, cpu_exceeded), + ( repeat, fail ). + +cpu_exceeded(_Sig) :- + format(user_error, 'CPU time exceeded~n', []), + halt(1). diff --git a/packages/clib/time.c b/packages/clib/time.c new file mode 100644 index 000000000..758c05c5c --- /dev/null +++ b/packages/clib/time.c @@ -0,0 +1,1007 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +#define O_DEBUG 1 /* provides time:time_debug(+Level) */ +//#define O_SAFE 1 /* extra safety checks */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include +#include + +#ifdef SIGUSR2 +#define SIG_TIME SIGUSR2 +#else +#define SIG_TIME SIGALRM +#endif + +#ifdef O_SAFE +#define __USE_GNU +#endif + +#include + +typedef enum +{ TIME_ABS, + TIME_REL +} time_abs_rel; + +#ifdef __WINDOWS__ +#include +#include + +#ifndef SIGALRM +#define SIGALRM 14 +#endif + +struct timeval +{ long tv_sec; + long tv_usec; +}; + +struct timezone +{ int zone; +}; + +static int +gettimeofday(struct timeval *tv, struct timezone *tz) +{ struct timeb tb; + + ftime(&tb); + tv->tv_sec = (long)tb.time; + tv->tv_usec = tb.millitm * 1000; + + return 0; +} + + +#else /*__WINDOWS__*/ + +#include +#include + +#endif /*__WINDOWS__*/ + +#ifdef O_DEBUG +static int debuglevel = 0; +#define DEBUG(n, g) if ( debuglevel >= n ) g + +static foreign_t +pl_time_debug(term_t n) +{ return PL_get_integer(n, &debuglevel); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +glibc defines backtrace() and friends to print the calling context. For +debugging this is just great, as the problem generally appear after +generating an exception. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#ifdef HAVE_EXECINFO_H +#define BACKTRACE 1 + +#if BACKTRACE +#include +#include + +static void +print_trace (void) +{ void *array[100]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, sizeof(array)/sizeof(void *)); + strings = backtrace_symbols(array, size); + +#ifdef _REENTRANT + Sdprintf("on_alarm() Prolog-context [thread %d]:\n", PL_thread_self()); +#else + Sdprintf("on_alarm() Prolog-context:\n"); +#endif + PL_action(PL_ACTION_BACKTRACE, 3); + + Sdprintf("on_alarm() C-context:\n"); + + for(i = 0; i < size; i++) + { if ( !strstr(strings[i], "checkData") ) + Sdprintf("\t[%d] %s\n", i, strings[i]); + } + + free(strings); +} +#endif /*BACKTRACE*/ +#endif /*HAVE_EXECINFO_H*/ +#else /*O_DEBUG*/ +#define DEBUG(n, g) ((void)0) +#endif /*O_DEBUG*/ + +static void on_alarm(int sig); + +static module_t MODULE_user; +static atom_t ATOM_remove; +static atom_t ATOM_install; +static atom_t ATOM_done; +static atom_t ATOM_next; +static atom_t ATOM_scheduled; +static functor_t FUNCTOR_module2; +static functor_t FUNCTOR_alarm1; +static functor_t FUNCTOR_alarm4; +static predicate_t PREDICATE_call1; + +#define EV_MAGIC 1920299187 /* Random magic number */ + +#define EV_DONE 0x0001 /* Handled this one */ +#define EV_REMOVE 0x0002 /* Automatically remove */ +#define EV_FIRED 0x0004 /* Windows: got this one */ +#define EV_NOINSTALL 0x0008 /* Only allocate; do not install */ + +typedef struct event +{ record_t goal; /* Thing to call */ + module_t module; /* Module to call in */ + struct event *next; /* linked list for current */ + struct event *previous; /* idem */ + unsigned long flags; /* misc flags */ + long magic; /* validate magic */ + struct timeval at; /* Time to deliver */ + pthread_t thread_id; /* Thread to call in */ + int pl_thread_id; /* Prolog thread ID */ +} event, *Event; + +typedef void (*handler_t)(int); + +typedef struct +{ Event first; /* first in list */ + Event scheduled; /* The one we scheduled for */ + int stop; /* stop alarm-loop */ +} schedule; + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static int scheduler_running = FALSE; /* is scheduler running? */ +static pthread_t scheduler; /* thread id of scheduler */ + +#define LOCK() pthread_mutex_lock(&mutex) +#define UNLOCK() pthread_mutex_unlock(&mutex) + +static schedule the_schedule = {0}; /* the schedule */ +#define TheSchedule() (&the_schedule) /* current schedule */ + +int signal_function_set = FALSE; /* signal function is set */ +static handler_t signal_function; /* Current signal function */ + +static int removeEvent(Event ev); + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Allocate the event, maintaining a time-sorted list of scheduled events. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static Event +allocEvent() +{ Event ev = malloc(sizeof(*ev)); + + if ( !ev ) + { pl_error(NULL, 0, NULL, ERR_ERRNO, errno, "allocate", "memory", 0); + return NULL; + } + + memset(ev, 0, sizeof(*ev)); + ev->magic = EV_MAGIC; + + return ev; +} + + +static void +setTimeEventAbs(Event ev, double t) +{ struct timeval tv; + + gettimeofday(&tv, NULL); + tv.tv_usec = (long)((t-floor(t))*1000000); + tv.tv_sec = (long)t; + + ev->at = tv; +} + + +static void +setTimeEvent(Event ev, double t) +{ struct timeval tv; + + gettimeofday(&tv, NULL); + tv.tv_usec += (long)((t-floor(t))*1000000); + tv.tv_sec += (long)t; + if ( tv.tv_usec >= 1000000 ) + { tv.tv_usec -= 1000000; + tv.tv_sec++; + } + + ev->at = tv; +} + + + +static int +insertEvent(Event ev) +{ schedule *sched = TheSchedule(); + Event e; + + DEBUG(1, Sdprintf("insertEvent(%d.%06d)\n", ev->at.tv_sec, ev->at.tv_usec)); + + for(e = sched->first; e; e = e->next) + { struct timeval d; + + if ( e == ev ) + return ERR_PERMISSION; /* already scheduled */ + + d.tv_sec = ev->at.tv_sec - e->at.tv_sec; + d.tv_usec = ev->at.tv_usec - e->at.tv_usec; + if ( d.tv_usec < 0 ) + { d.tv_sec--; + d.tv_usec += 1000000; + } + + if ( d.tv_sec < 0 ) /* new must be before e */ + { ev->next = e; + ev->previous = e->previous; + if ( e->previous ) + { e->previous->next = ev; + } else + { assert(sched->first == e); + sched->first = ev; + } + e->previous = ev; + + return TRUE; + } else + { if ( e->next ) + continue; + + ev->previous = e; /* end of the list */ + e->next = ev; + + return TRUE; + } + } + + sched->first = ev; /* the very first one */ + return TRUE; +} + + +static void +unlinkEvent(Event ev) +{ schedule *sched = TheSchedule(); + + if ( sched->scheduled == ev ) + sched->scheduled = NULL; + + if ( ev->previous ) + ev->previous->next = ev->next; + else + sched->first = ev->next; + + if ( ev->next ) + ev->next->previous = ev->previous; +} + + +static void +freeEvent(Event ev) +{ unlinkEvent(ev); + + if ( ev->goal ) + PL_erase(ev->goal); + + ev->magic = 0; + + free(ev); +} + + +static void +cleanupHandler() +{ if ( signal_function_set ) + { signal_function_set = FALSE; + PL_signal(SIG_TIME, signal_function); + } +} + + +static void +installHandler() +{ if ( !signal_function_set ) + { signal_function = PL_signal(SIG_TIME|PL_SIGSYNC, on_alarm); + signal_function_set = TRUE; + } +} + + +static void +cleanup(int rc, void *arg) +{ Event ev; + schedule *sched = TheSchedule(); + + while( (ev=sched->first) ) + { removeEvent(ev); + } + + cleanupHandler(); + + if ( scheduler_running ) + { sched->stop = TRUE; + pthread_cond_signal(&cond); + + pthread_join(scheduler, NULL); + scheduler_running = FALSE; + } +} + + +static Event +nextEvent(schedule *sched) +{ Event ev; + + for(ev=sched->first; ev; ev = ev->next) + { if ( ev->flags & (EV_DONE|EV_FIRED) ) + continue; + + return ev; + } + + return NULL; +} + + +typedef struct +{ int *bits; + size_t size; + size_t high; +} bitvector; + +#define BITSPERINT (8*sizeof(int)) + +static int +set_bit(bitvector *v, size_t bit) +{ size_t offset = bit/BITSPERINT; + int bi = bit%BITSPERINT; + + while ( offset >= v->size ) + { size_t osize = v->size * sizeof(int); + int *newbits = realloc(v->bits, osize*2); + + if ( !newbits ) + return FALSE; + memset((char*)newbits+osize, 0, osize); + v->bits = newbits; + v->size *= 2; + } + + while ( bit > v->high ) /* TBD: zero entire ints */ + { size_t ho = v->high/BITSPERINT; + int b = v->high%BITSPERINT; + + v->bits[ho] &= ~(1<<(b-1)); + v->high++; + } + + v->bits[offset] |= 1<<(bi-1); + return TRUE; +} + + +static int +is_set(bitvector *v, size_t bit) +{ if ( bit <= v->high ) + { size_t offset = bit/BITSPERINT; + int bi = bit%BITSPERINT; + + return (v->bits[offset] & (1<<(bi-1))) != 0; + } + + return FALSE; +} + + +static void * +alarm_loop(void * closure) +{ schedule *sched = TheSchedule(); + bitvector signalled; + + signalled.size = 4; + signalled.bits = malloc(signalled.size*sizeof(int)); + signalled.high = 0; + + pthread_mutex_lock(&mutex); /* for condition variable */ + DEBUG(1, Sdprintf("Iterating alarm_loop()\n")); + + while( !sched->stop ) + { Event ev = nextEvent(sched); + struct timeval now; + + signalled.high = 0; + gettimeofday(&now, NULL); + + for(; ev; ev = ev->next) + { struct timeval left; + + left.tv_sec = ev->at.tv_sec - now.tv_sec; + left.tv_usec = ev->at.tv_usec - now.tv_usec; + if ( left.tv_usec < 0 ) + { left.tv_sec--; + left.tv_usec += 1000000; + } + + if ( left.tv_sec < 0 || + (left.tv_sec == 0 && left.tv_usec == 0) ) + { if ( !is_set(&signalled, ev->pl_thread_id) ) + { DEBUG(1, Sdprintf("Signalling (left = %ld) %d ...\n", + (long)left.tv_sec, + ev->pl_thread_id)); + set_bit(&signalled, ev->pl_thread_id); +#ifdef __WINDOWS__ + PL_thread_raise(ev->pl_thread_id, SIG_TIME); +#else + pthread_kill(ev->thread_id, SIG_TIME); +#endif + } + } else + break; + } + + if ( ev ) + { int rc; + struct timespec timeout; + timeout.tv_sec = ev->at.tv_sec; + timeout.tv_nsec = ev->at.tv_usec*1000; + + retry_timed_wait: + DEBUG(1, Sdprintf("Waiting ...\n")); + rc = pthread_cond_timedwait(&cond, &mutex, &timeout); + + switch( rc ) + { case ETIMEDOUT: + case 0: + continue; + case EINTR: + goto retry_timed_wait; + default: + Sdprintf("alarm/4: pthread_cond_timedwait(): %s\n", strerror(rc)); + assert(0); + } + } else + { int rc; + + retry_wait: + DEBUG(1, Sdprintf("No waiting events\n")); + rc = pthread_cond_wait(&cond, &mutex); + switch(rc) + { case EINTR: + goto retry_wait; + case 0: + continue; + default: + Sdprintf("alarm/4: pthread_cond_timedwait(): %s\n", strerror(rc)); + assert(0); + } + } + } + + return NULL; +} + + +static void +on_alarm(int sig) +{ Event ev; + schedule *sched = TheSchedule(); + pthread_t self = pthread_self(); + + DEBUG(1, Sdprintf("Signal received in %d\n", + PL_thread_self())); +#ifdef BACKTRACE + DEBUG(10, print_trace()); +#endif + + for(;;) + { struct timeval now; + term_t goal = 0; + module_t module = NULL; + + gettimeofday(&now, NULL); + + LOCK(); + for(ev = sched->first; ev; ev=ev->next) + { struct timeval left; + + assert(ev->magic == EV_MAGIC); + + if ( (ev->flags & (EV_DONE|EV_FIRED)) || + !pthread_equal(self, ev->thread_id) ) + continue; + + left.tv_sec = ev->at.tv_sec - now.tv_sec; + left.tv_usec = ev->at.tv_usec - now.tv_usec; + if ( left.tv_usec < 0 ) + { left.tv_sec--; + left.tv_usec += 1000000; + } + + if ( left.tv_sec < 0 || + (left.tv_sec == 0 && left.tv_usec == 0) ) + { DEBUG(1, Sdprintf("Calling event\n")); + ev->flags |= EV_DONE; + module = ev->module; + goal = PL_new_term_ref(); + PL_recorded(ev->goal, goal); + + if ( ev->flags & EV_REMOVE ) + freeEvent(ev); + break; + } + } + UNLOCK(); + + if ( goal ) + { PL_call_predicate(module, + PL_Q_PASS_EXCEPTION, + PREDICATE_call1, + goal); + } else + break; + } + + DEBUG(1, Sdprintf("Processed pending events; signalling scheduler\n")); + pthread_cond_signal(&cond); +} + + +static int +installEvent(Event ev) +{ int rc; + + ev->thread_id = pthread_self(); + ev->pl_thread_id = PL_thread_self(); + + LOCK(); + if ( !scheduler_running ) + { pthread_attr_t attr; + + TheSchedule()->stop = FALSE; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, 8192); + rc = pthread_create(&scheduler, &attr, alarm_loop, NULL); + pthread_attr_destroy(&attr); + + if ( rc != 0 ) + { UNLOCK(); + return pl_error("alarm", 4, "Failed to start schedule thread", + ERR_ERRNO, rc); + } + + DEBUG(1, Sdprintf("Started scheduler thread\n")); + scheduler_running = TRUE; + } + + rc = insertEvent(ev); + UNLOCK(); + + if ( rc ) + pthread_cond_signal(&cond); + + return rc; +} + + +static int +uninstallEvent(Event ev) +{ LOCK(); + if ( TheSchedule()->scheduled == ev ) + ev->flags |= EV_DONE; + unlinkEvent(ev); + ev->flags &= ~(EV_FIRED|EV_DONE); + UNLOCK(); + + pthread_cond_signal(&cond); + + return TRUE; +} + + +static int +removeEvent(Event ev) +{ LOCK(); + if ( TheSchedule()->scheduled == ev ) + ev->flags |= EV_DONE; + freeEvent(ev); + UNLOCK(); + + pthread_cond_signal(&cond); + + return TRUE; +} + + + /******************************* + * PROLOG CONNECTION * + *******************************/ + +int +alarm_error(term_t alarm, int err) +{ switch(err) + { case ERR_RESOURCE: + return pl_error(NULL, 0, NULL, ERR_RESOURCE, "timers"); + case ERR_PERMISSION: + return pl_error(NULL, 0, "already installed", ERR_PERMISSION, + alarm, "install", "alarm"); + default: + assert(0); + return FALSE; + } +} + + +static int +unify_timer(term_t t, Event ev) +{ if ( !PL_is_variable(t) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 0, t, "unbound"); + + return PL_unify_term(t, + PL_FUNCTOR, FUNCTOR_alarm1, + PL_POINTER, ev); +} + + +static int +get_timer(term_t t, Event *ev) +{ if ( PL_is_functor(t, FUNCTOR_alarm1) ) + { term_t a = PL_new_term_ref(); + void *p; + + _PL_get_arg(1, t, a); + if ( PL_get_pointer(a, &p) ) + { Event e = p; + + if ( e->magic == EV_MAGIC ) + { *ev = e; + return TRUE; + } else + { return pl_error("get_timer", 1, NULL, + ERR_DOMAIN, t, "alarm"); + } + } + } + + return pl_error("get_timer", 1, NULL, + ERR_ARGTYPE, 1, t, "alarm"); +} + + +static int +pl_get_bool_ex(term_t arg, int *val) +{ if ( PL_get_bool(arg, val) ) + return TRUE; + + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 0, arg, "bool"); +} + + +static foreign_t +alarm4_gen(time_abs_rel abs_rel, term_t time, term_t callable, + term_t id, term_t options) +{ Event ev; + double t; + module_t m = NULL; + unsigned long flags = 0L; + + if ( options ) + { term_t tail = PL_copy_term_ref(options); + term_t head = PL_new_term_ref(); + + while( PL_get_list(tail, head, tail) ) + { atom_t name; + int arity; + + if ( PL_get_name_arity(head, &name, &arity) ) + { if ( arity == 1 ) + { term_t arg = PL_new_term_ref(); + + _PL_get_arg(1, head, arg); + + if ( name == ATOM_remove ) + { int t = FALSE; + + if ( !pl_get_bool_ex(arg, &t) ) + return FALSE; + if ( t ) + flags |= EV_REMOVE; + } else if ( name == ATOM_install ) + { int t = TRUE; + + if ( !pl_get_bool_ex(arg, &t) ) + return FALSE; + if ( !t ) + flags |= EV_NOINSTALL; + } + } + } + } + if ( !PL_get_nil(tail) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 4, options, "list"); + } + + if ( !PL_get_float(time, &t) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + time, "number"); + + + if ( !(ev = allocEvent()) ) + return FALSE; + + if (abs_rel==TIME_REL) + setTimeEvent(ev, t); + else + setTimeEventAbs(ev,t); + + if ( !unify_timer(id, ev) ) + { freeEvent(ev); /* not linked: no need to lock */ + return FALSE; + } + + ev->flags = flags; + PL_strip_module(callable, &m, callable); + ev->module = m; + ev->goal = PL_record(callable); + + if ( !(ev->flags & EV_NOINSTALL) ) + { int rc; + + if ( (rc=installEvent(ev)) != TRUE ) + { freeEvent(ev); /* not linked: no need to lock */ + return alarm_error(id, rc); + } + } + + return TRUE; +} + + +static foreign_t +alarm4_abs(term_t time, term_t callable, term_t id, term_t options) +{ return alarm4_gen(TIME_ABS,time,callable,id,options); +} + +static foreign_t +alarm4_rel(term_t time, term_t callable, term_t id, term_t options) +{ return alarm4_gen(TIME_REL,time,callable,id,options); +} + +static foreign_t +alarm3_abs(term_t time, term_t callable, term_t id) +{ return alarm4_gen(TIME_ABS,time, callable, id, 0); +} + +static foreign_t +alarm3_rel(term_t time, term_t callable, term_t id) +{ return alarm4_gen(TIME_REL,time, callable, id, 0); +} + +static foreign_t +install_alarm(term_t alarm) +{ Event ev = NULL; + int rc; + + if ( !get_timer(alarm, &ev) ) + return FALSE; + + if ( (rc=installEvent(ev)) != TRUE ) + return alarm_error(alarm, rc); + + return TRUE; +} + + +static foreign_t +install_alarm2(term_t alarm, term_t time) +{ Event ev = NULL; + double t; + int rc; + + if ( !get_timer(alarm, &ev) ) + return FALSE; + + if ( !PL_get_float(time, &t) ) + return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, + time, "number"); + + setTimeEvent(ev, t); + if ( (rc=installEvent(ev)) != TRUE ) + return alarm_error(alarm, rc); + + return TRUE; +} + + +static foreign_t +uninstall_alarm(term_t alarm) +{ Event ev = NULL; + + if ( !get_timer(alarm, &ev) ) + return FALSE; + + return uninstallEvent(ev); +} + + +static foreign_t +remove_alarm(term_t alarm) +{ Event ev = NULL; + + if ( !get_timer(alarm, &ev) ) + return FALSE; + + return removeEvent(ev); +} + + +static foreign_t +current_alarms(term_t time, term_t goal, term_t id, term_t status, + term_t matching) +{ Event ev; + term_t next = PL_new_term_ref(); + term_t g = PL_new_term_ref(); + term_t tail = PL_copy_term_ref(matching); + term_t head = PL_new_term_ref(); + term_t av = PL_new_term_refs(4); + pthread_t self = pthread_self(); + + LOCK(); + ev = TheSchedule()->first; + + for(; ev; ev = ev->next) + { atom_t s; + double at; + fid_t fid; + + if ( !pthread_equal(self, ev->thread_id) ) + continue; + + fid = PL_open_foreign_frame(); + + if ( ev->flags & EV_DONE ) + s = ATOM_done; + else if ( ev == TheSchedule()->scheduled ) + s = ATOM_next; + else + s = ATOM_scheduled; + + if ( !PL_unify_atom(status, s) ) + goto nomatch; + + PL_recorded(ev->goal, g); + if ( !PL_unify_term(goal, + PL_FUNCTOR, FUNCTOR_module2, + PL_ATOM, PL_module_name(ev->module), + PL_TERM, g) ) + goto nomatch; + + at = (double)ev->at.tv_sec + (double)ev->at.tv_usec / 1000000.0; + if ( !PL_unify_float(time, at) ) + goto nomatch; + + if ( !unify_timer(id, ev) ) + goto nomatch; + + PL_discard_foreign_frame(fid); + + if ( !PL_put_float(av+0, at) || /* time */ + !PL_recorded(ev->goal, av+1) || /* goal */ + !PL_put_variable(av+2) || /* id */ + !unify_timer(av+2, ev) || + !PL_put_atom(av+3, s) || /* status */ + !PL_cons_functor_v(next, FUNCTOR_alarm4, av) ) + { PL_close_foreign_frame(fid); + UNLOCK(); + return FALSE; + } + + if ( PL_unify_list(tail, head, tail) && + PL_unify(head, next) ) + { continue; + } else + { PL_close_foreign_frame(fid); + UNLOCK(); + + return FALSE; + } + + nomatch: + PL_discard_foreign_frame(fid); + } + UNLOCK(); + + return PL_unify_nil(tail); +} + + +install_t +install_time() +{ MODULE_user = PL_new_module(PL_new_atom("user")); + + FUNCTOR_alarm1 = PL_new_functor(PL_new_atom("$alarm"), 1); + FUNCTOR_alarm4 = PL_new_functor(PL_new_atom("alarm"), 4); + FUNCTOR_module2 = PL_new_functor(PL_new_atom(":"), 2); + + ATOM_remove = PL_new_atom("remove"); + ATOM_install = PL_new_atom("install"); + ATOM_done = PL_new_atom("done"); + ATOM_next = PL_new_atom("next"); + ATOM_scheduled = PL_new_atom("scheduled"); + + PREDICATE_call1 = PL_predicate("call", 1, "user"); + + PL_register_foreign("alarm_at", 4, alarm4_abs, PL_FA_TRANSPARENT); + PL_register_foreign("alarm", 4, alarm4_rel, PL_FA_TRANSPARENT); + PL_register_foreign("alarm_at", 3, alarm3_abs, PL_FA_TRANSPARENT); + PL_register_foreign("alarm", 3, alarm3_rel, PL_FA_TRANSPARENT); + PL_register_foreign("remove_alarm", 1, remove_alarm, 0); + PL_register_foreign("uninstall_alarm",1, uninstall_alarm,0); + PL_register_foreign("install_alarm", 1, install_alarm, 0); + PL_register_foreign("install_alarm", 2, install_alarm2, 0); + PL_register_foreign("remove_alarm_notrace",1, remove_alarm, PL_FA_NOTRACE); + PL_register_foreign("current_alarms", 5, current_alarms, 0); +#ifdef O_DEBUG + PL_register_foreign("time_debug", 1, pl_time_debug, 0); +#endif + + installHandler(); + PL_on_halt(cleanup, NULL); +} + + +install_t +uninstall_time() +{ cleanup(0, NULL); +} diff --git a/packages/clib/time.pl b/packages/clib/time.pl new file mode 100644 index 000000000..c801b0ee2 --- /dev/null +++ b/packages/clib/time.pl @@ -0,0 +1,136 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2009, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(time, + [ alarm/3, % +Time, :Callable, -Id + alarm/4, % +Time, :Callable, -Id, +Options + alarm_at/4, % +Time, :Callable, -Id, +Options + remove_alarm/1, % +Id + install_alarm/1, % +Id + install_alarm/2, % +Id, +Time + uninstall_alarm/1, % +Id + current_alarm/4, % ?At, ?:Goal, ?Id, ?Status + call_with_time_limit/2 % +Time, :Callable + ]). +:- use_module(library(lists)). +:- set_prolog_flag(generate_debug_info, false). + +:- meta_predicate + call_with_time_limit(+, 0), + alarm(+, 0, -), + alarm(+, 0, -, +), + alarm_at(+, 0, -, +). + +%% alarm(+Time, :Callable, -Id) is det. +%% alarm(+Time, :Callable, -Id, +Options) is det. +% +% Set up an alarm to be signaled Time seconds from now. If the +% alarm expires, Callable is called asynchronously. Callable can +% be used to raise an exception using throw/1 to abort some +% execution. +% +% Options is a list of Name(Value) options. Currently defined +% options are: +% +% * remove(Bool) +% If =true= (default =false=), remove the alarm-event (as +% remove_alarm/1) after it has been fired. +% * install(Bool) +% If =false= (default =true=) do not install the alarm. +% It must be installed separately using install_alarm/1. + +%% alarm_at(+Time, :Callable, -Id, +Options) is det +% +% As alarm/4, but schedule the alarm at an absolute point in time. +% +% @see date_time_stamp/2. + +%% install_alarm(+Id) is det. +% +% Install an alarm allocated using alarm/4 with the install(false) +% option. +% +% @deprecated With the introduction of setup_call_cleanup/3, +% this predicate is probably no longer needed. + +%% remove_alarm(+Id) is det. +% +% Remove an alarm. If it has not yet been fired, it never will. + +%% current_alarm(?Time, :Goal, ?Id, ?Status) is nondet. +% +% Enumerate the alarms in the schedule. Time is the absolute time +% the event is scheduled for (see also get_time/1). Goal is the +% goal to execute, Id is the identifier and Status is the +% scheduling status. It takes the value =done= if the alarm has +% been fired, =next= if the event is the next to be executed and +% =scheduled= otherwise. + +:- use_foreign_library(foreign(time)). + +%% call_with_time_limit(+Time, :Goal) is semidet. +% +% Call Goal, while watching out for a (wall-time) limit. If this +% limit is exceeded, the exception =time_limit_exceeded= is +% raised. Goal is called as in once/1. +% +% @throws =time_limit_exceeded= + +call_with_time_limit(Time, Goal) :- + Time > 0, !, + setup_call_cleanup(alarm(Time, time_limit_exceeded(Time), + Id, [install(false)]), + run_alarm_goal(Id, Goal), + remove_alarm_notrace(Id)). +call_with_time_limit(_Time, _Goal) :- + throw(time_limit_exceeded). + +run_alarm_goal(AlarmID, Goal) :- + install_alarm(AlarmID), + Goal, !. + +time_limit_exceeded(_Time) :- + throw(time_limit_exceeded). + +current_alarm(Time, Goal, Id, Status) :- + current_alarms(Time, Goal, Id, Status, List), + member(alarm(Time, Goal, Id, Status), List). + + /******************************* + * HANDLE MESSAGES * + *******************************/ + +:- multifile + prolog:message/3. + +prolog:message(time_limit_exceeded) --> + [ 'Time limit exceeded' ]. + diff --git a/packages/clib/unix.c b/packages/clib/unix.c new file mode 100644 index 000000000..348cb4618 --- /dev/null +++ b/packages/clib/unix.c @@ -0,0 +1,384 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clib.h" +#include +#include +#include +#ifdef HAVE_ALLOCA_H +#include +#endif + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Unix process management. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static IOSTREAM * +name_to_stream(const char *name) +{ IOSTREAM *s; + term_t t = PL_new_term_ref(); + + PL_put_atom_chars(t, name); + if ( PL_get_stream_handle(t, &s) ) + return s; + + return NULL; +} + + +static void +flush_stream(const char *name) +{ IOSTREAM *s; + + if ( (s = name_to_stream(name)) ) + Sflush(s); + + PL_release_stream(s); +} + + + +static foreign_t +pl_fork(term_t a0) +{ pid_t pid; + + flush_stream("user_output"); /* general call to flush all IO? */ + + if ( (pid = fork()) < 0 ) + return PL_warning("fork/1: failed: %s", strerror(errno)); + + if ( pid > 0 ) + return PL_unify_integer(a0, pid); + else + return PL_unify_atom_chars(a0, "child"); +} + + +#define free_argv(n) \ + { int _k; \ + for( _k=1; _k <= n; _k++) \ + free(argv[_k]); \ + free(argv); \ + } + +static foreign_t +pl_exec(term_t cmd) +{ int argc; + atom_t name; + + if ( PL_get_name_arity(cmd, &name, &argc) ) + { term_t a = PL_new_term_ref(); + char **argv = malloc(sizeof(char*) * (argc + 2)); + int i; + + argv[0] = (char *)PL_atom_chars(name); + + for(i=1; i<=argc; i++) + { char *s; + + if ( PL_get_arg(i, cmd, a) && + PL_get_chars(a, &s, CVT_ALL|REP_MB|BUF_MALLOC) ) + argv[i] = s; + else + { free_argv(i-1); + return pl_error("exec", 1, NULL, ERR_ARGTYPE, i, a, "atomic"); + } + } + argv[argc+1] = NULL; + + execvp(argv[0], argv); + free_argv(argc); + return pl_error("exec", 1, NULL, ERR_ERRNO, errno, "execute", "command", cmd); + } + + return pl_error("exec", 1, NULL, ERR_ARGTYPE, 1, cmd, "compound"); +} + + +static foreign_t +pl_wait(term_t Pid, term_t Status) +{ int status; + pid_t pid = wait(&status); + + if ( pid == -1 ) + return pl_error("wait", 2, NULL, ERR_ERRNO, errno, "wait", "process", Pid); + + if ( PL_unify_integer(Pid, pid) ) + { if ( WIFEXITED(status) ) + return PL_unify_term(Status, + CompoundArg("exited", 1), + IntArg(WEXITSTATUS(status))); + if ( WIFSIGNALED(status) ) + return PL_unify_term(Status, + CompoundArg("signaled", 1), + IntArg(WTERMSIG(status))); + if ( WIFSTOPPED(status) ) + return PL_unify_term(Status, + CompoundArg("stopped", 1), + IntArg(WSTOPSIG(status))); + assert(0); + } + + return FALSE; +} + + +static foreign_t +pl_kill(term_t Pid, term_t Sig) +{ int pid; + int sig; + + if ( !PL_get_integer(Pid, &pid) ) + return pl_error("kill", 2, NULL, ERR_ARGTYPE, 1, Pid, "pid"); + if ( !PL_get_signum_ex(Sig, &sig) ) + return FALSE; + + if ( kill(pid, sig) < 0 ) + return pl_error("kill", 2, NULL, ERR_ERRNO, errno, + "kill", "process", Pid); + + return TRUE; +} + + + /******************************* + * STREAM STUFF * + *******************************/ + +static foreign_t +pl_pipe(term_t Read, term_t Write) +{ int fd[2]; + IOSTREAM *in, *out; + + if ( pipe(fd) != 0 ) + return pl_error("pipe", 2, NULL, ERR_ERRNO, errno, "create", "pipe", 0); + + in = Sfdopen(fd[0], "r"); + out = Sfdopen(fd[1], "w"); + + if ( PL_open_stream(Read, in) && + PL_open_stream(Write, out) ) + return TRUE; + + return FALSE; +} + + +static int +get_stream_no(term_t t, IOSTREAM **s, int *fn) +{ if ( PL_get_integer(t, fn) ) + return TRUE; + if ( PL_get_stream_handle(t, s) ) + { *fn = Sfileno(*s); + return TRUE; + } + + return FALSE; +} + + +static foreign_t +pl_dup(term_t from, term_t to) +{ IOSTREAM *f = NULL, *t = NULL; + int rval = FALSE; + int fn, tn; + + if ( !get_stream_no(from, &f, &fn) || + !get_stream_no(to, &t, &tn) ) + goto out; + + if ( dup2(fn, tn) < 0 ) + { pl_error("dup", 2, NULL, ERR_ERRNO, errno, "dup", "stream", from); + goto out; + } else + { rval = TRUE; + } + +out: + if ( f ) + PL_release_stream(f); + if ( t ) + PL_release_stream(t); + + return rval; +} + + +static foreign_t +pl_environ(term_t l) +{ extern char **environ; + char **e; + term_t t = PL_copy_term_ref(l); + term_t t2 = PL_new_term_ref(); + term_t nt = PL_new_term_ref(); + term_t vt = PL_new_term_ref(); + functor_t FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); + + for(e = environ; *e; e++) + { char *s = strchr(*e, '='); + + if ( !s ) + s = *e + strlen(*e); + + { int len = s-*e; + char *name = alloca(len+1); + + strncpy(name, *e, len); + name[len] = '\0'; + PL_put_atom_chars(nt, name); + PL_put_atom_chars(vt, s+1); + if ( !PL_cons_functor(nt, FUNCTOR_equal2, nt, vt) || + !PL_unify_list(t, t2, t) || + !PL_unify(t2, nt) ) + return FALSE; + } + } + + return PL_unify_nil(t); +} + + + /******************************* + * DEAMON IO * + *******************************/ + +static atom_t error_file; /* file for output */ +static int error_fd; /* and its fd */ + +static ssize_t +read_eof(void *handle, char *buf, size_t count) +{ return 0; +} + + +static ssize_t +write_null(void *handle, char *buf, size_t count) +{ if ( error_fd ) + { if ( error_fd >= 0 ) + return write(error_fd, buf, count); + } else if ( error_file ) + { error_fd = open(PL_atom_chars(error_file), O_WRONLY|O_CREAT|O_TRUNC, 0644); + return write_null(handle, buf, count); + } + + return count; +} + + +static long +seek_error(void *handle, long pos, int whence) +{ return -1; +} + + +static int +close_null(void *handle) +{ return 0; +} + + +static IOFUNCTIONS dummy = +{ read_eof, + write_null, + seek_error, + close_null, + NULL +}; + + +static void +close_underlying_fd(IOSTREAM *s) +{ if ( s ) + { int fd; + + if ( (fd = Sfileno(s)) >= 0 ) + close(fd); + + s->functions = &dummy; + s->flags &= ~SIO_FILE; /* no longer a file */ + s->flags |= SIO_LBUF; /* do line-buffering */ + } +} + + +static foreign_t +pl_detach_IO() +{ char buf[100]; + + sprintf(buf, "/tmp/pl-out.%d", (int)getpid()); + error_file = PL_new_atom(buf); + + close_underlying_fd(Serror); + close_underlying_fd(Soutput); + close_underlying_fd(Sinput); + close_underlying_fd(name_to_stream("user_input")); + close_underlying_fd(name_to_stream("user_output")); + close_underlying_fd(name_to_stream("user_error")); + +#ifdef HAVE_SETSID + setsid(); +#else +{ int fd; + + if ( (fd = open("/dev/tty", 2)) ) + { ioctl(fd, TIOCNOTTY, NULL); /* detach from controlling tty */ + close(fd); + } +} +#endif + + return TRUE; +} + + +install_t +install_unix() +{ PL_register_foreign("fork", 1, pl_fork, 0); + PL_register_foreign("exec", 1, pl_exec, 0); + PL_register_foreign("wait", 2, pl_wait, 0); + PL_register_foreign("kill", 2, pl_kill, 0); + PL_register_foreign("pipe", 2, pl_pipe, 0); + PL_register_foreign("dup", 2, pl_dup, 0); + PL_register_foreign("detach_IO", 0, pl_detach_IO, 0); + PL_register_foreign("environ", 1, pl_environ, 0); +} + + + + + + + diff --git a/packages/clib/unix.pl b/packages/clib/unix.pl new file mode 100644 index 000000000..a8a175329 --- /dev/null +++ b/packages/clib/unix.pl @@ -0,0 +1,51 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(unix, + [ fork/1, % -'client'|pid + exec/1, % +Command(...Args...) + wait/2, % -Pid, -Reason + kill/2, % +Pid. +Signal + pipe/2, % +Read, +Write + dup/2, % +From, +To + detach_IO/0, + environ/1 % -[Name=Value] + ]). +:- use_module(library(shlib)). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +These predicates are documented in the source-distribution of the package +`clib'. See also the SWI-Prolog home-page at + + http://www.swi.psy.uva.nl/projects/SWI-Prolog/ +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +:- use_foreign_library(foreign(unix), install_unix). diff --git a/packages/clib/uri.c b/packages/clib/uri.c new file mode 100644 index 000000000..6d4504905 --- /dev/null +++ b/packages/clib/uri.c @@ -0,0 +1,1599 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2009, VU University Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#ifdef __WINDOWS__ +#define inline __inline +#endif + +#include +#include +#include +#include +#include +#include + +static size_t removed_dot_segments(size_t len, const pl_wchar_t *in, + pl_wchar_t *out); +static pl_wchar_t *remove_last_segment(const pl_wchar_t *base, + const pl_wchar_t *o); +static char *_utf8_put_char(char *out, int chr); + +#define ISUTF8_MB(c) ((unsigned)(c) >= 0xc0 && (unsigned)(c) <= 0xfd) +#define utf8_put_char(out, chr) \ + ((chr) < 0x80 ? out[0]=(char)(chr), out+1 \ + : _utf8_put_char(out, (chr))) + + + /******************************* + * ERRORS * + *******************************/ + +static atom_t ATOM_query_value; +static atom_t ATOM_fragment; +static atom_t ATOM_path; + +static functor_t FUNCTOR_equal2; /* =/2 */ +static functor_t FUNCTOR_pair2; /* -/2 */ +static functor_t FUNCTOR_uri_components5; +static functor_t FUNCTOR_uri_authority4; +static functor_t FUNCTOR_error2; +static functor_t FUNCTOR_syntax_error1; +static functor_t FUNCTOR_type_error2; +static functor_t FUNCTOR_domain_error2; + + +static int +syntax_error(const char *culprit) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_syntax_error1, + PL_CHARS, culprit, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +type_error(const char *expected, term_t found) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_type_error2, + PL_CHARS, expected, + PL_TERM, found, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + +static int +domain_error(const char *expected, term_t found) +{ term_t ex; + + if ( (ex=PL_new_term_ref()) && + PL_unify_term(ex, + PL_FUNCTOR, FUNCTOR_error2, + PL_FUNCTOR, FUNCTOR_domain_error2, + PL_CHARS, expected, + PL_TERM, found, + PL_VARIABLE) ) + return PL_raise_exception(ex); + + return FALSE; +} + + + /******************************* + * ESCAPING * + *******************************/ + +#define ESC_PATH (CH_PCHAR|CH_EX_PATH) +#define ESC_QUERY (CH_PCHAR|CH_EX_QF) +#define ESC_QVALUE (CH_UNRESERVED|CH_QSUBDELIM|CH_EX_PCHAR|CH_EX_QF) +#define ESC_QNAME (CH_PCHAR) +#define ESC_FRAGMENT (CH_PCHAR|CH_EX_QF) +#define ESC_AUTH (CH_PCHAR) +#define ESC_PASSWD (CH_PCHAR) +#define ESC_USER (CH_PCHAR) +#define ESC_SCHEME (CH_SCHEME) +#define ESC_PORT (CH_DIGIT) +#define ESC_HOST (CH_UNRESERVED|CH_SUBDELIM) + +#define CH_ALPHA 0x0001 +#define CH_DIGIT 0x0002 +#define CH_EX_UNRES 0x0004 +#define CH_GENDELIM 0x0008 +#define CH_SUBDELIM 0x0010 +#define CH_URL 0x0020 +#define CH_EX_PCHAR 0x0040 +#define CH_EX_QF 0x0080 /* Extra query and fragment chars */ +#define CH_EX_SCHEME 0x0100 +#define CH_QSUBDELIM 0x0200 +#define CH_EX_PATH 0x0400 + +#define CH_SCHEME (CH_ALPHA|CH_DIGIT|CH_EX_SCHEME) +#define CH_UNRESERVED (CH_ALPHA|CH_DIGIT|CH_EX_UNRES) +#define CH_PCHAR (CH_UNRESERVED|CH_SUBDELIM|CH_EX_PCHAR) + +static int charflags[128] = {0}; +static int flags_done = 0; + +static void +set_flags(const char *from, int flag) +{ for(; *from; from++) + charflags[from[0]&0xff] |= flag; +} + +static void +fill_flags() +{ if ( !flags_done ) + { int c; + + for(c='a'; c<='z'; c++) + charflags[c] |= CH_ALPHA; + for(c='A'; c<='Z'; c++) + charflags[c] |= CH_ALPHA; + for(c='0'; c<='9'; c++) + charflags[c] |= CH_DIGIT; + + set_flags("-._~", CH_EX_UNRES); + set_flags(":/?#[]@", CH_GENDELIM); + set_flags("!$&'()+*,;=", CH_SUBDELIM); + set_flags("!$'()*,;", CH_QSUBDELIM); /* = CH_SUBDELIM - "&=+" */ + set_flags(":@", CH_EX_PCHAR); + set_flags("/", CH_EX_PATH); + set_flags("/?", CH_EX_QF); + set_flags("+-.", CH_EX_SCHEME); + + set_flags("/:?#&=", CH_URL); + + flags_done = TRUE; + } +} + +#define no_escape(c, f) ((c < 128) && (charflags[(int)c] & (f))) +#define iri_no_escape(c, f) ((c > 128) || (charflags[(int)c] & (f))) + + +/* hex(const pl_wchar_t *in, int digits, int *value) + + Get characters from in and interpret them as a hexadecimal + integer. Returns pointer to the end on success or NULL if error. +*/ + +static const pl_wchar_t * +hex(const pl_wchar_t *in, int digits, int *value) +{ int v = 0; + + while(digits-- > 0) + { int c = *in++; + + if ( c >= '0' && c <= '9' ) + v = (v<<4) + c - '0'; + else if ( c >= 'A' && c <= 'F' ) + v = (v<<4) + c + 10 - 'A'; + else if ( c >= 'a' && c <= 'f' ) + v = (v<<4) + c + 10 - 'a'; + else + return NULL; + } + + *value = v; + return in; +} + + +static const pl_wchar_t * +get_encoded_utf8_cont_1(const pl_wchar_t *in, int *val) +{ int c; + + if ( in[0] == '%' && hex(in+1, 2, &c) ) + { if ( (c&0xc0) == 0x80 ) + { *val = (c&0x3f); + return in+3; + } + } + + return NULL; +} + + +static const pl_wchar_t * +get_encoded_utf8_cont(const pl_wchar_t *in, int cnt, int *val) +{ int shift = cnt*6; + + *val <<= shift; + shift -= 6; + + while(cnt-->0) + { int v0; + + if ( (in = get_encoded_utf8_cont_1(in, &v0)) ) + { *val |= (v0<base = cb->here = cb->tmp; + cb->end = &cb->tmp[sizeof(cb->tmp)/sizeof(pl_wchar_t)]; +} + + +static int +init_charbuf_at_size(charbuf *cb, size_t size) +{ size++; + + if ( size < sizeof(cb->tmp)/sizeof(pl_wchar_t) ) + cb->base = cb->here = cb->tmp; + else + cb->base = cb->here = PL_malloc(size*sizeof(pl_wchar_t)); + + return TRUE; +} + + +static int +add_charbuf(charbuf *cb, int c) +{ if ( cb->here < cb->end ) + { *cb->here++ = c; + } else + { size_t len = (cb->end-cb->base); + + if ( cb->base == cb->tmp ) + { pl_wchar_t *n = PL_malloc(len*2*sizeof(pl_wchar_t)); + memcpy(n, cb->base, sizeof(cb->tmp)); + cb->base = n; + } else + { cb->base = PL_realloc(cb->base, len*2*sizeof(pl_wchar_t)); + } + cb->here = &cb->base[len]; + cb->end = &cb->base[len*2]; + *cb->here++ = c; + } + + return TRUE; +} + + +static inline int +hexdigit(int val) +{ if ( val < 10 ) + return '0'+val; + return 'A'-10+val; +} + + +static int +add_encoded_charbuf(charbuf *cb, int c, int flags) +{ if ( no_escape(c, flags) ) + { add_charbuf(cb, c); + } else + { char tmp[6]; + const char *end = utf8_put_char(tmp, c); + const char *s; + + for(s=tmp; s>4)); + add_charbuf(cb, hexdigit(b&0xf)); + } + } + + return TRUE; +} + + +static int +iri_add_encoded_charbuf(charbuf *cb, int c, int flags) +{ if ( iri_no_escape(c, flags) ) + { add_charbuf(cb, c); + } else + { assert(c < 128); + add_charbuf(cb, '%'); + add_charbuf(cb, hexdigit(c>>4)); + add_charbuf(cb, hexdigit(c&0xf)); + } + + return TRUE; +} + + + +static int +add_nchars_charbuf(charbuf *cb, size_t len, const pl_wchar_t *s) +{ if ( cb->here+len <= cb->end ) + { wcsncpy(cb->here, s, len); + cb->here += len; + } else + { size_t n; + + for(n=0; nstart; + + for(; send; s++) + { if ( s[0] == '%' || (s[0] == '+' && flags == ESC_QVALUE) ) + return TRUE; + } + + return FALSE; +} + + +static int +range_is_unreserved(const range *r, int iri, int flags) +{ const pl_wchar_t *s = r->start; + + if ( iri ) + { for(; send; s++) + { if ( !iri_no_escape(s[0], flags) ) + return FALSE; + } + } else + { for(; send; s++) + { if ( !no_escape(s[0], flags) ) + return FALSE; + } + } + + return TRUE; +} + + +static int +add_verb_range_charbuf(charbuf *cb, const range *r) +{ return add_nchars_charbuf(cb, r->end-r->start, r->start); +} + + +static int +add_decoded_range_charbuf(charbuf *cb, const range *r, int flags) +{ const pl_wchar_t *s = r->start; + + while(send) + { int c; + + if ( *s == '%' ) + { const pl_wchar_t *e; + + if ( (e=get_encoded_utf8(s, &c)) ) + { s = e; + } else if (hex(s+1, 2, &c) ) + { s += 3; + } else + { c = *s++; + } + } else if ( *s == '+' && flags == ESC_QVALUE ) + { s++; + c = ' '; + } else + { c = *s++; + } + + add_charbuf(cb, c); + } + + return TRUE; +} + + +static int +add_normalized_range_charbuf(charbuf *cb, const range *r, int iri, int flags) +{ const pl_wchar_t *s = r->start; + + while(send) + { int c; + + if ( *s == '%' ) + { const pl_wchar_t *e; + + if ( (e=get_encoded_utf8(s, &c)) ) + { s = e; + } else if (hex(s+1, 2, &c) ) + { s += 3; + } else + { c = *s++; + } + } else if ( *s == '+' && flags == ESC_QVALUE ) + { s++; + c = ' '; + } else + { c = *s++; + } + + if ( iri ) + { iri_add_encoded_charbuf(cb, c, flags); + } else + { add_encoded_charbuf(cb, c, flags); + } + } + + return TRUE; +} + + +/* add_range_charbuf(charbuf *cb, const range *r, int iri, int flags) + + Add a range of characters while normalizing %-encoding. This + implies not to use encoding if it is not needed and upcase + %xx to %XX otherwise. + + If iri == TRUE, values >= 128 are not escaped. Otherwise they + use %-encoded UTF-8 +*/ + +static int +add_range_charbuf(charbuf *cb, const range *r, int iri, int flags) +{ if ( range_has_escape(r, flags) ) + { return add_normalized_range_charbuf(cb, r, iri, flags); + } else if ( range_is_unreserved(r, iri, flags) ) + { add_nchars_charbuf(cb, r->end-r->start, r->start); + } else + { const pl_wchar_t *s = r->start; + + if ( iri ) + { while(send) + iri_add_encoded_charbuf(cb, *s++, flags); + } else + { while(send) + add_encoded_charbuf(cb, *s++, flags); + } + } + + return TRUE; +} + + +/* add_lwr_range_charbuf(charbuf *cb, const range *r, int iri, int flags) + + Add a range of characters while normalizing %-encoding and + mapping all characters to lowercase. + + FIXME: encoding and decoding compatible to add_range_charbuf(); +*/ + + +static int +add_lwr_range_charbuf(charbuf *cb, const range *r, int iri, int flags) +{ const pl_wchar_t *s = r->start; + + while(send) + { int c; + + if ( *s == '%' ) + { const pl_wchar_t *e; + + if ( (e=get_encoded_utf8(s, &c)) ) + { s = e; + } else if (hex(s+1, 2, &c) ) + { s += 3; + } else + { c = *s++; + } + } else + { c = *s++; + } + + if ( iri ) + iri_add_encoded_charbuf(cb, towlower((wint_t)c), flags); + else + add_encoded_charbuf(cb, towlower((wint_t)c), flags); + } + + return TRUE; +} + + +static void +free_charbuf(charbuf *cb) +{ if ( cb->base != cb->tmp ) + PL_free(cb->base); +} + + +#define TXT_EX_TEXT (CVT_ATOM|CVT_STRING|CVT_EXCEPTION) + +static int +get_text_arg(term_t term, int pos, size_t *len, pl_wchar_t **s, int flags) +{ term_t tmp = PL_new_term_ref(); + + _PL_get_arg(pos, term, tmp); + if ( PL_is_variable(tmp) ) + return FALSE; + if ( !PL_get_wchars(tmp, len, s, flags) ) + return -1; + + return TRUE; +} + + +/** uri_components(+URI, -Components) + +Based on RFC-3986 regular expression: + + == + ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? + 12 3 4 5 6 7 8 9 + == +*/ + +typedef struct uri_component_ranges +{ range scheme; + range authority; + range path; + range query; + range fragment; +} uri_component_ranges; + + +static const pl_wchar_t * +skip_not(const pl_wchar_t *in, const pl_wchar_t *end, const pl_wchar_t *chars) +{ if ( !chars[1] ) + { for(; in < end; in++) + { if ( chars[0] == in[0] ) + return in; + } + } else + { for(; in < end; in++) + { if ( wcschr(chars, in[0]) ) + return in; + } + } + return in; +} + + +static int +unify_range(term_t t, const range *r) +{ if ( r->start ) + return PL_unify_wchars(t, PL_ATOM, r->end - r->start, r->start); + + return TRUE; +} + + +static int +parse_uri(uri_component_ranges *ranges, size_t len, const pl_wchar_t *s) +{ const pl_wchar_t *end = &s[len]; + const pl_wchar_t *here = s; + const pl_wchar_t *e; + + memset(ranges, 0, sizeof(*ranges)); + + e = skip_not(here, end, L":/?#"); + if ( e > s && e[0] == ':' ) /* 1&2 */ + { ranges->scheme.start = s; + ranges->scheme.end = e; + here = e+1; + } + + if ( here[0] == '/' && here[1] == '/' ) /* 3 */ + { here += 2; /* 4 */ + e = skip_not(here, end, L"/?#"); + ranges->authority.start = here; + ranges->authority.end = e; + here = e; /* 5 */ + } + + e = skip_not(here, end, L"?#"); + ranges->path.start = here; + ranges->path.end = e; + here = e; /* 6 */ + + if ( here[0] == '?' ) + { here++; /* 7 */ + e = skip_not(here, end, L"#"); + ranges->query.start = here; + ranges->query.end = e; + here = e; /* 8 */ + } + + if ( here[0] == '#' ) + { here++; /* 9 */ + ranges->fragment.start = here; + ranges->fragment.end = end; + } + + return TRUE; +} + + +static foreign_t +uri_components(term_t URI, term_t components) +{ pl_wchar_t *s; + size_t len; + + if ( PL_get_wchars(URI, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST) ) + { uri_component_ranges ranges; + term_t rt = PL_new_term_refs(6); + term_t av = rt+1; + + parse_uri(&ranges, len, s); + + unify_range(av+0, &ranges.scheme); + unify_range(av+1, &ranges.authority); + unify_range(av+2, &ranges.path); + unify_range(av+3, &ranges.query); + unify_range(av+4, &ranges.fragment); + + return (PL_cons_functor_v(rt, FUNCTOR_uri_components5, av) && + PL_unify(components, rt)); + } else if ( PL_is_functor(components, FUNCTOR_uri_components5) ) + { charbuf b; + int rc; + + init_charbuf(&b); + /* schema */ + if ( (rc=get_text_arg(components, 1, &len, &s, TXT_EX_TEXT)) == TRUE ) + { add_nchars_charbuf(&b, len, s); + add_charbuf(&b, ':'); + } else if ( rc == -1 ) + { free_charbuf(&b); + return FALSE; + } + /* authority */ + if ( (rc=get_text_arg(components, 2, &len, &s, TXT_EX_TEXT)) == TRUE ) + { add_charbuf(&b, '/'); + add_charbuf(&b, '/'); + add_nchars_charbuf(&b, len, s); + } else if ( rc == -1 ) + { free_charbuf(&b); + return FALSE; + } + /* path */ + if ( (rc=get_text_arg(components, 3, &len, &s, TXT_EX_TEXT)) == TRUE ) + { add_nchars_charbuf(&b, len, s); + } else if ( rc == -1 ) + { free_charbuf(&b); + return FALSE; + } + /* query */ + if ( (rc=get_text_arg(components, 4, &len, &s, TXT_EX_TEXT)) == TRUE ) + { if ( len > 0 ) + { add_charbuf(&b, '?'); + add_nchars_charbuf(&b, len, s); + } + } else if ( rc == -1 ) + { free_charbuf(&b); + return FALSE; + } + /* fragment */ + if ( (rc=get_text_arg(components, 5, &len, &s, TXT_EX_TEXT)) == TRUE ) + { add_charbuf(&b, '#'); + add_nchars_charbuf(&b, len, s); + } else if ( rc == -1 ) + { free_charbuf(&b); + return FALSE; + } + + rc = PL_unify_wchars(URI, PL_ATOM, b.here-b.base, b.base); + free_charbuf(&b); + + return rc; + } else /* generate an error */ + { return PL_get_wchars(URI, &len, &s, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION); + } +} + + +/** uri_is_global(+URI) is semidet. +*/ + +static foreign_t +uri_is_global(term_t URI) +{ pl_wchar_t *s; + size_t len; + + if ( PL_get_wchars(URI, &len, &s, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + { const pl_wchar_t *e; + const pl_wchar_t *end = &s[len]; + range r; + + e = skip_not(s, end, L":/?#"); + if ( e > s && e[0] == ':' ) + { r.start = s; + r.end = e; + if ( range_is_unreserved(&r, TRUE, CH_SCHEME) ) + return TRUE; + } + } + + return FALSE; +} + + + /******************************* + * QUERY-STRING * + *******************************/ + +static int +unify_decoded_atom(term_t t, range *r, int flags) +{ if ( range_has_escape(r, flags) ) + { charbuf b; + int rc; + + init_charbuf(&b); + add_decoded_range_charbuf(&b, r, flags); + rc = PL_unify_wchars(t, PL_ATOM, b.here - b.base, b.base); + free_charbuf(&b); + return rc; + } else + { return unify_range(t, r); + } +} + + +static int +unify_query_string_components(term_t list, size_t len, const pl_wchar_t *qs) +{ if ( len == 0 ) + { return PL_unify_nil(list); + } else + { term_t tail = PL_copy_term_ref(list); + term_t head = PL_new_term_ref(); + term_t eq = PL_new_term_refs(3); + term_t nv = eq+1; + const pl_wchar_t *end = &qs[len]; + + while(qs < end) + { range name, value; + + name.start = qs; + name.end = skip_not(qs, end, L"="); + if ( name.end < end ) + { value.start = name.end+1; + value.end = skip_not(value.start, end, L"&"); + + qs = value.end+1; + } else + { return syntax_error("illegal_uri_query"); + } + + PL_put_variable(nv+0); + PL_put_variable(nv+1); + unify_decoded_atom(nv+0, &name, ESC_QNAME); + unify_decoded_atom(nv+1, &value, ESC_QVALUE); + + if ( !PL_cons_functor_v(eq, FUNCTOR_equal2, nv) || + !PL_unify_list(tail, head, tail) || + !PL_unify(head, eq) ) + return FALSE; + } + + return PL_unify_nil(tail); + } +} + + +static int +add_encoded_term_charbuf(charbuf *cb, term_t value, int flags) +{ pl_wchar_t *s; + range r; + size_t len; + + if ( !PL_get_wchars(value, &len, &s, CVT_ATOMIC|CVT_EXCEPTION) ) + return FALSE; + + r.start = s; + r.end = r.start+len; + if ( range_is_unreserved(&r, TRUE, flags) ) + { add_nchars_charbuf(cb, r.end-r.start, r.start); + } else + { const pl_wchar_t *s = r.start; + + while(sscheme.start ) + { add_lwr_range_charbuf(cb, &ranges->scheme, iri, ESC_SCHEME); + add_charbuf(cb, ':'); + } + if ( ranges->authority.start ) + { add_charbuf(cb, '/'); + add_charbuf(cb, '/'); + add_lwr_range_charbuf(cb, &ranges->authority, iri, ESC_AUTH); + } + if ( ranges->path.end > ranges->path.start ) + { charbuf pb; + charbuf path; + size_t len; + + init_charbuf(&pb); + add_range_charbuf(&pb, &ranges->path, iri, ESC_PATH); + init_charbuf_at_size(&path, pb.here-pb.base); + len = removed_dot_segments(pb.here-pb.base, pb.base, path.base); + add_nchars_charbuf(cb, len, path.base); + free_charbuf(&path); + free_charbuf(&pb); + } + if ( ranges->query.start ) + { add_charbuf(cb, '?'); + add_range_charbuf(cb, &ranges->query, iri, ESC_QUERY); + } + if ( ranges->fragment.start ) + { add_charbuf(cb, '#'); + add_range_charbuf(cb, &ranges->fragment, iri, ESC_FRAGMENT); + } + + return TRUE; +} + + +static foreign_t +normalized(term_t URI, term_t CannonicalURI, int iri) +{ pl_wchar_t *s; + size_t len; + + if ( PL_get_wchars(URI, &len, &s, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + { uri_component_ranges ranges; + charbuf b; + int rc; + + parse_uri(&ranges, len, s); + init_charbuf(&b); + normalize_in_charbuf(&b, &ranges, iri); + + rc = PL_unify_wchars(CannonicalURI, PL_ATOM, b.here-b.base, b.base); + free_charbuf(&b); + + return rc; + } + + return FALSE; +} + + +/** uri_normalized(+URI, -CannonicalURI) +*/ + +static foreign_t +uri_normalized(term_t URI, term_t CannonicalURI) +{ return normalized(URI, CannonicalURI, FALSE); +} + + +/** uri_normalized_iri(+URI, -CannonicalIRI) +*/ + +static foreign_t +uri_normalized_iri(term_t URI, term_t CannonicalURI) +{ return normalized(URI, CannonicalURI, TRUE); +} + + +static int +ranges_in_charbuf(charbuf *cb, uri_component_ranges *ranges) +{ if ( ranges->scheme.start ) + { add_verb_range_charbuf(cb, &ranges->scheme); + add_charbuf(cb, ':'); + } + if ( ranges->authority.start ) + { add_charbuf(cb, '/'); + add_charbuf(cb, '/'); + add_verb_range_charbuf(cb, &ranges->authority); + } + add_verb_range_charbuf(cb, &ranges->path); + if ( ranges->query.start ) + { add_charbuf(cb, '?'); + add_verb_range_charbuf(cb, &ranges->query); + } + if ( ranges->fragment.start ) + { add_charbuf(cb, '#'); + add_verb_range_charbuf(cb, &ranges->fragment); + } + + return TRUE; +} + + +typedef struct +{ atom_t atom; + pl_wchar_t *text; + uri_component_ranges ranges; +} base_cache; + +#ifdef _REENTRANT +#include +static pthread_key_t base_key; + +static void +free_base_cache(void *cache) +{ base_cache *base = cache; + + if ( PL_query(PL_QUERY_HALTING) ) + return; + + if ( base->atom ) + { PL_unregister_atom(base->atom); + PL_free(base->text); + } + + PL_free(base); +} + +static base_cache * +myBase() +{ base_cache *base; + + if ( (base=pthread_getspecific(base_key)) ) + return base; + base = PL_malloc(sizeof(*base)); + memset(base, 0, sizeof(*base)); + + pthread_setspecific(base_key, base); + return base; +} + +#else +static base_cache base_store; +#define myBase() &base_store; +#endif + + +static const uri_component_ranges * +base_ranges(term_t t) +{ atom_t a; + + if ( PL_get_atom(t, &a) ) + { base_cache *base = myBase(); + + if ( base->atom != a ) + { size_t len; + pl_wchar_t *s; + + if ( base->atom ) + { PL_unregister_atom(base->atom); + PL_free(base->text); + } + if ( !PL_get_wchars(t, &len, &s, CVT_ATOM|BUF_MALLOC) ) + return NULL; + base->atom = a; + PL_register_atom(a); + base->text = s; + parse_uri(&base->ranges, len, s); + } + + return &base->ranges; + } else + { type_error("atom", t); + return NULL; + } +} + + +static foreign_t +resolve(term_t Rel, term_t Base, term_t URI, int normalize, int iri) +{ pl_wchar_t *s; + size_t slen; + uri_component_ranges s_ranges, t_ranges; + int rc; + size_t len; + charbuf out, pb, path; + + init_charbuf(&pb); /* path-buffer */ + + if ( PL_get_wchars(Rel, &slen, &s, + CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) + { parse_uri(&s_ranges, slen, s); + if ( s_ranges.scheme.start ) + { t_ranges = s_ranges; + } else + { const uri_component_ranges *b_ranges; + + if ( !(b_ranges = base_ranges(Base)) ) + return FALSE; + + memset(&t_ranges, 0, sizeof(t_ranges)); + if ( s_ranges.authority.start ) + { t_ranges.authority = s_ranges.authority; + t_ranges.path = s_ranges.path; + t_ranges.query = s_ranges.query; + } else + { if ( s_ranges.path.start == s_ranges.path.end ) + { t_ranges.path = b_ranges->path; + if ( s_ranges.query.start ) + t_ranges.query = s_ranges.query; + else + t_ranges.query = b_ranges->query; + } else + { if ( s_ranges.path.start[0] == '/' ) + { t_ranges.path = s_ranges.path; + } else + { if ( b_ranges->authority.start && + b_ranges->path.start == b_ranges->path.end ) + { add_charbuf(&pb, '/'); + add_verb_range_charbuf(&pb, &s_ranges.path); + } else + { range path = b_ranges->path; + + path.end = remove_last_segment(path.start, path.end); + add_verb_range_charbuf(&pb, &path); + add_verb_range_charbuf(&pb, &s_ranges.path); + t_ranges.path.start = pb.base; + t_ranges.path.end = pb.here; + } + } + t_ranges.query = s_ranges.query; + } + t_ranges.authority = b_ranges->authority; + } + t_ranges.scheme = b_ranges->scheme; + t_ranges.fragment = s_ranges.fragment; + } + } else + return FALSE; + + init_charbuf(&out); /* output buffer */ + + if ( normalize ) + { normalize_in_charbuf(&out, &t_ranges, iri); + } else + { init_charbuf_at_size(&path, t_ranges.path.end - t_ranges.path.start); + len = removed_dot_segments(t_ranges.path.end - t_ranges.path.start, + t_ranges.path.start, + path.base); + t_ranges.path.start = path.base; + t_ranges.path.end = path.base+len; + free_charbuf(&pb); + + ranges_in_charbuf(&out, &t_ranges); + } + + rc = PL_unify_wchars(URI, PL_ATOM, out.here-out.base, out.base); + free_charbuf(&out); + + return rc; +} + +/** uri_resolve(+Relative, +Base, -Absolute) is det. +*/ + +static foreign_t +uri_resolve(term_t Rel, term_t Base, term_t URI) +{ return resolve(Rel, Base, URI, FALSE, FALSE); +} + + +/** uri_normalized(+Relative, +Base, -Absolute) is det. +*/ + +static foreign_t +uri_normalized3(term_t Rel, term_t Base, term_t URI) +{ return resolve(Rel, Base, URI, TRUE, FALSE); +} + + +/** uri_normalized_iri(+Relative, +Base, -Absolute) is det. +*/ + +static foreign_t +uri_normalized_iri3(term_t Rel, term_t Base, term_t IRI) +{ return resolve(Rel, Base, IRI, TRUE, TRUE); +} + + + /******************************* + * PATH LOGIC * + *******************************/ + +/* http://labs.apache.org/webarch/uri/rfc/rfc3986.html#relative-dot-segments +*/ + +static pl_wchar_t * +remove_last_segment(const pl_wchar_t *base, const pl_wchar_t *o) +{ while(o>base && o[-1] != '/' ) + o--; + + return (pl_wchar_t*) o; +} + + +static inline int +fetch(const pl_wchar_t *in, const pl_wchar_t *end, int at) +{ if ( in+at>=end ) + return 0; + return in[at]; +} + +static size_t +removed_dot_segments(size_t len, const pl_wchar_t *in, pl_wchar_t *out) +{ const pl_wchar_t *end = &in[len]; + pl_wchar_t *o = out; + + while(in "/" */ + continue; + } + if ( !fetch(in, end, 2) ) + { *o++ = '/'; /* 2B "/." --> "/" (and close) */ + in += 2; + continue; + } + if ( fetch(in, end, 2) == '.' ) + { if ( fetch(in, end, 3) == '/' ) + { in += 3; /* 2C "/../" --> "/" */ + o = remove_last_segment(out, o); + if ( o>out ) o--; /* delete / */ + continue; + } + if ( !fetch(in, end, 3) ) + { o = remove_last_segment(out, o); + if ( o>out ) o--; /* delete / */ + *o++ = '/'; + in += 3; + continue; + } + } + } + if ( in[0] == '.' ) + { if ( !fetch(in, end, 1) ) + { in++; /* 3D */ + continue; + } + if ( fetch(in, end, 1) == '.' && !fetch(in, end, 2) ) + { in += 2; /* 3D */ + continue; + } + } + if ( in[0] == '/' ) + *o++ = *in++; + while( in < end && in[0] != '/' ) + *o++ = *in++; + } + + return o-out; +} + + + /******************************* + * IRI HANDLING * + *******************************/ + +#define utf8_put_char(out, chr) \ + ((chr) < 0x80 ? out[0]=(char)(chr), out+1 \ + : _utf8_put_char(out, (chr))) + + +static char * +_utf8_put_char(char *out, int chr) +{ if ( chr < 0x80 ) + { *out++ = chr; + } else if ( chr < 0x800 ) + { *out++ = 0xc0|((chr>>6)&0x1f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x10000 ) + { *out++ = 0xe0|((chr>>12)&0x0f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x200000 ) + { *out++ = 0xf0|((chr>>18)&0x07); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x4000000 ) + { *out++ = 0xf8|((chr>>24)&0x03); + *out++ = 0x80|((chr>>18)&0x3f); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( (unsigned)chr < 0x80000000 ) + { *out++ = 0xfc|((chr>>30)&0x01); + *out++ = 0x80|((chr>>24)&0x3f); + *out++ = 0x80|((chr>>18)&0x3f); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } + + return out; +} + + +/** uri_iri(+URI, -IRI) is det. + uri_iri(-URI, +IRI) is det. + +Perform %- and UTF-8 encoding/decoding to translate between a URI and +IRI +*/ + +static foreign_t +uri_iri(term_t URI, term_t IRI) +{ if ( !PL_is_variable(URI) ) + return uri_normalized_iri(URI, IRI); + else + return uri_normalized(IRI, URI); +} + + + /******************************* + * REGISTRATION * + *******************************/ + +#define MKATOM(n) \ + ATOM_ ## n = PL_new_atom(#n) +#define MKFUNCTOR(n,a) \ + FUNCTOR_ ## n ## a = PL_new_functor(PL_new_atom(#n), a) + +install_t +install_uri() +{ MKATOM(query_value); + MKATOM(fragment); + MKATOM(path); + + MKFUNCTOR(uri_components, 5); + MKFUNCTOR(uri_authority, 4); + MKFUNCTOR(error, 2); + MKFUNCTOR(syntax_error, 1); + MKFUNCTOR(type_error, 2); + MKFUNCTOR(domain_error, 2); + FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); + FUNCTOR_pair2 = PL_new_functor(PL_new_atom("-"), 2); + +#ifdef _REENTRANT + pthread_key_create(&base_key, free_base_cache); +#endif + + PL_register_foreign("uri_components", 2, uri_components, 0); + PL_register_foreign("uri_is_global", 1, uri_is_global, 0); + PL_register_foreign("uri_normalized", 2, uri_normalized, 0); + PL_register_foreign("uri_normalized_iri", 2, uri_normalized_iri, 0); + PL_register_foreign("uri_resolve", 3, uri_resolve, 0); + PL_register_foreign("uri_normalized", 3, uri_normalized3, 0); + PL_register_foreign("uri_normalized_iri", 3, uri_normalized_iri3, 0); + PL_register_foreign("uri_query_components", 2, uri_query_components, 0); + PL_register_foreign("uri_authority_components", + 2, uri_authority_components, 0); + PL_register_foreign("uri_encoded", 3, uri_encoded, 0); + PL_register_foreign("uri_iri", 2, uri_iri, 0); +} diff --git a/packages/clib/uri.pl b/packages/clib/uri.pl new file mode 100644 index 000000000..4ab37f44d --- /dev/null +++ b/packages/clib/uri.pl @@ -0,0 +1,282 @@ +/* Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: J.Wielemaker@cs.vu.nl + WWW: http://www.swi-prolog.org + Copyright (C): 2009, VU University Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +:- module(uri, + [ uri_components/2, % ?URI, ?Components + uri_data/3, % ?Field, +Components, ?Data + uri_data/4, % +Field, +Components, -Data, -New + + uri_normalized/2, % +URI, -NormalizedURI + uri_normalized_iri/2, % +URI, -NormalizedIRI + uri_normalized/3, % +URI, +Base, -NormalizedURI + uri_normalized_iri/3, % +URI, +Base, -NormalizedIRI + uri_resolve/3, % +URI, +Base, -AbsURI + uri_is_global/1, % +URI + uri_query_components/2, % ?QueryString, ?NameValueList + uri_authority_components/2, % ?Authority, ?Components + uri_authority_data/3, % ?Field, ?Components, ?Data + % Encoding + uri_encoded/3, % +Component, ?Value, ?Encoded + uri_file_name/2, % ?URI, ?Path + uri_iri/2 % ?URI, ?IRI + ]). +:- use_foreign_library(foreign(uri)). + +/** Process URIs + +This library provides high-performance C-based primitives for +manipulating URIs. We decided for a C-based implementation for the much +better performance on raw character manipulation. Notably, URI handling +primitives are used in time-critical parts of RDF processing. This +implementation is based on RFC-3986: + + http://labs.apache.org/webarch/uri/rfc/rfc3986.html + +The URI processing in this library is rather liberal. That is, we break +URIs according to the rules, but we do not validate that the components +are valid. Also, percent-decoding for IRIs is liberal. It first tries +UTF-8; then ISO-Latin-1 and finally accepts %-characters verbatim. + +Earlier experience has shown that strict enforcement of the URI syntax +results in many errors that are accepted by many other web-document +processing tools. +*/ + +%% uri_components(+URI, -Components) is det. +%% uri_components(-URI, +Components) is det. +% +% Break a URI into its 5 basic components according to the +% RFC-3986 regular expression: +% +% == +% ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? +% 12 3 4 5 6 7 8 9 +% == +% +% @param Components is a term uri_components(Scheme, Authority, +% Path, Search, Fragment). See uri_data/3 for accessing this +% structure. + +%% uri_data(?Field, +Components, ?Data) is semidet. +% +% Provide access the uri_component structure. Defined field-names +% are: =scheme=, =authority=, =path=, =search= and =fragment= + +uri_data(scheme, uri_components(S, _, _, _, _), S). +uri_data(authority, uri_components(_, A, _, _, _), A). +uri_data(path, uri_components(_, _, P, _, _), P). +uri_data(search, uri_components(_, _, _, S, _), S). +uri_data(fragment, uri_components(_, _, _, _, F), F). + +%% uri_data(+Field, +Components, +Data, -NewComponents) is semidet. +% +% NewComponents is the same as Components with Field set to Data. + +uri_data(scheme, uri_components(_, A, P, Q, F), S, + uri_components(S, A, P, Q, F)). +uri_data(authority, uri_components(S, _, P, Q, F), A, + uri_components(S, A, P, Q, F)). +uri_data(path, uri_components(S, A, _, Q, F), P, + uri_components(S, A, P, Q, F)). +uri_data(search, uri_components(S, A, P, _, F), Q, + uri_components(S, A, P, Q, F)). +uri_data(fragment, uri_components(S, A, P, Q, _), F, + uri_components(S, A, P, Q, F)). + +%% uri_normalized(+URI, -NormalizedURI) is det. +% +% NormalizedURI is the normalized form of URI. Normalization is +% syntactic and involves the following steps: +% +% * 6.2.2.1. Case Normalization +% * 6.2.2.2. Percent-Encoding Normalization +% * 6.2.2.3. Path Segment Normalization + +%% uri_normalized_iri(+URI, -NormalizedIRI) is det. +% +% As uri_normalized/2, but percent-encoding is translated into IRI +% Unicode characters. The translation is liberal: valid UTF-8 +% sequences of %-encoded bytes are mapped to the Unicode +% character. Other %XX-sequences are mapped to the corresponding +% ISO-Latin-1 character and sole % characters are left untouched. +% +% @see uri_iri/2. + + +%% uri_is_global(+URI) is semidet. +% +% True if URI has a scheme. The semantics is the same as the code +% below, but the implementation is more efficient as it does not +% need to parse the other components, nor needs to bind the +% scheme. +% +% == +% uri_is_global(URI) :- +% uri_components(URI, Components), +% uri_data(Components, scheme, Scheme), +% nonvar(Scheme). +% == + +%% uri_resolve(+URI, +Base, -GlobalURI) is det. +% +% Resolve a possibly local URI relative to Base. This implements +% http://labs.apache.org/webarch/uri/rfc/rfc3986.html#relative-transform + +%% uri_normalized(+URI, +Base, -NormalizedGlobalURI) is det. +% +% NormalizedGlobalURI is the normalized global version of URI. +% Behaves as if defined by: +% +% == +% uri_normalized(URI, Base, NormalizedGlobalURI) :- +% uri_resolve(URI, Base, GlobalURI), +% uri_normalized(GlobalURI, NormalizedGlobalURI). +% == + +%% uri_normalized_iri(+URI, +Base, -NormalizedGlobalIRI) is det. +% +% NormalizedGlobalIRI is the normalized global IRI of URI. Behaves +% as if defined by: +% +% == +% uri_normalized(URI, Base, NormalizedGlobalIRI) :- +% uri_resolve(URI, Base, GlobalURI), +% uri_normalized_iri(GlobalURI, NormalizedGlobalIRI). +% == + +%% uri_query_components(+String, -Query) is det. +%% uri_query_components(-String, +Query) is det. +% +% Perform encoding and decoding of an URI query string. Query is a +% list of fully decoded (Unicode) Name=Value pairs. In mode (-,+), +% query elements of the forms Name(Value) and Name-Value are also +% accepted to enhance interoperability with the option and pairs +% libraries. E.g. +% +% == +% ?- uri_query_components(QS, [a=b, c('d+w'), n-'VU Amsterdam']). +% QS = 'a=b&c=d%2Bw&n=VU%20Amsterdam'. +% +% ?- uri_query_components('a=b&c=d%2Bw&n=VU%20Amsterdam', Q). +% Q = [a=b, c='d+w', n='VU Amsterdam']. +% == + + +%% uri_authority_components(+Authority, -Components) is det. +%% uri_authority_components(-Authority, +Components) is det. +% +% Break-down the authority component of a URI. The fields of the +% structure Components can be accessed using uri_authority_data/3. + +%% uri_authority_data(+Field, ?Components, ?Data) is semidet. +% +% Provide access the uri_authority structure. Defined field-names +% are: =user=, =password=, =host= and =port= + +uri_authority_data(user, uri_authority(U, _, _, _), U). +uri_authority_data(password, uri_authority(_, P, _, _), P). +uri_authority_data(host, uri_authority(_, _, H, _), H). +uri_authority_data(port, uri_authority(_, _, _, P), P). + + +%% uri_encoded(+Component, +Value, -Encoded) is det. +%% uri_encoded(+Component, -Value, +Encoded) is det. +% +% Encoded is the URI encoding for Value. When encoding +% (Value->Encoded), Component specifies the URI component where +% the value is used. It is one of =query_value=, =fragment= or +% =path=. Besides alphanumerical characters, the following +% characters are passed verbatim (the set is split in logical +% groups according to RFC3986). +% +% $ query_value, fragment : +% "-._~" | "!$'()*,;" | ":@" | "/?" +% $ path : +% "-._~" | "!$&'()*,;=" | ":@" | "/" + + +%% uri_iri(+URI, -IRI) is det. +%% uri_iri(-URI, +IRI) is det. +% +% Convert between a URI, encoded in US-ASCII and an IRI. An IRI is +% a fully expanded Unicode string. Unicode strings are first +% encoded into UTF-8, after which %-encoding takes place. +% +% @error syntax_error(Culprit) in mode (+,-) if URI is not a +% legally percent-encoded UTF-8 string. + + +%% uri_file_name(+URI, -FileName) is semidet. +%% uri_file_name(-URI, +FileName) is det. +% +% Convert between a URI and a local file_name. This protocol is +% covered by RFC 1738. Please note that file-URIs use _absolute_ +% paths. The mode (-, +) translates a possible relative path into +% an absolute one. + +uri_file_name(URI, FileName) :- + nonvar(URI), !, + uri_components(URI, Components), + uri_data(scheme, Components, file), + ( uri_data(authority, Components, '') + -> true + ; uri_data(authority, Components, localhost) + ), + uri_data(path, Components, FileNameEnc), + uri_encoded(path, FileName0, FileNameEnc), + delete_leading_slash(FileName0, FileName). +uri_file_name(URI, FileName) :- + nonvar(FileName), !, + absolute_file_name(FileName, Path0), + ensure_leading_slash(Path0, Path), + uri_encoded(path, Path, PathEnc), + uri_data(scheme, Components, file), + uri_data(authority, Components, ''), + uri_data(path, Components, PathEnc), + uri_components(URI, Components). + +%% ensure_leading_slash(+WinPath, -Path). +%% delete_leading_slash(+Path, -WinPath). +% +% Deal with the fact that absolute paths in Windows start with a +% drive letter rather than a /. For URIs we need a path that +% starts with a /. + +ensure_leading_slash(Path, SlashPath) :- + ( sub_atom(Path, 0, _, _, /) + -> SlashPath = Path + ; atom_concat(/, Path, SlashPath) + ). + +:- if(current_prolog_flag(windows, true)). +delete_leading_slash(Path, WinPath) :- + atom_concat(/, WinPath, Path), + is_absolute_file_name(WinPath), !. +:- endif. +delete_leading_slash(Path, Path). diff --git a/packages/clib/util.h b/packages/clib/util.h new file mode 100644 index 000000000..6037cd197 --- /dev/null +++ b/packages/clib/util.h @@ -0,0 +1,75 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef UTIL_H_INCLUDED +#define UTIL_H_INCLUDED + +#define HAVE_STRERROR 1 +#define HAVE_TZNAME + +#if defined(sun) && !defined(__svr4__) /* Old SunOS 4.x */ +#undef HAVE_STRERROR +#undef HAVE_TZNAME +#endif + +#include +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +typedef struct +{ char *name; + char *value; +} var, *Var; + +extern int use_nph; /* 1: nph-cgi-script */ + +/* util.c */ +#ifndef HAVE_STRERROR +const char * strerror(int err); +#endif +char * save_string(const char *s); +int cat(const char *file); +int catfd(const char *file, FILE *out); +void error(const char *msg, ...); +void printenv(void); +int copyPage(FILE *in, FILE *out, Var vars); +int echoPage(const char *page, ...); +int echoPagev(const char *page, va_list args); +int mailFileFromVars(const char *email, + const char *from, + const char *file, + Var vars); +int mailFile(const char *email, + const char *from, + const char *file, + ...); +long fileSize(const char *file); +char * rfc_date(time_t t); +char * rfc_modified(const char *file); + +#endif /*UTIL_H_INCLUDED*/ diff --git a/packages/clib/winpipe.c b/packages/clib/winpipe.c new file mode 100644 index 000000000..fca17f426 --- /dev/null +++ b/packages/clib/winpipe.c @@ -0,0 +1,290 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2004, University of Amsterdam + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + As a special exception, if you link this library with other files, + compiled with a Free Software compiler, to produce an executable, this + library does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. +*/ + +#include +#include +#include + +#ifdef __WINDOWS__ +#include + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +This file provides a windows alternative to an anonymous pipe that can +be waited for in the same pool as sockets using by tcp_select/3. It is a +work-around that allows a socket-based server using tcp_select/3 for IO +multiplexing to create an additional communication channal for +controlling the server. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#define PIPE_MAGIC 0x6b3a914cL +#define ISPIPE(p) if ( p->magic != PIPE_MAGIC ) \ + { errno = EINVAL; \ + return -1; \ + } + +typedef struct pipe +{ long magic; /* magic code */ + int size; /* size of the pipe */ + char *buf; /* Buffer */ + int in; + int out; + int writers; /* write open count */ + int readers; /* read open count */ + int blocking; /* pipe is blocking */ + + CRITICAL_SECTION mutex; + HANDLE event; /* signal if data is available */ +} pipe; + + +static pipe * +create_pipe(int size, int blocking) +{ pipe *p = PL_malloc(sizeof(*p)); + + p->buf = PL_malloc(size); + p->size = size; + p->in = p->out = 0; + p->readers = p->writers = 0; + p->blocking = blocking; + + InitializeCriticalSection(&p->mutex); + p->event = CreateEvent(NULL, FALSE, FALSE, NULL); + p->magic = PIPE_MAGIC; + + return p; +} + + +static int +destroy_pipe(pipe *p) +{ ISPIPE(p); + + EnterCriticalSection(&p->mutex); + + PL_free(p->buf); + CloseHandle(p->event); + LeaveCriticalSection(&p->mutex); + DeleteCriticalSection(&p->mutex); + p->magic = 0; + PL_free(p); + + return 0; +} + + +static int +write_pipe(pipe *pipe, char *buf, int size) +{ ISPIPE(pipe); + + EnterCriticalSection(&pipe->mutex); + + for(;;) + { if ( pipe->in + size <= pipe->size ) + { memcpy(pipe->buf+pipe->in, buf, size); + pipe->in += size; + + SetEvent(pipe->event); + LeaveCriticalSection(&pipe->mutex); + + return size; + } + + if ( pipe->out > 0 ) + { memmove(pipe->buf, pipe->buf+pipe->out, pipe->in - pipe->out); + pipe->in -= pipe->out; + pipe->out = 0; + } + + if ( size > pipe->size ) + size = pipe->size; + } +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Non-blocking read from our pipe. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +static int +read_pipe(pipe *pipe, char *buf, int size) +{ int avail; + + ISPIPE(pipe); + +retry: + EnterCriticalSection(&pipe->mutex); + avail = pipe->in - pipe->out; + + if ( avail > 0 ) + { if ( size < avail ) + avail = size; + + memcpy(buf, pipe->buf+pipe->out, avail); + pipe->out += avail; + if ( pipe->in == pipe->out ) + pipe->in = pipe->out = 0; + + LeaveCriticalSection(&pipe->mutex); + return avail; + } + + if ( pipe->writers == 0 ) + { LeaveCriticalSection(&pipe->mutex); + return 0; + } + + if ( pipe->blocking ) + { int rc; + + LeaveCriticalSection(&pipe->mutex); + rc = MsgWaitForMultipleObjects(1, + &pipe->event, + FALSE, /* wait for either event */ + INFINITE, + QS_ALLINPUT); + if ( rc == WAIT_OBJECT_0+1 ) /* message arrived */ + { MSG msg; + + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { TranslateMessage(&msg); + DispatchMessage(&msg); + if ( PL_handle_signals() < 0 ) + { errno = EINTR; /* exception */ + return -1; + } + } + } + + goto retry; + } + + errno = EWOULDBLOCK; + LeaveCriticalSection(&pipe->mutex); + + return -1; +} + + +static int +reader_close_pipe(pipe *p) +{ ISPIPE(p); + p->readers--; + + if ( p->readers <= 0 && p->writers <= 0 ) + return destroy_pipe(p); + + return 0; +} + + +static int +writer_close_pipe(pipe *p) +{ ISPIPE(p); + p->writers--; + + if ( p->readers <= 0 && p->writers <= 0 ) + return destroy_pipe(p); + if ( p->writers <= 0 ) + { SetEvent(p->event); /* Signal EOF */ + } + + return 0; +} + + +static IOFUNCTIONS pipe_read_functions = +{ (Sread_function) read_pipe, + (Swrite_function) write_pipe, + (Sseek_function) 0, + (Sclose_function) reader_close_pipe, + (Scontrol_function) 0 +}; + + +static IOFUNCTIONS pipe_write_functions = +{ (Sread_function) read_pipe, + (Swrite_function) write_pipe, + (Sseek_function) 0, + (Sclose_function) writer_close_pipe, + (Scontrol_function) 0 +}; + + +static foreign_t +tcp_pipe(term_t in, term_t out) +{ pipe *p = create_pipe(4096, TRUE); + IOSTREAM *sin, *sout; + + sin = Snew(p, SIO_FBUF|SIO_INPUT|SIO_RECORDPOS, &pipe_read_functions); + p->readers++; + sout = Snew(p, SIO_FBUF|SIO_OUTPUT|SIO_RECORDPOS, &pipe_write_functions); + p->writers++; + + if ( !PL_unify_stream(in, sin) || + !PL_unify_stream(out, sout) ) + { Sclose(sin); + Sclose(sout); + + return FALSE; + } + + return TRUE; +} + +#else /*__WINDOWS__*/ + +static foreign_t +tcp_pipe(term_t Read, term_t Write) +{ int fd[2]; + IOSTREAM *in, *out; + + if ( pipe(fd) != 0 ) + return pl_error("pipe", 2, NULL, ERR_ERRNO, errno, "create", "pipe", 0); + + in = Sfdopen(fd[0], "r"); + out = Sfdopen(fd[1], "w"); + + if ( PL_unify_stream(Read, in) && + PL_unify_stream(Write, out) ) + return TRUE; + + Sclose(in); + Sclose(out); + + return FALSE; +} + +#endif /*__WINDOWS__*/ + +install_t +install_winpipe() +{ PL_register_foreign("tcp_pipe", 2, tcp_pipe, 0); +}