wvstreams-4.6.1/0000755000175000001440000000000011260431131012562 5ustar wlachuserswvstreams-4.6.1/configure.ac0000644000175000001440000004072411260430767015075 0ustar wlachusers# Process this file with autoconf to produce a configure script. AC_INIT(WvStreams, 4.6.1, wvstreams-devel@googlegroups.com, wvstreams) SO_VERSION=4.6 # append to a variable without introducing superfluous white space AC_DEFUN([WV_APPEND],[ if test -z "$$1"; then $1="$2" else $1="$$1 $2" fi ]) QT_SEARCH_PATH=" $prefix /usr $libdir/qt-3.1 $libdir/qt3 $libdir/qt $datadir/qt3 $datadir/qt /usr /usr/lib/qt3 /usr/lib/qt-3.1 /usr/share/qt3 /usr/lib/qt /usr/share/qt " AC_CONFIG_SRCDIR(streams/wvstream.cc) AC_ARG_ENABLE(debug, AC_HELP_STRING([--disable-debug], [strip debug information])) AC_ARG_ENABLE(fatal-warnings, AC_HELP_STRING([--enable-fatal-warnings], [turn warnings into errors])) AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [optimization options])) AC_ARG_ENABLE(resolver-fork, AC_HELP_STRING([--disable-resolver-fork], [WvResolver background name resolution (debugging)])) AC_ARG_ENABLE(delete-detector, AC_HELP_STRING([--enable-delete-detector], [Delete detector (reference counting)])) AC_ARG_ENABLE(warnings, AC_HELP_STRING([--disable-warnings], [extra warnings])) AC_ARG_ENABLE(testgui, AC_HELP_STRING([--disable-testgui], [GUI for unit tests])) AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus], [DBUS])) AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl], [OpenSSL >= 0.9.7 (required)])) AC_ARG_WITH(pam, AC_HELP_STRING([--with-pam], [PAM])) AC_ARG_WITH(tcl, AC_HELP_STRING([--with-tcl], [Tcl])) AC_ARG_WITH(qt, AC_HELP_STRING([--with-qt], [Qt])) AC_ARG_WITH(zlib, AC_HELP_STRING([--with-zlib], [zlib (required)])) AC_ARG_WITH(valgrind, AC_HELP_STRING([--with-valgrind], [Valgrind])) AC_ARG_VAR(MOC, [Qt meta object compiler]) AC_ARG_VAR(WEAVER_BUILD_INFO, [Extra version info]) # avoid autoconf's default values, but keep those the user might have given CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" AC_PROG_CC AC_PROG_CXX AC_PROG_CPP AC_PROG_CXXCPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_RANLIB # Detect target build environment AC_CANONICAL_TARGET case "$target" in *-linux*) ARCH_SUBDIRS="linuxstreams" OS="LINUX" ;; *-sunos*|*-solaris*) ARCH_SUBDIRS="" ac_libs="-lstdc++ -lgcc_s -ldl -lm -lc" OS="SOLARIS" ;; *-win*|*-mingw32*) ARCH_SUBDIRS="win32" OS="WIN32" ;; *-apple*) ARCH_SUBDIRS="" OS="MACOS" ;; *) ARCH_SUBDIRS="" OS="OTHER" ;; esac AC_SUBST(target) AC_SUBST(ARCH_SUBDIRS) AC_SUBST(OS) # Detect endianness AC_C_BIGENDIAN # Look for __attribute__ ((deprecated)) CPPFLAGS_save="$CPPFLAGS" WV_APPEND(CPPFLAGS, -Werror) AC_MSG_CHECKING(for __attribute__ ((deprecated))) AC_COMPILE_IFELSE( [#include "confdefs.h" void f() __attribute__ ((deprecated)); void f() { } int main() { return 0; } ], [AC_MSG_RESULT([yes]) AC_DEFINE([ATTR_DEPRECATED], [__attribute__ ((deprecated))], [Compiler warning on deprecated functions])], [AC_MSG_RESULT([no]) AC_DEFINE([ATTR_DEPRECATED], [], [Compiler warning on deprecated functions])]) CPPFLAGS="$CPPFLAGS_save" # argp USE_WVSTREAMS_ARGP=0 AC_CHECK_HEADERS(argp.h) AC_CHECK_FUNC(argp_parse) if test "$ac_cv_func_argp_parse" != yes \ -o "$ac_cv_header_argp_h" != yes ; then ( echo echo 'configuring argp...' cd argp ./configure --host=$host_cpu-$host_os || exit $? echo 'argp configured.' echo ) || exit $? USE_WVSTREAMS_ARGP=1 fi # Function checks AC_HEADER_DIRENT AC_FUNC_ALLOCA AC_CHECK_HEADERS(execinfo.h) # Check for error_t AC_CHECK_HEADERS([argz.h errno.h]) AC_CHECK_TYPE(error_t,, [AC_DEFINE([error_t], [int], [Define to a type to use for `error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])],dnl ` [#if HAVE_ARGZ_H # include #else # if HAVE_ERRNO_H # include # endif #endif]) # Check for size of ethernet addresses AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([net/if.h], [], [], [#include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif ]) AC_CHECK_HEADERS([net/ethernet.h], [], [], [#include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif ]) AC_CHECK_HEADERS([netinet/if_ether.h], [], [], [#include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_IF_H # include #endif ]) AC_CHECK_DECL(ETHER_ADDR_LEN,, AC_CHECK_TYPE(ether_addr_t, AC_DEFINE([ETHER_ADDR_LEN], [sizeof(ether_addr_t)], [Size of ethernet address]), AC_DEFINE([ETHER_ADDR_LEN], [6]), [#include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif ]), [#include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif ]) # Check for basic Internet support AC_CHECK_HEADERS([netdb.h]) AC_CHECK_HEADERS([netinet/in.h]) AC_CHECK_HEADERS([netinet/in_systm.h]) AC_CHECK_HEADERS([netinet/ip.h], [], [], [#include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IN_SYSTM_H # include #endif ]) AC_CHECK_HEADERS([netinet/tcp.h]) # Check for advanced Linux-style modem support AC_CHECK_HEADERS([linux/serial.h]) AC_CHECK_FUNCS([cfmakeraw]) # Detect hard-linking based on LN_S's behaviour AC_MSG_CHECKING([whether ln works...]) case "$LN_S" in ln*) LN='ln' AC_MSG_RESULT([yes]) ;; *) LN="$LN_S" AC_MSG_RESULT([no, using $LN]) ;; esac AC_SUBST(LN) # Setting the default language to C++ means that CXX and CXXCPP will be # used for compile tests. AC_LANG(C++) # __libc_stack_end isn't available to shared libraries with some libc versions AC_MSG_CHECKING([whether __libc_stack_end is public]) AH_TEMPLATE([HAVE_LIBC_STACK_END], [Whether libc supports __libc_stack_end]) LDFLAGS_save="$LDFLAGS" WV_APPEND(LDFLAGS, [-Wl,-z,defs -shared]) HAVE_LIBC_STACK_END=no AC_TRY_LINK([extern const void *__libc_stack_end; ], [volatile const void *x = __libc_stack_end; ], [HAVE_LIBC_STACK_END=yes; ]) if test "$HAVE_LIBC_STACK_END" = "yes"; then AC_DEFINE([HAVE_LIBC_STACK_END]) fi AC_MSG_RESULT([$HAVE_LIBC_STACK_END]) LDFLAGS="$LDFLAGS_save" # Detect pkg-config AC_PATH_PROG([PKGCONFIG], [pkg-config], [no]) if test "$PKGCONFIG" = "no"; then AC_MSG_WARN([pkg-config is not installed]) fi if test "$enable_debug" != "no"; then AC_DEFINE_UNQUOTED(VER_STRING_EXTRA, [" (`whoami`@`hostname`$VER_STRING_EXTRA)"], [Extra version string.]) fi # resolver-fork if test "$enable_resolver_fork" = "no"; then AC_DEFINE(WVRESOLVER_SKIP_FORK,, [Define to disable WvResolver forking for debugging with gdb.]) fi # xplc delete detector if test "$enable_delete_detector" = "yes"; then AC_DEFINE(ENABLE_DELETE_DETECTOR,, [Define to enable the XPLC delete detector.]) fi # dbus if test "$with_dbus" != "no"; then if test "$with_dbus" = "" -o "$with_dbus" = "yes"; then AC_MSG_CHECKING([Checking that D-Bus version greater than 1.2.14 installed.]) if pkg-config --atleast-version 1.2.14 dbus-1; then WV_APPEND(CPPFLAGS, [`pkg-config --cflags dbus-1`]) WV_APPEND(LDFLAGS, [`pkg-config --libs-only-L dbus-1`]) LIBS_DBUS=`pkg-config --libs-only-l dbus-1` AC_MSG_RESULT([yes]) else with_dbus=no AC_MSG_RESULT([no]) fi else # no version check when doing --with-dbus DBUS_LIBDIR=$with_dbus/dbus/.libs WV_APPEND(CPPFLAGS, -I$with_dbus) WV_APPEND(LDFLAGS, -L$DBUS_LIBDIR) LIBS_DBUS=-ldbus-1 fi # ... but double check that we actually have D-Bus if test "$with_dbus" != "no"; then OLD_LIBS="$LIBS" WV_APPEND(LIBS, $LIBS_DBUS) AC_CHECK_HEADERS(dbus/dbus.h,, [with_dbus=no]) with_dbus=no AC_TRY_LINK([extern "C" void dbus_message_new(); ], [dbus_message_new(); ], [with_dbus=]) LIBS=$OLD_LIBS fi if test "$with_dbus" != "no"; then AC_DEFINE(WITH_DBUS,, [Define to enable DBUS support.]) fi fi # BSD sockets, if you're on Solaris AC_CHECK_LIB(socket, bind) # openssl if test "$with_openssl" != "no"; then if test "$with_openssl" != ""; then WV_APPEND(CPPFLAGS, [-I$with_openssl/include]) WV_APPEND(LDFLAGS, [-L$with_openssl]) fi AC_CHECK_HEADERS(openssl/ssl.h,, [with_openssl=no], [#define OPENSSL_NO_KRB5]) LIBS_save="$LIBS" AC_CHECK_LIB(crypto, X509_free) AC_CHECK_LIB(ssl, SSL_has_matching_session_id,, [with_openssl=no]) AC_CHECK_LIB(ssl, POLICY_MAPPING_new,, [with_openssl_policy_mapping=no]) if test "$with_openssl_policy_mapping" != "no"; then AC_DEFINE([HAVE_OPENSSL_POLICY_MAPPING], [1], [Whether libssl has the POLICY_MAPPING features (0.9.8 and up)]) fi LIBS="$LIBS_save" if test "$with_openssl" != "no"; then LIBS_SSL="-lcrypto -lssl" fi fi # readline if test "$with_readline" != "no"; then AC_CHECK_HEADERS(readline/readline.h,, [with_readline=no]) AC_CHECK_LIB(readline, readline,, [with_readline=no]) fi # pam if test "$with_pam" != "no"; then AC_CHECK_HEADERS(security/pam_appl.h,, [with_pam=no]) LIBS_save="$LIBS" AC_CHECK_LIB(pam, pam_start,, [with_pam=no]) AC_MSG_CHECKING(for sane PAM implementation) AC_COMPILE_IFELSE( [#include "confdefs.h" #if HAVE_SECURITY_PAM_APPL_H # include #endif /* noconv: null PAM conversation function */ int noconv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *userdata) { // if you need to ask things, it won't work return PAM_CONV_ERR; } int main() { struct pam_conv c; c.conv = noconv; return 0; } ], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_BROKEN_PAM], [0])], [AC_MSG_RESULT([no]) AC_DEFINE([HAVE_BROKEN_PAM], [1], [Solaris has a broken PAM implementation])]) LIBS="$LIBS_save" if test "$with_pam" != "no" -a "$HAVE_BROKEN_PAM" != "1"; then LIBS_PAM=-lpam fi fi # tcl if test "$with_tcl" != "no"; then CPPFLAGS_save="$CPPFLAGS" WV_APPEND(CPPFLAGS, -I/usr/include/tcl8.3) AC_CHECK_HEADERS(tcl.h,, [with_tcl=no]) LIBS_save="$LIBS" AC_CHECK_LIB(tcl8.3, TclInterpInit,, [with_tcl=no]) LIBS="$LIBS_save" if test "$with_tcl" != "no"; then CPPFLAGS="$CPPFLAGS_save" LIBS_TCL=-ltcl8.3 fi fi # qt if test "$with_qt" != "no"; then test "$with_qt" = yes && with_qt= AC_CACHE_CHECK([for Qt], [wv_cv_with_qt], [ wv_cv_with_qt=no CPPFLAGS_save="$CPPFLAGS" LDFLAGS_save="$LDFLAGS" LIBS_save="$LIBS" for wv_qtdir in $with_qt $QTDIR $QT_SEARCH_PATH $(pkg-config --variable=prefix qt-mt); do eval wv_qtdir="$wv_qtdir" CPPFLAGS="$CPPFLAGS_save -I$wv_qtdir/include -I$wv_qtdir/include/qt3" LDFLAGS="$LDFLAGS_save -L$wv_qtdir/lib" LIBS="$LIBS_save -lqt-mt" AC_TRY_LINK([#include ], [QString x("hello"); return 0; ], [wv_cv_with_qt=$wv_qtdir; break]) done CPPFLAGS="$CPPFLAGS_save" LDFLAGS="$LDFLAGS_save" LIBS="$LIBS_save" ]) with_qt=$wv_cv_with_qt if test "$with_qt" != no; then WV_APPEND(CPPFLAGS, -I$with_qt/include -I$with_qt/include/qt3) if test "$wv_qtdir" != "/usr" ; then # never explicitly include /usr/lib WV_APPEND(LDFLAGS, -L$with_qt/lib) fi WV_APPEND(LIBS_QT, -lqt-mt) fi AC_PATH_PROG(MOC, moc, [moc not found], $with_qt/bin) fi # valgrind if test "$with_valgrind" != "no"; then AC_CHECK_PROG(VALGRIND, valgrind, valgrind) AC_CHECK_HEADERS(valgrind/memcheck.h) fi # zlib if test "$with_zlib" != "no"; then AC_CHECK_HEADERS(zlib.h,, [with_zlib=no]) AC_CHECK_LIB(z, compress,, [with_zlib=no]) fi # Find out whether TR1 or Boost are available. AC_CHECK_HEADERS(tr1/functional) AC_CHECK_HEADERS(boost/function.hpp) # When compiling with exceptions disabled and Boost, applications need # to provide an "exception handler", declared here. AC_CHECK_HEADERS(boost/throw_exception.hpp) # check for missing packages missing_required= missing_devel= if test "$with_dbus" = "no"; then AC_MSG_WARN([DBUS is missing.]) missing_devel=yes fi if test "$with_pam" = "no"; then AC_MSG_WARN([PAM is missing.]) missing_devel=yes fi if test "$with_qt" = "no"; then AC_MSG_WARN([Qt is missing.]) missing_devel=yes fi if test "$VALGRIND" = ""; then AC_MSG_WARN([Valgrind is missing.]) fi if test "$with_openssl" = "no"; then AC_MSG_WARN([OpenSSL is missing.]) missing_required="$missing_required OpenSSL>=0.9.7" fi if test "$with_readline" = "no"; then AC_MSG_WARN([readline is missing.]) fi if test "$with_zlib" = "no"; then AC_MSG_WARN([zlib is missing.]) missing_required="$missing_required zlib" fi if test "$ac_cv_header_tr1_functional" != "yes" \ -a "$ac_cv_header_boost_function_hpp" != "yes"; then AC_MSG_WARN([both tr1/functional and boost/function.hpp are missing.]) missing_required="$missing_required boost/function.hpp" fi if test -n "$missing_required"; then AC_MSG_ERROR([Required dependencies missing:$missing_required]) fi if test "$VALGRIND" != ""; then VALGRIND="valgrind --tool=memcheck --leak-check=yes --num-callers=10 --suppressions=\$(WVSTREAMS_SRC)/wvstreams.supp" if valgrind --help | grep log-file >/dev/null; then VALGRIND="$VALGRIND --log-file=valgrind.log" else VALGRIND="$VALGRIND --logfile=valgrind.log" fi fi # Compiler is always posix if invoking this configure script COMPILER_STANDARD=posix AC_SUBST(SO_VERSION) AC_SUBST(USE_WVSTREAMS_ARGP) AC_SUBST(enable_debug) AC_SUBST(enable_optimization) AC_SUBST(enable_resolver_fork) AC_SUBST(enable_delete_detector) AC_SUBST(enable_warnings) AC_SUBST(enable_testgui) AC_SUBST(with_dbus) AC_SUBST(with_openssl) AC_SUBST(with_openssl_policy_mapping) AC_SUBST(with_pam) AC_SUBST(with_readline) AC_SUBST(with_qt) AC_SUBST(with_tcl) AC_SUBST(with_zlib) AC_SUBST(LIBS_DBUS) AC_SUBST(LIBS_QT) AC_SUBST(LIBS_PAM) AC_SUBST(LIBS_TCL) AC_SUBST(ac_libs) AC_SUBST(COMPILER_STANDARD) AC_DEFINE_UNQUOTED([VERBOSE_PACKAGE_VERSION],["$PACKAGE_VERSION$WEAVER_BUILD_INFO"],[Verbose package version]) AC_CONFIG_FILES(config.mk) AC_CONFIG_FILES([pkgconfig/libuniconf.pc pkgconfig/libuniconf-uninstalled.pc pkgconfig/libwvbase.pc pkgconfig/libwvbase-uninstalled.pc pkgconfig/libwvdbus.pc pkgconfig/libwvdbus-uninstalled.pc pkgconfig/libwvqt.pc pkgconfig/libwvqt-uninstalled.pc pkgconfig/libwvstreams.pc pkgconfig/libwvstreams-uninstalled.pc pkgconfig/libwvutils.pc pkgconfig/libwvutils-uninstalled.pc pkgconfig/libwvtest.pc pkgconfig/libwvtest-uninstalled.pc]) AC_CONFIG_HEADERS(include/wvautoconf.h) AC_OUTPUT # Now convert PACKAGE_* macros into WVPACKAGE_* in include/wvautoconf.h sed 's,\(\#define.*\)PACKAGE,\1WVPACKAGE,' include/wvautoconf.h > include/wvautoconf.h.new if test "x$?" = "x0"; then if ! diff include/wvautoconf.h include/wvautoconf.h.new >/dev/null; then mv include/wvautoconf.h.new include/wvautoconf.h else rm include/wvautoconf.h.new fi fi wvstreams-4.6.1/configfile/0000755000175000001440000000000011260431126014673 5ustar wlachuserswvstreams-4.6.1/configfile/tests/0000755000175000001440000000000011260431131016031 5ustar wlachuserswvstreams-4.6.1/configfile/tests/delsectiontest.cc0000644000175000001440000000074211036722347021411 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Deletes a section from a config file. Useful when netmaps are too big. * */ #include "wvconf.h" int main( int argc, char ** argv ) /********************************/ { if (argc != 3) { fprintf( stderr, "Usage: %s cfgfilename section\n", argv[0] ); return( -1 ); } WvConf cfg( argv[1] ); cfg.delete_section( argv[2] ); return( 0 ); } wvstreams-4.6.1/configfile/tests/testfile.ini0000644000175000001440000002701111036722347020367 0ustar wlachusers [windows] NullPort = None device = HP DeskJet 500,HPDSKJET,LPT1: FooPort = testywesty [Desktop] Wallpaper = C:\WINDOWS\FOREST.BMP TileWallpaper = 1 WallpaperStyle = 0 Pattern = (None) [intl] iCountry = 2 ICurrDigits = 2 iCurrency = 0 iDate = 1 iDigits = 2 iLZero = 1 iMeasure = 0 iNegCurr = 1 iTime = 0 iTLZero = 0 s1159 = AM s2359 = PM sCountry = Canada sCurrency = $ sDate = / sDecimal = . sLanguage = enc sList = , sLongDate = MMMM d, yyyy sShortDate = dd/MM/yy sThousand = , sTime = : [fonts] [FontSubstitutes] Helv = MS Sans Serif Tms Rmn = MS Serif Times = Times New Roman Helvetica = Arial MS Shell Dlg = MS Sans Serif [Compatibility] _3DPC = 0x00400000 _BNOTES = 0x224000 _LNOTES = 0x00100000 ACAD = 0x8000 ACT! = 0x400004 ACROBAT = 0x04000000 ADW30 = 0x10000000 ALARMMGR = 0x0040000 ALDSETUP = 0x00400000 AMIPRINT = 0x04000000 AMIPRO = 0x04000010 APORIA = 0x0100 APPROACH = 0x0004 BALER = 0x08000000 BMAPP = 0x0004 CASMONEY = 0x00200000 CAVOIDE = 0x00200000 CCMAIL = 0x00200000 CCMCWFY = 0x80 CHARISMA = 0x2000 CONFIG = 0x00400000 CORELDRW = 0x48000 CORELPNT = 0x08000000 COSTAR = 0x0004 CROSSTIE = 0x00000400 DARCH = 0x80 DESIGNER = 0x00002000 DIRECTOR = 0x00800000 DPLANNER = 0x00200000 DRAW = 0x2000 DS40 = 0x8000 DTWIN20 = 0x00000400 EAP = 0x0004 EXCEL = 0x1000 EXPASTRO = 0x04000000 EXTYPWND = 0x00200000 FAXVIEW = 0x04000000 FAXWORKS = 0x00000400 FH4 = 0x00E08000 FLW2 = 0x8000 FMPRO = 0x00200000 FREEHAND = 0x8000 FULLTEXT = 0x20000000 GIFTMAKE = 0x20000000 GUIDE = 0x1000 HDW = 0x04800000 HGW = 0x8000 HGW2EXE = 0x8000 HGW3EXE = 0x8000 HJDRAW = 0x00400000 IDAPICFG = 0x00400000 IDRAW = 0x04008000 ILLUSTRATOR = 0x8000 IMPROV2 = 0x00000000 INFOCENT = 0x04000000 INSIGHT = 0x00000400 INSTAL1 = 0x00400000 INSTALL = 0x00400000 INTERMIS = 0x10000000 IS20INST = 0x00000000 IVIHEALT = 0x00400000 JEOPARDY = 0x00200000 KALOAD2 = 0x00400000 KEYCAD = 0x8000 LE_ADMIN = 0x00400000 LUI = 0x20000000 MAILSPL = 0x10000000 MAKER = 0x00200000 MAPS1 = 0x04008022 MATH = 0x00000001 MAVIS = 0x00200000 MCOURIER = 0x0800 MFWIN20 = 0x02000000 MILESV3 = 0x1000 MILESV40 = 0x4 MOZART = 0x40000000 MSARTIST = 0x00100000 MSBHUMAN = 0x4 MSREMIND = 0x10000000 MVIEWER2 = 0x40200000 MYINV = 0x00200000 MYST = 0x08000000 NAFTA1 = 0x4008022 NBAMW4V4 = 0x04000000 NETSET2 = 0x0100 NOTES = 0x200000 NOTSHELL = 0x0001 OPERATOR = 0x02000000 OUTPOST = 0x00000000 OWLAPP = 0x00400000 PACKRAT = 0x0800 PAINTER = 0x00000000 PAWC8DC3 = 0x00400000 PAWIN = 0x4 PEACHW = 0x04800004 PIXIE = 0x0040 PLANIT = 0x0004 PLANNER = 0x2000 PLUS = 0x1000 PM4 = 0xA000 PM5APP = 0x8000 PP4 = 0x00000000 PR2 = 0x2000 PRINTHLP = 0x0004 QAPLUSW = 0x0004 QLIIFAX = 0x00400000 QUAKE = 0x80 RELAY = 0x20000000 REM = 0x8022 RR2CD = 0x00200000 RXL = 0x00000400 SETUP = 0x00000000 SIDEKICK = 0x0004 SLEEPER = 0x10000000 SPCB = 0x04008000 SPORTJEP = 0x00200000 SPWIN20 = 0x00400000 ST2 = 0x4008022 STRAUSS = 0x40000000 STRAV = 0x40000000 SCHUBERT = 0x40000000 SSBWIN = 0x00200000 SWCWIN = 0x00800004 TCVWIN = 0x00200000 TCW = 0x00400000 TCWIN = 0x0004 TERRAIN = 0x00400000 TISETUP = 0x00200000 TL6 = 0x08000000 TME = 0x0100 TMSWIN = 0x20000000 TMTWIN = 0x00200000 TMTWINCD = 0x00200000 TOUCHUP = 0x00400000 TURBOTAX = 0x00080000 VEWINFIL = 0x00400000 VISIO = 0x00000004 VISIOHM = 0x00000004 VISION = 0x0040 W4GL = 0x4000 W4GLR = 0x4000 WGW = 0x00440000 WINCIM = 0x4 WINLINK = 0x20000000 WINPHONE = 0x0004 WINSIM = 0x2000 WINTACH = 0x00200000 WORDSCAN = 0x02200000 WPWIN60 = 0x00000400 WPWIN61 = 0x02000400 WSETUP = 0x00200000 XPRESS = 0x00000008 ZETA01 = 0x00400000 ZIFFBOOK = 0x00200000 [Compatibility32] CLWORKS = 0x00A00000 MCAD = 0x00600000 PODW = 0x00200000 SPSSWIN = 0x00200000 TYPSTRY2 = 0x00200000 V32VM20 = 0x02000000 VISIO = 0x00000000 VISIOHM = 0x00000000 WINPHONE = 0x00000004 WRDART32 = 0x00400000 [mci extensions] mid = Sequencer rmi = Sequencer wav = waveaudio avi = AVIVideo MPG = MPEGVIDEO DAT = MPEGVIDEO MPA = MPEGVIDEO MPV = MPEGVIDEO [MCICompatibility] QTWVideo = 0x0001 MCIXSND = 0x0001 GDAnim = 0x0001 [mciavi] [ModuleCompatibility] ACEROOBE = 0x0004 AIRNFM = 0x0002 ALDNCD = 0x0002 AMRES = 0x0002 ATM = 0x0002 ARCHANGEL = 0x0002 CSNOV = 0x0002 DEFDEMO = 0x0002 DIBWND = 0x0002 DIB = 0x0002 EMLIB = 0x0002 EMSAVE = 0x0002 FH4 = 0x0002 GEDIT = 0x0002 GEORGE = 0x0002 GVBSETUP = 0x0002 HRWCD = 0x0002 ISLFAXPR = 0x0002 KIDDESK = 0x0002 KIDSTYPE = 0x0000 KNPS = 0x0002 LIONKING = 0x0002 MAUI_DRV = 0x0002 MGXWMF = 0x0002 MEMMAP = 0x0002 MSARTIST = 0x0002 MSCRWRTR = 0x0002 MSCUISTF = 0x0001 MVIEWER2 = 0x0002 MWAVSCAN = 0x0002 MYINV = 0x0002 OLESVR = 0x0002 PDOXWIN = 0x0002 PLANIT = 0x0002 PP3 = 0x0002 PP4 = 0x0002 PPPP = 0x0002 PXDSRV2 = 0x0002 REVIEWRT = 0x0002 ROULETTE = 0x0002 RRIRJ = 0x0002 RR1 = 0x0002 RR2CD = 0x0002 STL_DLG = 0x0002 TECO = 0x0001 TER = 0x0002 TLW0LOC = 0x0002 TMSWIN = 0x0002 USA = 0x0002 VOICE = 0x0002 WFXVIEW = 0x0004 WINFORM = 0x0002 WPWIN61 = 0x0002 [Pscript.Drv] ATMWorkaround = 1 [Extensions] txt = notepad.exe ^.txt bmp = C:\Progra~1\Access~1\mspaint.exe ^.bmp pcx = C:\Progra~1\Access~1\mspaint.exe ^.pcx set = C:\UTILS\TAPE\QBWIN\QBWIN.EXE ^.set ;line added by Arcada Backup wcm = c:\office\shared\wpc20\mfwin20.exe /# /m= ^.wcm wch = c:\office\shared\wpc20\mfwin20.exe /# /m= ^.wch IDE = BCW.EXE ^.IDE mov = C:\WINDOWS\PLAY32.EXE ^.mov pic = C:\WINDOWS\VIEW32.EXE ^.pic WB1 = C:\COREL\OFFICE7\QUATTRO7\QPW.EXE ^.WB1 WB2 = C:\COREL\OFFICE7\QUATTRO7\QPW.EXE ^.WB2 WB3 = C:\COREL\OFFICE7\QUATTRO7\QPW.EXE ^.WB3 psd = C:\PHOTOSHP\photoshp.exe ^.psd [Ports] COM1: = 9600,n,8,1,x COM2: = 9600,n,8,1,x COM3: = 9600,n,8,1,x COM4: = 9600,n,8,1,x [embedding] AVIFile = Video Clip,Video Clip,C:\WINDOWS\mplayer.exe /avi,picture Package = Package,Package,packager.exe,picture PBrush = Paintbrush Picture,Paintbrush Picture,C:\PROGRA~1\ACCESS~1\MSPAINT.EXE,picture Paint.Picture = Bitmap Image,Bitmap Image,C:\PROGRA~1\ACCESS~1\MSPAINT.EXE,picture SoundRec = Wave Sound,Wave Sound,C:\WINDOWS\sndrec32.exe,picture mplayer = Media Clip,Media Clip,C:\WINDOWS\mplayer.exe,picture midfile = MIDI Sequence,MIDI Sequence,C:\WINDOWS\mplayer.exe /mid,picture Wordpad.Document.1 = WordPad Document,WordPad Document,C:\PROGRA~1\ACCESS~1\WORDPAD.EXE,picture WPWin6.1 = WordPerfect Document (6.1),WordPerfect Document (6.1),c:\office\wpwin\WPWIN.EXE,picture WPWin6.0 = WordPerfect Document (6.0),WordPerfect Document (6.0),c:\office\wpwin\WPWIN.EXE,picture WPWin6.1File = WordPerfect Document (6.1) File,WordPerfect Document (6.1) File,c:\office\wpwin\WPWIN.EXE,picture TextArt.Document = TextArt 2.0 Document,TextArt 2.0 Document,c:\office\shared\textart\TEXTART.EXE,picture PhotoStylerImage = PhotoStyler Image,PhotoStyler Image,C:\PROGRA~1\PS2_SE\PSTYLER.EXE,picture CorelDRAW.Graphic.6 = CorelDRAW 6.0 Graphic,CorelDRAW 6.0 Graphic,E:\COREL6\PROGRAMS\CORELDRW.EXE,picture CorelDraw.CMX.6 = CorelDRAW 6.0 Exchange Graphic,CorelDRAW 6.0 Exchange Graphic,E:\COREL6\PROGRAMS\CORELDRW.EXE,picture CDraw5 = CorelDRAW 5.0 Graphic,CorelDRAW 5.0 Graphic,E:\COREL6\PROGRAMS\CORELDRW.EXE,picture CDraw4 = CorelDRAW 4.0 Graphic,CorelDRAW 4.0 Graphic,E:\COREL6\PROGRAMS\CORELDRW.EXE,picture CDraw = CorelDRAW Graphic,CorelDRAW Graphic,E:\COREL6\PROGRAMS\CORELDRW.EXE,picture CorelEquation = Corel Equation 1.0 Equation,Corel Equation 1.0 Equation,"e:\corel6\PROGRAMS\CORELEQN.EXE",picture CorelPhotoPaint.Image.6 = Corel PHOTO-PAINT 6.0 Image,Corel PHOTO-PAINT 6.0 Image,"e:\corel6\PROGRAMS\PHOTOPNT.EXE",picture CPaint5 = Corel PHOTO-PAINT 5.0 Image,Corel PHOTO-PAINT 5.0 Image,"e:\corel6\PROGRAMS\PHOTOPNT.EXE",picture CPaint4 = Corel PHOTO-PAINT 4.0 Picture,Corel PHOTO-PAINT 4.0 Picture,"e:\corel6\PROGRAMS\PHOTOPNT.EXE",picture PhotoPaint = Corel PHOTO-PAINT Picture,Corel PHOTO-PAINT Picture,"e:\corel6\PROGRAMS\PHOTOPNT.EXE",picture PlayerFrameClass = QuickTime Movie,QuickTime Movie,c:\windows\play32.exe,picture ViewerFrameClass = QuickTime Picture,QuickTime Picture,c:\windows\view32.exe,picture WP7Doc = WordPerfect 7 Document,WordPerfect 7 Document,c:\Corel\Office7\WPWin7\WPWIN.EXE,picture Textart7.Document = Textart 7 Document,Textart 7 Document,c:\Corel\Office7\Shared\TextArt7\TEXTART.EXE,picture QuattroProGraph = Quattro Pro Graph,Quattro Pro Graph,C:\COREL\OFFICE7\QUATTRO7\QPW.EXE,picture QuattroProNotebook = Quattro Pro Notebook,Quattro Pro Notebook,C:\COREL\OFFICE7\QUATTRO7\QPW.EXE,picture QuattroPro.Chart.7 = Quattro Pro 7 Chart,Quattro Pro 7 Chart,C:\COREL\OFFICE7\QUATTRO7\QPW.EXE,picture NetscapeMarkup = Netscape Hypertext Document,Netscape Hypertext Document,C:\PROGRA~1\NETSCAPE\NAVIGA~1\PROGRAM\NETSCAPE.EXE,picture Mathcad = Mathcad PLUS 6.0,Mathcad PLUS 6.0,E:\WINMCAD\MCAD.EXE,picture Word.Document.6 = Microsoft Word Document,Microsoft Word Document,E:\MSWORKS\WINWORD\WINWORD.EXE,picture Word.Picture.6 = Microsoft Word Picture,Microsoft Word Picture,E:\MSWORKS\WINWORD\WINWORD.EXE,picture WordDocument = Microsoft Word 2.0 Document,Microsoft Word 2.0 Document,E:\MSWORKS\WINWORD\WINWORD.EXE,picture Excel.Chart.5 = Microsoft Excel Chart,Microsoft Excel Chart,E:\MSWORKS\EXCEL\excel.exe,picture ExcelChart = Microsoft Excel Chart,Microsoft Excel Chart,E:\MSWORKS\EXCEL\excel.exe,picture ExcelMacrosheet = Microsoft Excel 4.0 Macro,Microsoft Excel 4.0 Macro,E:\MSWORKS\EXCEL\excel.exe,picture Excel.Sheet.5 = Microsoft Excel Worksheet,Microsoft Excel Worksheet,E:\MSWORKS\EXCEL\excel.exe,picture ExcelWorksheet = Microsoft Excel Worksheet,Microsoft Excel Worksheet,E:\MSWORKS\EXCEL\excel.exe,picture CorelDraw.Graphic.7 = CorelDRAW 7.0 Graphic,CorelDRAW 7.0 Graphic,D:\COREL\DRAW70\PROGRAMS\CORELDRW.EXE,picture CorelDraw.CMX.7 = CorelDRAW 7.0 Exchange Graphic,CorelDRAW 7.0 Exchange Graphic,D:\COREL\DRAW70\PROGRAMS\CORELDRW.EXE,picture [Devices] HP DeskJet 500 = HPDSKJET,LPT1: [PrinterPorts] HP DeskJet 500 = HPDSKJET,LPT1:,15,45 [Sounds] SystemDefault = , [colors] Scrollbar = 192 192 192 Background = 0 128 128 ActiveTitle = 128 0 0 InactiveTitle = 128 128 128 Menu = 192 192 192 Window = 255 255 255 WindowFrame = 0 0 0 MenuText = 0 0 0 WindowText = 0 0 0 TitleText = 255 255 255 ActiveBorder = 192 192 192 InactiveBorder = 192 192 192 AppWorkspace = 128 128 128 Hilight = 128 0 0 HilightText = 255 255 255 ButtonFace = 192 192 192 ButtonShadow = 128 128 128 GrayText = 128 128 128 ButtonText = 0 0 0 InactiveTitleText = 192 192 192 ButtonHilight = 255 255 255 ButtonDkShadow = 0 0 0 ButtonLight = 224 224 224 InfoText = 0 0 0 InfoWindow = 255 255 225 [Windows Telephony] TelephonINIChanged = 1996-10-10 09:35:44 [WPCorp-Windows Printer Flags] TTY = 0x00000009 HPDSKJET = 0x00100104 DESKJETC = 0x00100104 HPPCL5C = 0x00000400 HPPCL5E = 0x01000160 HPPCL = 0x00000810 HPPCL5MS = 0x00000100 HPPLOT = 0x00000001 INTLPCL5 = 0x00000100 EPSON24 = 0x00002080 EPL2 = 0x00000080 EPSON9 = 0x00000080 PANSON24 = 0x00000080 PAN24_11 = 0x00000080 PANSCALE = 0x00000080 OKI9 = 0x00000080 WINFAX = 0x00481000 PROPRINT = 0x00000080 IBM4029 = 0x00008000 META_DRV = 0x00004000 PDFWRITR = 0x00020000 ENVOYDRV = 0x00020000 PSCRIPT = 0x00040400 OKI300 = 0x00000100 IJ4076 = 0x00000200 ADOBEPS = 0x01200000 FAXITDRV = 0x00480000 FAXABLTY = 0x00400000 [WordPerfect] MDI Frame Position (X) = -32768 MDI Frame Position (Y) = -32768 MDI Frame Position (CX) = -32768 MDI Frame Position (CY) = -32768 MDI Frame Position (ShowCmd) = 3 [Netscape] ini = C:\INTERNET\NETSCAPE\NETSCAPE.INI [BNClock] UserName = sabrina [DrawDib] pnpdrvr.drv 800x600x16(0) = 37,5,5,5 macxw4.drv 1024x768x16(0) = 37,5,5,5 [SciCalc] layout = 0 [BCW4.0 INSTALL] Reserved1 = D:\BC45 [MSCharMap] Font = NEW CENTURY SCHOOLBOOK [NGME] dir = C:\progra~1\NGME [Windows Help] H_WindowPosition = [341,256,341,256,0] M_WindowPosition = [241,22,681,764,0] [Mathcad] Private-Ini-File = E:\WINMCAD\mcad.ini [TrueType] FontSmoothing = 1 [WinPlay3] ProgramFile = G:\PLAYER20\WINPLAY3.EXE wvstreams-4.6.1/configfile/tests/initest.cc0000644000175000001440000000173111036722347020036 0ustar wlachusers /* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * The test program for the WvConfigFile class. Not to be used in real life. * * Created: Sept 12 1997 D. Coombs * Modified: Sept 21 1997 D. Coombs * */ #include #include "wvconf.h" int main(int argc, char *argv[]) { WvConf cfg("testfile.ini"); const char *test_str; if (!cfg.isok()) return -1; if (argc != 3) { printf("Usage: %s section name\n", argv[0]); return -1; } test_str = cfg.get(argv[1], argv[2], "not there"); printf("%d\n", cfg.getint("intl", "icountry", 5)); printf("%s\n\n", test_str); if (!cfg.isok()) return -1; cfg.set("Windows", "FooPort", "testywesty\n\n\n \n"); if (!cfg.isok()) return -1; WvConfigSection *sect = cfg["fontsubSTitUtES"]; if (sect) sect->dump(*wvcon); puts(""); sect = cfg["should_not_exist"]; return 0; } wvstreams-4.6.1/configfile/tests/nofile.cc0000644000175000001440000000264611036722347017641 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Plays with WvConfigSectionList (without the WvConf file interface wrapper) * */ #include "wvconf.h" int main() { WvConfigSectionList sectlist; sectlist.append(new WvConfigSection("Hello"), true); sectlist.append(new WvConfigSection("Hellooo"), true); sectlist.append(new WvConfigSection("\n# test\n"), true); sectlist.append(new WvConfigSection("aaaa"), true); sectlist.append(new WvConfigSection("bbbb"), true); WvConfigSectionList::Iter zzz(sectlist); zzz.rewind();zzz.next(); WvConfigSection *sect = &*zzz; if(!sect) { printf("crap\n"); return 0; } sect->set("suck", "blah"); sect->set("buck", "more blah"); sect->set("luck", "even more"); sect->set("duck", "bored now"); zzz.rewind(); zzz.next(); sect = &*zzz; WvConfigEntry *luck = (*zzz)["luck"]; if(!!luck) { WvString value = luck->value; value = WvString("DIRTIED! [%s]", value); luck->value = value; printf("Lucky me [%s]\n", luck->value.edit()); } else zzz->quick_set("weeeee", "waaaaah"); zzz->quick_set("weeeee", "ARGH"); printf("--- list everything ---\n"); for(zzz.rewind(); zzz.next(); ) { printf("[%s]\n", zzz->name.edit()); zzz->dump(*wvcon); } printf("------- end list ------\n"); return 0; } wvstreams-4.6.1/configfile/cfgsection.cc0000644000175000001440000000330711036722347017342 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of the WvConfigSection class. * * Created: Sept 28 1997 D. Coombs * */ #include "wvconf.h" WvConfigSection::WvConfigSection(WvStringParm _name) : name(_name) { } WvConfigSection::~WvConfigSection() { // the WvConfigEntryList destructor automatically deletes all its // entries, so no need to worry about doing that. } WvConfigEntry *WvConfigSection::operator[] (WvStringParm ename) { Iter i(*this); for (i.rewind(); i.next();) { if (strcasecmp(i().name, ename) == 0) return &i(); } return NULL; } const char *WvConfigSection::get(WvStringParm entry, const char *def_val) { WvConfigEntry *e = (*this)[entry]; return e ? (const char *)e->value : def_val; } void WvConfigSection::set(WvStringParm entry, WvStringParm value) { WvString clean_entry = entry; trim_string(clean_entry.edit()); WvConfigEntry *e = (*this)[clean_entry]; // need to delete the entry? if (!value || !value[0]) { if (e) unlink(e); return; } // otherwise, add the entry requested if (e) e->set(value); else append(new WvConfigEntry(clean_entry, value), true); } void WvConfigSection::quick_set(WvStringParm entry, WvStringParm value) { WvString clean_entry = entry; trim_string(clean_entry.edit()); append(new WvConfigEntry(clean_entry, value), true); } void WvConfigSection::dump(WvStream &fp) { Iter i(*this); for (i.rewind(); i.next(); ) { WvConfigEntry &e = *i; if (e.value && e.value[0]) fp.print("%s = %s\n", e.name, e.value); else fp.print("%s =\n", e.name); } } wvstreams-4.6.1/configfile/cfgentry.cc0000644000175000001440000000063011036722347017033 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of the WvConfigEntry class. * * Created: Sept 28 1997 D. Coombs * */ #include "wvconf.h" WvConfigEntry::WvConfigEntry() { } WvConfigEntry::WvConfigEntry(WvStringParm _name, WvStringParm _value) : name(_name), value(_value) { } WvConfigEntry::~WvConfigEntry() { } wvstreams-4.6.1/configfile/wvconf.cc0000644000175000001440000003174611036722347016530 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of the WvConfigFile class. * * Created: Sept 12 1997 D. Coombs * */ #include "wvconf.h" #include "wvfile.h" #include "wvstringtable.h" #include #include void WvConf::setbool(void *userdata, WvStringParm sect, WvStringParm ent, WvStringParm oldval, WvStringParm newval) { if (!*(bool *)userdata) { WvLog log("Config Event", WvLog::Debug); if(sect == "Tunnel Vision" && ent == "Magic Password") log("Changed:[%s]%s\n",sect, ent); else log("Changed: [%s]%s = '%s' -> '%s'\n", sect, ent, oldval, newval); } *(bool *)userdata = true; } void WvConf::addname(void *userdata, WvStringParm sect, WvStringParm ent, WvStringParm oldval, WvStringParm newval) { (*(WvStringList *)userdata).append(new WvString(ent), true); } void WvConf::addfile(void *userdata, WvStringParm sect, WvStringParm ent, WvStringParm oldval, WvStringParm newval) { WvFile tmp(WvString("/home/%s/%s", ent, *(WvString *)userdata), O_WRONLY | O_CREAT | O_TRUNC, 0600); if(tmp.isok()) { if(!!newval) tmp.print("%s\n", newval); else tmp.print("%s\n", ent); } } WvConf::WvConf(WvStringParm _filename, int _create_mode) : filename(_filename), log(filename), globalsection("") { create_mode = _create_mode; dirty = error = loaded_once = false; wvauthd = NULL; load_file(); } int WvConf::check_for_bool_string(const char *s) { if (strcasecmp(s, "off") == 0 || strcasecmp(s, "false") == 0 || strncasecmp(s, "no", 2) == 0) // also handles "none" return (0); if (strcasecmp(s, "on") == 0 || strcasecmp(s, "true") == 0 || strcasecmp(s, "yes") == 0) return (1); // not a special bool case, so just return the number return (atoi(s)); } // parse the WvConf string "request"; pointers to the found section, // entry, and value fields are stored in *section, *entry, and *value // respectively, and request[] is modified. // // For example, the string: // [silly]billy=willy // is parsed into: // section="silly"; entry="billy"; value="willy"; // // Returns 0 on success, -1 if the command is missing the '[', -2 if the // string is missing a ']', or -3 if the section or entry is blank. If a // "value" is not found (ie. there is no equal sign outside the [] brackets) // this does not qualify as an error, but *value is set to NULL. // int WvConf::parse_wvconf_request(char *request, char *§ion, char *&entry, char *&value) { //printf("parsing %s\n", request); entry = value = NULL; section = strchr(request, '['); if (!section) return -1; section++; entry = strchr(section, ']'); if (!entry) return -2; *entry++ = 0; value = strchr(entry, '='); if (value) { *value++ = 0; value = trim_string(value); } //printf("section: %s\nentry: %s\n", section, entry); section = trim_string(section); entry = trim_string(entry); if (!*section) return -3; return 0; } // This "int" version of get is smart enough to interpret words like on/off, // true/false, and yes/no. int WvConf::getint(WvStringParm section, WvStringParm entry, int def_val) { WvString def_str(def_val); return check_for_bool_string(get(section, entry, def_str)); } // This "int" version of fuzzy_get is smart enough to interpret words like // on/off, true/false, and yes/no. int WvConf::fuzzy_getint(WvStringList §ion, WvStringList &entry, int def_val) { WvString def_str(def_val); return check_for_bool_string(fuzzy_get(section, entry, def_str)); } // This "int" version of fuzzy_get is smart enough to interpret words like // on/off, true/false, and yes/no. int WvConf::fuzzy_getint(WvStringList §ion, WvStringParm entry, int def_val) { WvString def_str(def_val); return check_for_bool_string(fuzzy_get(section, entry, def_str)); } void WvConf::setint(WvStringParm section, WvStringParm entry, int value) { WvString def_str(value); set(section, entry, def_str); } // only set the value if it isn't already in the config file void WvConf::maybesetint(WvStringParm section, WvStringParm entry, int value) { if (!get(section, entry, NULL)) setint(section, entry, value); } void WvConf::load_file(WvStringParm filename) { const char *p; char *from_file; WvConfigSection *sect = &globalsection; bool quick_mode = false; WvFile file(filename, O_RDONLY); #ifdef _WIN32 //FIXME: Windows doesn't have a sticky bit so we can't use that to signal other processes that // the file is being written to. Just be careful :). #else // check the sticky bit and fail if set struct stat statbuf; if (file.isok() && fstat(file.getrfd(), &statbuf) == -1) { log(WvLog::Warning, "Can't stat config file %s\n", filename); file.close(); } if (file.isok() && (statbuf.st_mode & S_ISVTX)) { file.close(); file.seterr(EAGAIN); } #endif if (!file.isok()) { // Could not open for read. // ...actually, this warning is mainly just annoying. //log(loaded_once ? WvLog::Debug1 : WvLog::Warning, // "Can't read config file %s: %s\n", filename, file.errstr()); if (file.geterr() != ENOENT && !loaded_once) error = true; return; } while ((from_file = trim_string(file.getline())) != NULL) { if ((p = parse_section(from_file)) != NULL) { quick_mode = false; // a new section? if (!p[0]) // blank name: global section sect = &globalsection; else { sect = (*this)[p]; if (!sect) { sect = new WvConfigSection(p); append(sect, true); quick_mode = true; } } } else { // it must be an element for the current section *sect. p = parse_value(from_file); if (!p) p = ""; // allow empty entries from_file = trim_string(from_file); if (from_file[0]) // nonblank option name { if (quick_mode) sect->quick_set(from_file, p); else sect->set(from_file, p); } } } run_all_callbacks(); loaded_once = true; } WvConf::~WvConf() { // We don't really have to do anything here. sections's destructor // will go through and delete all its entries, so we should be fine. flush(); } const char *WvConf::get(WvStringParm section, WvStringParm entry, const char *def_val) { WvStringTable cache(5); WvConfigSection *s; for(s = (*this)[section]; s && !cache[s->name]; s = (*s)["Inherits"] ? (*this)[(*s)["Inherits"]->value] : NULL) { const char *ret = s->get(entry); if (ret) return ret; cache.add(&s->name, false); } return globalsection.get(entry, def_val); } // Gets an entry, given a string in the form [section]entry=value. Returns // the value or NULL if not found. The parameter parse_error is set to the // return value of parse_wvconf_request. WvString WvConf::getraw(WvString wvconfstr, int &parse_error) { char *section, *entry, *value; parse_error = parse_wvconf_request(wvconfstr.edit(), section, entry, value); if (parse_error) return WvString(); return get(section, entry, value); } const char *WvConf::fuzzy_get(WvStringList §ions, WvStringList &entries, const char *def_val) { WvStringList::Iter i(sections), i2(entries); WvStringTable cache(5); WvConfigSection *s; for (i.rewind(); i.next(); ) { for (i2.rewind(); i2.next();) { for(s = (*this)[*i]; s && !cache[s->name]; s = (*s)["Inherits"] ? (*this)[(*s)["Inherits"]->value] : NULL) { const char *ret = s->get(*i2); if (ret) return ret; cache.add(&s->name, false); } } } return def_val; } const char *WvConf::fuzzy_get(WvStringList §ions, WvStringParm entry, const char *def_val) { WvStringList::Iter i(sections); WvStringTable cache(5); WvConfigSection *s; for (i.rewind(); i.next(); ) { for(s = (*this)[*i]; s && !cache[s->name]; s = (*s)["Inherits"] ? (*this)[(*s)["Inherits"]->value] : NULL) { const char *ret = s->get(entry); if (ret) return ret; cache.add(&s->name, false); } } return def_val; } void WvConf::set(WvStringParm section, WvStringParm entry, const char *value) { WvConfigSection *s = (*this)[section]; // section does not exist yet if (!s) { if (!value || !value[0]) return; // no section, no entry, no problem! s = new WvConfigSection(section); append(s, true); } const char *oldval = s->get(entry, ""); if (!value) value = ""; if (strcmp(oldval, value)) // case sensitive { run_callbacks(section, entry, oldval, value); /* fprintf(stderr, "cfg.set: set [%s]%s = %s\n", (const char *)section, (const char *)entry, (const char *)value ?: "!!!"); */ s->set(entry, value); dirty = true; } } // Takes a string in the form [section]entry=value and sets it. Returns an // error code as defined in parse_wvconf_request. The value parameter is // also set to the value (useful in rcommand, when we display the value after // it has been set). void WvConf::setraw(WvString wvconfstr, const char *&xvalue, int &parse_error) { char *section, *entry, *value; parse_error = parse_wvconf_request(wvconfstr.edit(), section, entry, value); if (!parse_error) { set(section, entry, value); xvalue = get(section, entry, value); } else xvalue = NULL; } // only set the value if it isn't already in the config file void WvConf::maybeset(WvStringParm section, WvStringParm entry, const char *value) { if (value && !get(section, entry, NULL)) set(section, entry, value); } WvConfigSection *WvConf::operator[] (WvStringParm section) { Iter i(*this); if (section) for (i.rewind(); i.next(); ) { if (strcasecmp(i().name, section) == 0) return &i(); } return NULL; } void WvConf::delete_section(WvStringParm section) { WvConfigSection *s = (*this)[section]; if (s) { unlink(s); dirty = true; } } char *WvConf::parse_section(char *s) { char *q; if (s[0] != '[') return (NULL); q = strchr(s, ']'); if (!q || q[1]) return (NULL); *q = 0; return trim_string(s + 1); } char *WvConf::parse_value(char *s) { char *q; q = strchr(s, '='); if (q == NULL) return (NULL); *q++ = 0; // 's' points to option name, 'q' points to value return (trim_string(q)); } void WvConf::save(WvStringParm _filename) { if (error || !_filename) return; WvFile fp(_filename, O_WRONLY|O_CREAT|O_TRUNC, create_mode); if (!fp.isok()) { log(WvLog::Error, "Can't write to config file %s: %s\n", _filename, strerror(errno)); if (fp.geterr() != ENOENT) error = true; return; } #ifdef _WIN32 //FIXME: Windows doesn't have a sticky bit so we can't use that to signal other processes that // the file is being written to. Just be careful :). #else struct stat statbuf; if (fstat(fp.getwfd(), &statbuf) == -1) { log(WvLog::Error, "Can't stat config file %s: %s\n", _filename, strerror(errno)); error = true; return; } fchmod(fp.getwfd(), (statbuf.st_mode & 07777) | S_ISVTX); #endif globalsection.dump(fp); Iter i(*this); for (i.rewind(); i.next();) { WvConfigSection & sect = *i; fp.print("\n[%s]\n", sect.name); sect.dump(fp); } #ifdef _WIN32 //FIXME: Windows doesn't have a sticky bit so we can't use that to signal other processes that // the file is being written to. Just be careful :). #else fchmod(fp.getwfd(), statbuf.st_mode & 07777); #endif } void WvConf::save() { save(filename); } // only save the config file if it's dirty void WvConf::flush() { if (!dirty || error) return; // save under default filename save(filename); dirty = false; } void WvConf::add_callback(WvConfCallback callback, void *userdata, WvStringParm section, WvStringParm entry, void *cookie) { callbacks.append(new WvConfCallbackInfo(callback, userdata, section, entry, cookie), true); } void WvConf::del_callback(WvStringParm section, WvStringParm entry, void *cookie) { WvConfCallbackInfoList::Iter i(callbacks); for (i.rewind(); i.next(); ) { if (i->cookie == cookie && i->section == section && i->entry == entry) { i.unlink(); return; } } } void WvConf::run_callbacks(WvStringParm section, WvStringParm entry, WvStringParm oldvalue, WvStringParm newvalue) { WvConfCallbackInfoList::Iter i(callbacks); for (i.rewind(); i.next(); ) { if (!i->section || !strcasecmp(i->section, section)) { if (!i->entry || !strcasecmp(i->entry, entry)) i->callback(i->userdata, section, entry, oldvalue, newvalue); } } } void WvConf::run_all_callbacks() { WvConfCallbackInfoList::Iter i(callbacks); for (i.rewind(); i.next(); ) i->callback(i->userdata, "", "", "", ""); } wvstreams-4.6.1/wvtestrun0000755000175000001440000000705611205042556014611 0ustar wlachusers#!/usr/bin/perl -w # # WvTest: # Copyright (C)2007-2009 Versabanq Innovations Inc. and contributors. # Licensed under the GNU Library General Public License, version 2. # See the included file named LICENSE for license information. # use strict; use Time::HiRes qw(time); # always flush $| = 1; if (@ARGV < 1) { print STDERR "Usage: $0 \n"; exit 127; } print STDERR "Testing \"all\" in @ARGV:\n"; my $pid = open(my $fh, "-|"); if (!$pid) { # child setpgrp(); open STDERR, '>&STDOUT' or die("Can't dup stdout: $!\n"); exec(@ARGV); exit 126; # just in case } my $istty = -t STDOUT; my @log = (); my ($gpasses, $gfails) = (0,0); sub bigkill($) { my $pid = shift; if (@log) { print "\n" . join("\n", @log) . "\n"; } print STDERR "\n! Killed by signal FAILED\n"; ($pid > 0) || die("pid is '$pid'?!\n"); local $SIG{CHLD} = sub { }; # this will wake us from sleep() faster kill 15, $pid; sleep(2); if ($pid > 1) { kill 9, -$pid; } kill 9, $pid; exit(125); } # parent local $SIG{INT} = sub { bigkill($pid); }; local $SIG{TERM} = sub { bigkill($pid); }; local $SIG{ALRM} = sub { print STDERR "Alarm timed out! No test results for too long.\n"; bigkill($pid); }; sub colourize($) { my $result = shift; my $pass = ($result eq "ok"); if ($istty) { my $colour = $pass ? "\e[32;1m" : "\e[31;1m"; return "$colour$result\e[0m"; } else { return $result; } } sub mstime($$$) { my ($floatsec, $warntime, $badtime) = @_; my $ms = int($floatsec * 1000); my $str = sprintf("%d.%03ds", $ms/1000, $ms % 1000); if ($istty && $ms > $badtime) { return "\e[31;1m$str\e[0m"; } elsif ($istty && $ms > $warntime) { return "\e[33;1m$str\e[0m"; } else { return "$str"; } } sub resultline($$) { my ($name, $result) = @_; return sprintf("! %-65s %s", $name, colourize($result)); } my $allstart = time(); my ($start, $stop); sub endsect() { $stop = time(); if ($start) { printf " %s %s\n", mstime($stop - $start, 500, 1000), colourize("ok"); } } while (<$fh>) { chomp; s/\r//g; if (/^\s*Testing "(.*)" in (.*):\s*$/) { alarm(120); my ($sect, $file) = ($1, $2); endsect(); printf("! %s %s: ", $file, $sect); @log = (); $start = $stop; } elsif (/^!\s*(.*?)\s+(\S+)\s*$/) { alarm(120); my ($name, $result) = ($1, $2); my $pass = ($result eq "ok"); if (!$start) { printf("\n! Startup: "); $start = time(); } push @log, resultline($name, $result); if (!$pass) { $gfails++; if (@log) { print "\n" . join("\n", @log) . "\n"; @log = (); } } else { $gpasses++; print "."; } } else { push @log, $_; } } endsect(); my $newpid = waitpid($pid, 0); if ($newpid != $pid) { die("waitpid returned '$newpid', expected '$pid'\n"); } my $code = $?; my $ret = ($code >> 8); # return death-from-signal exits as >128. This is what bash does if you ran # the program directly. if ($code && !$ret) { $ret = $code | 128; } if ($ret && @log) { print "\n" . join("\n", @log) . "\n"; } if ($code != 0) { print resultline("Program returned non-zero exit code ($ret)", "FAILED"); } my $gtotal = $gpasses+$gfails; printf("\nWvTest: %d test%s, %d failure%s, total time %s.\n", $gtotal, $gtotal==1 ? "" : "s", $gfails, $gfails==1 ? "" : "s", mstime(time() - $allstart, 2000, 5000)); print STDERR "\nWvTest result code: $ret\n"; exit( $ret ? $ret : ($gfails ? 125 : 0) ); wvstreams-4.6.1/include/0000755000175000001440000000000011260431131014205 5ustar wlachuserswvstreams-4.6.1/include/wvrsa.h0000644000175000001440000000657211036722347015547 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * RSA cryptography abstractions. */ #ifndef __WVRSA_H #define __WVRSA_H #include "wverror.h" #include "wvencoder.h" #include "wvencoderstream.h" #include "wvlog.h" struct rsa_st; /** * An RSA public key or public/private key pair that can be used for * encryption. * * Knows how to encode/decode itself into a string of hex digits * for easy transport. * * @see WvRSAEncoder */ class WvRSAKey { public: /** * Type for the @ref encode() and @ref decode() methods. * RsaPEM = PEM Encoded RSA Private Key * RsaPubPEM = PEM Encoded RSA Public Key * RsaHex = DER Encoded RSA Private Key in hexified form * RsaPubHex = DER Encoded RSA Public Key in hexified form */ enum DumpMode { RsaPEM, RsaPubPEM, RsaHex, RsaPubHex }; struct rsa_st *rsa; WvRSAKey(); WvRSAKey(const WvRSAKey &k); WvRSAKey(WvStringParm keystr, bool priv); WvRSAKey(struct rsa_st *_rsa, bool priv); // note: takes ownership /** * Create a new RSA key of bits strength. */ WvRSAKey(int bits); virtual ~WvRSAKey(); virtual bool isok() const; /** * Return the information requested by mode. */ virtual WvString encode(const DumpMode mode) const; virtual void encode(const DumpMode mode, WvBuf &buf) const; /** * Load the information from the format requested by mode into * the class - this overwrites the certificate. */ virtual void decode(const DumpMode mode, WvStringParm encoded); virtual void decode(const DumpMode mode, WvBuf &encoded); private: bool priv; mutable WvLog debug; }; /** * An encoder implementing the RSA public key encryption method. * * This encoder really slow, particularly for decryption, so should * only be used to negotiate session initiation information. For * more intensive work, consider exchanging a key for use with a * faster symmetric cipher like Blowfish. * * Supports reset(). * */ class WvRSAEncoder : public WvEncoder { public: enum Mode { Encrypt, /*!< Encrypt with public key */ Decrypt, /*!< Decrypt with private key */ SignEncrypt, /*!< Encrypt digital signature with private key */ SignDecrypt /*!< Decrypt digital signature with public key */ }; /** * Creates a new RSA cipher encoder. * * "mode" is the encryption mode * "key" is the public key if mode is Encrypt or SignDecrypt, * otherwise the private key */ WvRSAEncoder(Mode mode, const WvRSAKey &key); virtual ~WvRSAEncoder(); protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported private: Mode mode; WvRSAKey key; size_t rsasize; }; /** * A crypto stream implementing RSA public key encryption. * * By default, written data is encrypted using WvRSAEncoder::Encrypt, * read data is decrypted using WvRSAEncoder::Decrypt. * * @see WvRSAEncoder */ class WvRSAStream : public WvEncoderStream { public: WvRSAStream(WvStream *_cloned, const WvRSAKey &_my_key, const WvRSAKey &_their_key, WvRSAEncoder::Mode readmode = WvRSAEncoder::Decrypt, WvRSAEncoder::Mode writemode = WvRSAEncoder::Encrypt); virtual ~WvRSAStream() { } }; #endif // __WVRSA_H wvstreams-4.6.1/include/wvxor.h0000644000175000001440000000216211036722347015561 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * XOR cryptography abstractions. * Could use this to implement short one time pads. */ #ifndef __WVXOR_H #define __WVXOR_H #include "wvencoder.h" #include "wvencoderstream.h" /** * An encoder implementing simple XOR encryption. * Mainly useful for testing. */ class WvXOREncoder : public WvEncoder { public: /** * Creates a new XOR encoder / decoder. * _key : the key * _keylen : the length of the key in bytes */ WvXOREncoder(const void *_key, size_t _keylen); virtual ~WvXOREncoder(); protected: bool _encode(WvBuf &in, WvBuf &out, bool flush); private: unsigned char *key; size_t keylen; int keyoff; }; /** * A crypto stream implementing XOR encryption. * See WvXOREncoder for details. */ class WvXORStream : public WvEncoderStream { public: WvXORStream(WvStream *_cloned, const void *key, size_t _keysize); virtual ~WvXORStream() { } public: const char *wstype() const { return "WvXORStream"; } }; #endif /// __WVXOR_H wvstreams-4.6.1/include/wvbufbase.h0000644000175000001440000007152011036722347016364 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generic buffering API. * Please declare specializations in a separate header file, * See "wvbuf.h". */ #ifndef __WVBUFFERBASE_H #define __WVBUFFERBASE_H #include "wvbufstore.h" template class WvBufBase; /** * An abstract generic buffer template. * Buffers are simple data queues designed to ease the construction of * functions that must generate, consume, or transform large amount of * data in pipeline fashion. Concrete buffer subclases define the actual * storage mechanism and queuing machinery. In addition they may provide * additional functionality for accomplishing particular tasks. * * The base component is split into two parts, WvBufBaseCommonImpl * that defines the common API for all buffer types, and WvBufBase * that allows specializations to be defined to add functionality * to the base type. When passing around buffer objects, you should * use the WvBufBase type rather than WvBufBaseCommonImpl. * * See WvBufBase * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvBufBaseCommonImpl { protected: typedef T Elem; typedef WvBufBase Buffer; WvBufStore *store; // discourage copying explicit WvBufBaseCommonImpl( const WvBufBaseCommonImpl &other) { } protected: /** * Initializes the buffer. * * Note: Does not take ownership of the storage object. * * * "store" is the low-level storage object */ explicit WvBufBaseCommonImpl(WvBufStore *store) : store(store) { } public: /** Destroys the buffer. */ virtual ~WvBufBaseCommonImpl() { } /** * Returns a pointer to the underlying storage class object. * * Returns: the low-level storage class object pointer, non-null */ WvBufStore *getstore() { return store; } /*** Buffer Reading ***/ /** * Returns true if the buffer supports reading. * * Returns: true if reading is supported */ bool isreadable() const { return store->isreadable(); } /** * Returns the number of elements in the buffer currently * available for reading. * * This function could also be called gettable(). */ size_t used() const { return store->used() / sizeof(Elem); } /** * Reads exactly the specified number of elements and returns * a pointer to a storage location owned by the buffer. * * The pointer is only valid until the next non-const buffer * member is called. eg. alloc(size_t) * * If count == 0, a NULL pointer may be returned. * * It is an error for count to be greater than the number of * available elements in the buffer. * * For maximum efficiency, call this function multiple times * with count no greater than optgettable() each time. * * After this operation, at least count elements may be ungotten. */ const T *get(size_t count) { if (count > used()) return NULL; return static_cast( store->get(count * sizeof(Elem))); } /** * Skips exactly the specified number of elements. * * This is equivalent to invoking get(size_t) with the count * and discarding the result, but may be faster for certain * types of buffers. As with get(size_t), the call may be * followed up by an unget(size_t). * * It is an error for count to be greater than the number of * available elements in the buffer. * * "count" is the number of elements */ void skip(size_t count) { store->skip(count * sizeof(Elem)); } /** * Returns the optimal maximum number of elements in the * buffer currently available for reading without incurring * significant overhead. * * Invariants: * * - optgettable() <= used() * - optgettable() != 0 if used() != 0 * * * Returns: the number of elements */ size_t optgettable() const { size_t avail = store->optgettable(); size_t elems = avail / sizeof(Elem); if (elems != 0) return elems; return avail != 0 && store->used() >= sizeof(Elem) ? 1 : 0; } /** * Ungets exactly the specified number of elements by returning * them to the buffer for subsequent reads. * * This operation may always be safely performed with count * less than or equal to that specified in the last get(size_t) * if no non-const buffer members have been called since then. * * If count == 0, nothing happens. * * It is an error for count to be greater than ungettable(). * * * "count" is the number of elements */ void unget(size_t count) { store->unget(count * sizeof(Elem)); } /** * Returns the maximum number of elements that may be ungotten * at this time. * * Returns: the number of elements */ size_t ungettable() const { return store->ungettable() / sizeof(Elem); } /** * Returns a const pointer into the buffer at the specified * offset to the specified number of elements without actually * adjusting the current get() index. * * The pointer is only valid until the next non-const buffer * member is called. eg. alloc(size_t) * * If count == 0, a NULL pointer may be returned. * * If offset is greater than zero, then elements will be returned * beginning with the with the offset'th element that would be * returned by get(size_t). * * If offset equals zero, then elements will be returned beginning * with the next one available for get(size_t). * * If offset is less than zero, then elements will be returned * beginning with the first one that would be returned on a * get(size_t) following an unget(-offset). * * It is an error for count to be greater than peekable(offset). * * For maximum efficiency, call this function multiple times * with count no greater than that returned by optpeekable(size_t) * at incremental offsets. * * * "offset" is the buffer offset * "count" is the number of elements * Returns: the element storage pointer */ const T *peek(int offset, size_t count) { return static_cast(store->peek( offset * sizeof(Elem), count * sizeof(Elem))); } size_t peekable(int offset) { return store->peekable(offset * sizeof(Elem)) / sizeof(Elem); } size_t optpeekable(int offset) { offset *= sizeof(Elem); size_t avail = store->optpeekable(offset); size_t elems = avail / sizeof(Elem); if (elems != 0) return elems; return avail != 0 && store->peekable(offset) >= sizeof(Elem) ? 1 : 0; } /** * Clears the buffer. * * For many types of buffers, calling zap() will increased the * amount of free space available for writing (see below) by * an amount greater than used(). Hence it is wise to zap() * a buffer just before writing to it to maximize free space. * * After this operation, used() == 0, and often ungettable() == 0. * */ void zap() { store->zap(); } /** * Reads the next element from the buffer. * * It is an error to invoke this method if used() == 0. * * After this operation, at least 1 element may be ungotten. * * * Returns: the element */ T get() { return *get(1); } /** * Returns the element at the specified offset in the buffer. * * It is an error to invoke this method if used() == 0. * * * "offset" is the offset, default 0 * Returns: the element */ T peek(int offset = 0) { return *peek(offset * sizeof(Elem), sizeof(Elem)); } /** * Efficiently copies the specified number of elements from the * buffer to the specified UNINITIALIZED storage location * and removes the elements from the buffer. * * It is an error for count to be greater than used(). * * For maximum efficiency, choose as large a count as possible. * * The pointer buf may be NULL only if count == 0. * * After this operation, an indeterminate number of elements * may be ungotten. * * * "buf" is the buffer that will receive the elements * "count" is the number of elements */ void move(T *buf, size_t count) { store->move(buf, count * sizeof(Elem)); } /** * Efficiently copies the specified number of elements from the * buffer to the specified UNINITIALIZED storage location * but does not remove the elements from the buffer. * * It is an error for count to be greater than peekable(offset). * * For maximum efficiency, choose as large a count as possible. * * The pointer buf may be NULL only if count == 0. * * * "buf" is the buffer that will receive the elements * "offset" is the buffer offset * "count" is the number of elements */ void copy(T *buf, int offset, size_t count) { store->copy(buf, offset * sizeof(Elem), count * sizeof(Elem)); } /*** Buffer Writing ***/ /** * Returns true if the buffer supports writing. * * Returns: true if writing is supported */ bool iswritable() const { return true; } /** * Returns the number of elements that the buffer can currently * accept for writing. * * Returns: the number of elements */ size_t free() const { return store->free() / sizeof(Elem); } /** * Allocates exactly the specified number of elements and returns * a pointer to an UNINITIALIZED storage location owned by the * buffer. * * The pointer is only valid until the next non-const buffer * member is called. eg. alloc(size_t) * * If count == 0, a NULL pointer may be returned. * * It is an error for count to be greater than free(). * * For best results, call this function multiple times with * count no greater than optallocable() each time. * * After this operation, at least count elements may be unallocated. * * * "count" is the number of elements * Returns: the element storage pointer */ T *alloc(size_t count) { return static_cast(store->alloc(count * sizeof(Elem))); } /** * Returns the optimal maximum number of elements that the * buffer can currently accept for writing without incurring * significant overhead. * * Invariants: * * - optallocable() <= free() * - optallocable() != 0 if free() != 0 * * * Returns: the number of elements */ size_t optallocable() const { size_t avail = store->optallocable(); size_t elems = avail / sizeof(Elem); if (elems != 0) return elems; return avail != 0 && store->free() >= sizeof(Elem) ? 1 : 0; } /** * Unallocates exactly the specified number of elements by removing * them from the buffer and releasing their storage. * * This operation may always be safely performed with count * less than or equal to that specified in the last alloc(size_t) * or put(const T*, size_t) if no non-const buffer members have * been called since then. * * If count == 0, nothing happens. * * It is an error for count to be greater than unallocable(). * * * "count" is the number of elements */ void unalloc(size_t count) { return store->unalloc(count * sizeof(Elem)); } /** * Returns the maximum number of elements that may be unallocated * at this time. * * For all practical purposes, this number will always be at least * as large as the amount currently in use. It is provided * primarily for symmetry, but also to handle cases where * buffer reading (hence used()) is not supported by the * implementation. * * Invariants: * * - unallocable() >= used() * * * Returns: the number of elements */ size_t unallocable() const { return store->unallocable() / sizeof(Elem); } /** * Returns a non-const pointer info the buffer at the specified * offset to the specified number of elements without actually * adjusting the current get() index. * * Other than the fact that the returned storage is mutable, * operates identically to peek(int, size_t). * * * "offset" is the buffer offset * "count" is the number of elements * Returns: the element storage pointer */ T *mutablepeek(int offset, size_t count) { return static_cast(store->mutablepeek( offset * sizeof(Elem), count * sizeof(Elem))); } /** * Writes the specified number of elements from the specified * storage location into the buffer at its tail. * * It is an error for count to be greater than free(). * * For maximum efficiency, choose as large a count as possible. * * The pointer buf may be NULL only if count == 0. * * After this operation, at least count elements may be unallocated. * * * "data" is the buffer that contains the elements * "count" is the number of elements */ void put(const T *data, size_t count) { store->put(data, count * sizeof(Elem)); } /** * Efficiently copies the specified number of elements from the * specified storage location into the buffer at a particular * offset. * * If offset <= used() and offset + count > used(), the * remaining data is simply tacked onto the end of the buffer * with put(). * * It is an error for count to be greater than free() - offset. * * * "data" is the buffer that contains the elements * "count" is the number of elements * "offset" is the buffer offset, default 0 */ void poke(const T *data, int offset, size_t count) { store->poke(data, offset * sizeof(Elem), count * sizeof(Elem)); } /** * Writes the element into the buffer at its tail. * * It is an error to invoke this method if free() == 0. * * After this operation, at least 1 element may be unallocated. * * * "valid" is the element */ void put(T &value) { store->fastput(& value, sizeof(Elem)); } /** * Writes the element into the buffer at the specified offset. * * It is an error to invoke this method if free() == 0. * * After this operation, at least 1 element may be unallocated. * * * "value" is the element * "offset" is the buffer offset */ void poke(T &value, int offset) { poke(& value, offset, 1); } /*** Buffer to Buffer Transfers ***/ /** * Efficiently moves count bytes from the specified buffer into * this one. In some cases, this may be a zero-copy operation. * * It is an error for count to be greater than inbuf.used(). * * For maximum efficiency, choose as large a count as possible. * * After this operation, an indeterminate number of elements * may be ungotten from inbuf. * * * "inbuf" is the buffer from which to read * "count" is the number of elements */ void merge(Buffer &inbuf, size_t count) { store->merge(*inbuf.store, count * sizeof(Elem)); } /** * Efficiently merges the entire contents of a buffer into this one. * * "inbuf" is the buffer from which to read */ void merge(Buffer &inbuf) { merge(inbuf, inbuf.used()); } }; /** * The generic buffer base type. * To specialize buffers to add new functionality, declare a template * specialization of this type that derives from WvBufBaseCommonImpl. * * See WvBufBaseCommonImpl * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvBufBase : public WvBufBaseCommonImpl { public: explicit WvBufBase(WvBufStore *store) : WvBufBaseCommonImpl(store) { } }; /** * A buffer that wraps a pre-allocated array and provides * read-write access to its elements. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvInPlaceBufBase : public WvBufBase { protected: typedef T Elem; WvInPlaceBufStore mystore; public: /** * Creates a new buffer backed by the supplied array. * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading * "_size" is the size of the array * "_autofree" is if true, the array will be freed when discarded */ WvInPlaceBufBase(T *_data, size_t _avail, size_t _size, bool _autofree = false) : WvBufBase(& mystore), mystore(sizeof(Elem), _data, _avail * sizeof(Elem), _size * sizeof(Elem), _autofree) { } /** * Creates a new empty buffer backed by a new array. * * "_size" is the size of the array */ explicit WvInPlaceBufBase(size_t _size) : WvBufBase(& mystore), mystore(sizeof(Elem), _size * sizeof(Elem)) { } /** Creates a new empty buffer with no backing array. */ WvInPlaceBufBase() : WvBufBase(& mystore), mystore(sizeof(Elem), NULL, 0, 0, false) { } /** * Destroys the buffer. * * Frees the underlying array if autofree(). * */ virtual ~WvInPlaceBufBase() { } /** * Returns the underlying array pointer. * * Returns: the element pointer */ T *ptr() const { return static_cast(mystore.ptr()); } /** * Returns the total size of the buffer. * * Returns: the number of elements */ size_t size() const { return mystore.size() / sizeof(Elem); } /** * Returns the autofree flag. * * Returns: the autofree flag */ bool get_autofree() const { return mystore.get_autofree(); } /** * Sets or clears the autofree flag. * * "_autofree" is if true, the array will be freed when discarded */ void set_autofree(bool _autofree) { mystore.set_autofree(_autofree); } /** * Resets the underlying buffer pointer and properties. * * If the old and new buffer pointers differ and the old buffer * was specified as autofree, the old buffer is destroyed. * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading * "_size" is the size of the array * "_autofree" is if true, the array will be freed when discarded */ void reset(T *_data, size_t _avail, size_t _size, bool _autofree = false) { mystore.reset(_data, _avail * sizeof(Elem), _size * sizeof(Elem), _autofree); } /** * Sets the amount of available data using the current buffer * and resets the read index to the beginning of the buffer. * * "_avail" is the amount of data available for reading */ void setavail(size_t _avail) { mystore.setavail(_avail * sizeof(Elem)); } }; /** * A buffer that wraps a pre-allocated array and provides * read-only access to its elements. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvConstInPlaceBufBase : public WvBufBase { protected: typedef T Elem; WvConstInPlaceBufStore mystore; public: /** * Creates a new buffer backed by the supplied array. * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading */ WvConstInPlaceBufBase(const T *_data, size_t _avail) : WvBufBase(& mystore), mystore(sizeof(Elem), _data, _avail * sizeof(Elem)) { } /** Creates a new empty buffer with no backing array. */ WvConstInPlaceBufBase() : WvBufBase(& mystore), mystore(sizeof(Elem), NULL, 0) { } /** * Destroys the buffer. * * Never frees the underlying array. * */ virtual ~WvConstInPlaceBufBase() { } /** * Returns the underlying array pointer. * * Returns: the element pointer */ const T *ptr() const { return static_cast(mystore.ptr()); } /** * Resets the underlying buffer pointer and properties. * * Never frees the old buffer. * * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading */ void reset(const T *_data, size_t _avail) { mystore.reset(_data, _avail * sizeof(Elem)); } /** * Sets the amount of available data using the current buffer * and resets the read index to the beginning of the buffer. * * "_avail" is the amount of data available for reading */ void setavail(size_t _avail) { mystore.setavail(_avail * sizeof(Elem)); } }; /** * A buffer that wraps a pre-allocated array and provides * read-write access to its elements using a circular buffering * scheme rather than a purely linear one, as used by * WvInPlaceBuf. * * When there is insufficient contigous free/used space to * satisfy a read or write request, the data is automatically * reordered in-place to coalesce the free/used spaces into * sufficiently large chunks. The process may also be manually * triggered to explicitly renormalize the array and shift its * contents to the front. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvCircularBufBase : public WvBufBase { protected: typedef T Elem; WvCircularBufStore mystore; public: /** * Creates a new circular buffer backed by the supplied array. * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading * at the beginning of the buffer * "_size" is the size of the array * "_autofree" is if true, the array will be freed when discarded */ WvCircularBufBase(T *_data, size_t _avail, size_t _size, bool _autofree = false) : WvBufBase(& mystore), mystore(sizeof(Elem), _data, _avail * sizeof(Elem), _size * sizeof(Elem), _autofree) { } /** * Creates a new empty circular buffer backed by a new array. * * "_size" is the size of the array */ explicit WvCircularBufBase(size_t _size) : WvBufBase(& mystore), mystore(sizeof(Elem), _size * sizeof(Elem)) { } /** Creates a new empty buffer with no backing array. */ WvCircularBufBase() : WvBufBase(& mystore), mystore(sizeof(Elem), NULL, 0, 0, false) { } /** * Destroys the buffer. * * Frees the underlying array if autofree(). * */ virtual ~WvCircularBufBase() { } /** * Returns the underlying array pointer. * * Returns: the element pointer */ T *ptr() const { return static_cast(mystore.ptr()); } /** * Returns the total size of the buffer. * * Returns: the number of elements */ size_t size() const { return mystore.size() / sizeof(Elem); } /** * Returns the autofree flag. * * Returns: the autofree flag */ bool get_autofree() const { return mystore.get_autofree(); } /** * Sets or clears the autofree flag. * * "_autofree" is if true, the array will be freed when discarded */ void set_autofree(bool _autofree) { mystore.set_autofree(_autofree); } /** * Resets the underlying buffer pointer and properties. * * If the old and new buffer pointers differ and the old buffer * was specified as autofree, the old buffer is destroyed. * * "_data" is the array of data to wrap * "_avail" is the amount of data available for reading * at the beginning of the buffer * "_size" is the size of the array * "_autofree" is if true, the array will be freed when discarded */ void reset(T *_data, size_t _avail, size_t _size, bool _autofree = false) { mystore.reset(_data, _avail * sizeof(Elem), _size * sizeof(Elem), _autofree); } /** * Sets the amount of available data using the current buffer * and resets the read index to the beginning of the buffer. * * "_avail" is the amount of data available for reading * at the beginning of the buffer */ void setavail(size_t _avail) { mystore.setavail(_avail * sizeof(Elem)); } /** * Normalizes the arrangement of the data such that the * contents of the buffer are stored at the beginning of * the array starting with the next element that would be * returned by get(size_t). * * After invocation, ungettable() may equal 0. * */ void normalize() { mystore.normalize(); } }; /** * A buffer that dynamically grows and shrinks based on demand. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvDynBufBase : public WvBufBase { protected: typedef T Elem; WvDynBufStore mystore; public: /** * Creates a new buffer. * * Provides some parameters for tuning response to buffer * growth. * * "_minalloc" is the minimum number of elements to allocate * at once when creating a new internal buffer segment * "_maxalloc" is the maximum number of elements to allocate * at once when creating a new internal buffer segment * before before reverting to a linear growth pattern */ explicit WvDynBufBase(size_t _minalloc = 1024, size_t _maxalloc = 1048576) : WvBufBase(& mystore), mystore(sizeof(Elem), _minalloc * sizeof(Elem), _maxalloc * sizeof(Elem)) { } }; /** * A buffer that is always empty. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvNullBufBase : public WvBufBase { protected: typedef T Elem; WvNullBufStore mystore; public: /** Creates a new buffer. */ WvNullBufBase() : WvBufBase(& mystore), mystore(sizeof(Elem)) { } }; /** * A buffer that acts like a cursor over a portion of another buffer. * The underlying buffer's get() position is not affected by * reading from this buffer. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvBufCursorBase : public WvBufBase { protected: typedef T Elem; WvBufCursorStore mystore; public: /** * Creates a new buffer. * * Does not take ownership of the supplied buffer. * * * "_buf" is a pointer to the buffer to be wrapped * "_start" is the buffer offset of the window start position * "_length" is the length of the window */ WvBufCursorBase(WvBufBase &_buf, int _start, size_t _length) : WvBufBase(& mystore), mystore(sizeof(Elem), _buf.getstore(), _start * sizeof(Elem), _length * sizeof(Elem)) { } }; /** * A buffer that provides a read-write view over another buffer * with a different datatype. Reading and writing through this * buffer implicitly performs the equivalent of reinterpret_cast * on each element. * * Most useful for manipulating data backed by a raw memory buffer. * * "T" is the type of object to store, must be a primitive or a struct * without special initialization, copy, or assignment semantics */ template class WvBufViewBase : public WvBufBase { public: /** * Creates a new buffer. * * Does not take ownership of the supplied buffer. * * * "_buf" is a pointer to the buffer to be wrapped */ template WvBufViewBase(WvBufBase &_buf) : WvBufBase(_buf.getstore()) { } }; #endif // __WVBUFFERBASE_H wvstreams-4.6.1/include/wvmagiccircle.h0000644000175000001440000000166311036722347017220 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A circular queue that can be accessed across fork(). */ #ifndef __WVMAGICCIRCLE_H #define __WVMAGICCIRCLE_H #include "wvshmzone.h" /** A circular queue that can be accessed across fork(). */ class WvMagicCircle : public WvErrorBase { public: /** * Creates a shared memory circular queue. * * "size" is the number of elements to store */ WvMagicCircle(size_t size); ~WvMagicCircle(); protected: WvShmZone shm; volatile int &head, &tail; int size; char *circle; public: size_t used(); size_t left() { return size - used() - 1; } size_t put(const void *data, size_t len); size_t get(void *data, size_t len); size_t skip(size_t len); public: const char *wstype() const { return "WvMagicCircle"; } }; #endif // __WVMAGICCIRCLE_H wvstreams-4.6.1/include/wvstrutils.h0000644000175000001440000004210711077430750016644 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Various little string functions... * * FIXME: and some other assorted crap that belongs anywhere but here. */ #ifndef __WVSTRUTILS_H #define __WVSTRUTILS_H #include // for off_t #include #include #include "wvstring.h" #include "wvstringlist.h" #include "wvhex.h" #ifndef _WIN32 #include "wvregex.h" #endif /** \file * Various little string functions */ /** * Add character c to the end of a string after removing * terminating carriage returns/linefeeds if any. * * You need a buffer that's at least one character bigger than the * current length of the string, including the terminating NULL. */ char *terminate_string(char *string, char c); /** * Trims whitespace from the beginning and end of the character string, * including carriage return / linefeed characters. Modifies the string * in place. Returns the new first character of the string, which points * either at 'string' itself or some character contained therein. * * string is allowed to be NULL; returns NULL in that case. */ char *trim_string(char *string); /** * Similar to above, but trims the string starting at the first occurrence of * c. */ char *trim_string(char *string, char c); /** * return the string formed by concatenating string 'a' and string 'b' with * the 'sep' character between them. For example, * spacecat("xx", "yy", ";"); * returns "xx;yy", and * spacecat("xx;;", "yy", ";") * returns "xx;;;yy", and * spacecat("xx;;", "yy", ";", true) * returns "xx;yy". * * This function is much faster than the more obvious WvString("%s;%s", a, b), * so it's useful when you're producing a *lot* of string data. */ WvString spacecat(WvStringParm a, WvStringParm b, char sep = ' ', bool onesep = false); /** * Replaces all whitespace characters in the string with non-breaking spaces * ( ) for use with web stuff. */ char *non_breaking(const char *string); /** * Replace all instances of c1 with c2 for the first 'length' characters in * 'string'. Ignores terminating NULL, so make sure you set 'length' correctly. */ void replace_char(void *string, char c1, char c2, int length); /** * Snip off the first part of 'haystack' if it consists of 'needle'. */ char *snip_string(char *haystack, char *needle); #ifndef _WIN32 /** * In-place modify a character string so that all contained letters are * in lower case. Returns 'string'. */ char *strlwr(char *string); /** * In-place modify a character string so that all contained letters are * in upper case. Returns 'string'. */ char *strupr(char *string); #endif /** Returns true if all characters in 'string' are isalnum() (alphanumeric). */ bool is_word(const char *string); /** * Produce a hexadecimal dump of the data buffer in 'buf' of length 'len'. * It is formatted with 16 bytes per line; each line has an address offset, * hex representation, and printable representation. * * This is used mostly for debugging purposes. You can send the returned * WvString object directly to a WvLog or any other WvStream for output. */ WvString hexdump_buffer(const void *buf, size_t len, bool charRep = true); /** * Returns true if 'c' is a newline or carriage return character. * Increases code readability a bit. */ bool isnewline(char c); /** * Converts escaped characters (things like %20 etc.) from web URLS * into their normal ASCII representations. If you happen to be * decoding PEM encoded stuff, or anything that has + signs in it that * you don't want encoded as spaces, then set no_space to true, and * it should "just work" for you. */ WvString url_decode(WvStringParm str, bool no_space = false); /** * Converts all those pesky spaces, colons, and other nasties into nice * unreadable Quasi-Unicode codes. The 'unsafe' parameter is a list of * characters that are unsafe and should be escaped. If unspecified, * all characters which are not part of the uric character class defined * in RFC 2396 will be escaped. Note: The '%' character is always escaped, as * otherwise the string would not be decodable. */ WvString url_encode(WvStringParm str, WvStringParm unsafe = ""); /** * Returns the difference between to dates in a human readable format */ WvString diff_dates(time_t t1, time_t t2); /** * Returns an RFC822-compatible date made out of _when, or, if _when < 0, out of * the current time. */ WvString rfc822_date(time_t _when = -1); /** Returns an RFC1123-compatible date made out of _when */ WvString rfc1123_date(time_t _when); /** Return the local date (TZ applied) out of _when */ WvString local_date(time_t _when = -1); /** Return the local time (in format of ISO 8601) out of _when */ WvString intl_time(time_t _when = -1); /** Return the local date (in format of ISO 8601) out of _when */ WvString intl_date(time_t _when = -1); /** Return the local date and time (in format of ISO 8601) out of _when */ WvString intl_datetime(time_t _when = -1); time_t intl_gmtoff(time_t t); #ifndef _WIN32 /** * Similar to crypt(), but this randomly selects its own salt. * This function is defined in strcrypt.cc. It chooses to use the DES * engine. */ WvString passwd_crypt(const char *str); #endif /** * Similar to crypt(), but this randomly selects its own salt. * This function is defined in strcrypt.cc. It chooses to use the MD5 * engine. */ WvString passwd_md5(const char *str); /** * Returns a string with a backslash in front of every non alphanumeric * character in s1. */ WvString backslash_escape(WvStringParm s1); /** How many times does 'c' occur in "s"? */ int strcount(WvStringParm s, const char c); /** * Example: encode_hostname_as_DN("www.fizzle.com") * will result in dc=www,dc=fizzle,dc=com,cn=www.fizzle.com */ WvString encode_hostname_as_DN(WvStringParm hostname); /** * Given a hostname, turn it into a "nice" one. It has to start with a * letter/number, END with a letter/number, have underscores converted to * hyphens, and have no more than one hyphen in a row. If we can't do this * and have any sort of answer, return "UNKNOWN". */ WvString nice_hostname(WvStringParm name); /** * Take a full path/file name and splits it up into respective pathname and * filename. This can also be useful for splitting the toplevel directory off a * path. */ WvString getfilename(WvStringParm fullname); WvString getdirname(WvStringParm fullname); /* * Possible rounding methods for numbers -- remember from school? */ enum RoundingMethod { ROUND_DOWN, ROUND_DOWN_AT_POINT_FIVE, ROUND_UP_AT_POINT_FIVE, ROUND_UP }; /** * Given a number of blocks and a blocksize (default==1 byte), return a * WvString containing a human-readable representation of blocks*blocksize. * This function uses SI prefixes. */ WvString sizetoa(unsigned long long blocks, unsigned long blocksize = 1, RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); /** * Given a size in kilobyes, return a human readable size. * This function uses SI prefixes (1 MB = 1 000 KB = 1 000 000 B). */ WvString sizektoa(unsigned long long kbytes, RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); /** * Given a number of blocks and a blocksize (default==1 byte), return a * WvString containing a human-readable representation of blocks*blocksize. * This function uses IEC prefixes. */ WvString sizeitoa(unsigned long long blocks, unsigned long blocksize = 1, RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); /** * Given a size in kilobytes, return a human readable size. * This function uses IEC prefixes. */ WvString sizekitoa(unsigned long long kbytes, RoundingMethod rounding_method = ROUND_UP_AT_POINT_FIVE); /** Given a number of seconds, returns a formatted human-readable string * saying how long the period is. */ WvString secondstoa(unsigned int total_seconds); /** * Finds a string in an array and returns its index. * Returns -1 if not found. */ int lookup(const char *str, const char * const *table, bool case_sensitive = false); /** * Splits a string and adds each substring to a collection. * coll : the collection of strings to add to * _s : the string to split * splitchars : the set of delimiter characters * limit : the maximum number of elements to split */ template void strcoll_split(StringCollection &coll, WvStringParm _s, const char *splitchars = " \t", int limit = 0) { WvString s(_s); char *sptr = s.edit(), *eptr, oldc; // Simple if statement to catch (and add) empty (but not NULL) strings. if (sptr && !*sptr ) { WvString *emptyString = new WvString(""); coll.add(emptyString, true); } // Needed to catch delimeters at the beginning of the string. bool firstrun = true; while (sptr && *sptr) { --limit; if (firstrun) { firstrun = false; } else { sptr += strspn(sptr, splitchars); } if (limit) { eptr = sptr + strcspn(sptr, splitchars); } else { eptr = sptr + strlen(sptr); } oldc = *eptr; *eptr = 0; WvString *newstr = new WvString(sptr); coll.add(newstr, true); *eptr = oldc; sptr = eptr; } } /** * Splits a string and adds each substring to a collection. * this behaves differently in that it actually delimits the * pieces as fields and returns them, it doesn't treat multiple * delimeters as one and skip them. * * ie., parm1::parm2 -> 'parm1','','parm2' when delimited with ':' * * coll : the collection of strings to add to * _s : the string to split * splitchars : the set of delimiter characters * limit : the maximum number of elements to split */ template void strcoll_splitstrict(StringCollection &coll, WvStringParm _s, const char *splitchars = " \t", int limit = 0) { WvString s(_s); char *cur = s.edit(); if (!cur) return; for (;;) { --limit; if (!limit) { coll.add(new WvString(cur), true); break; } int len = strcspn(cur, splitchars); char tmp = cur[len]; cur[len] = 0; coll.add(new WvString(cur), true); cur[len] = tmp; if (!cur[len]) break; cur += len + 1; } } #ifndef _WIN32 // don't have regex on win32 /** * Splits a string and adds each substring to a collection. * coll : the collection of strings to add to * _s : the string to split * splitchars : the set of delimiter characters * limit : the maximum number of elements to split */ template void strcoll_split(StringCollection &coll, WvStringParm s, const WvRegex ®ex, int limit = 0) { int start = 0; int match_start, match_end; int count = 0; while ((limit == 0 || count < limit) && regex.continuable_match(&s[start], match_start, match_end) && match_end > 0) { WvString *substr = new WvString; int len = match_start; substr->setsize(len+1); memcpy(substr->edit(), &s[start], len); substr->edit()[len] = '\0'; coll.add(substr, true); start += match_end; ++count; } if (limit == 0 || count < limit) { WvString *last = new WvString(&s[start]); last->unique(); coll.add(last, true); } } #endif /** * Concatenates all strings in a collection and returns the result. * coll : the collection of strings to read from * joinchars : the delimiter string to insert between strings */ template WvString strcoll_join(const StringCollection &coll, const char *joinchars = " \t") { size_t joinlen = strlen(joinchars); size_t totlen = 1; typename StringCollection::Iter s( const_cast(coll)); for (s.rewind(); s.next(); ) { if (s->cstr()) totlen += strlen(s->cstr()); totlen += joinlen; } totlen -= joinlen; // no join chars at tail WvString total; total.setsize(totlen); char *te = total.edit(); te[0] = 0; bool first = true; for (s.rewind(); s.next(); ) { if (first) first = false; else strcat(te, joinchars); if (s->cstr()) strcat(te, s->cstr()); } return total; } /** * Replace any instances of "a" with "b" in "s". Kind of like sed, only * much dumber. */ WvString strreplace(WvStringParm s, WvStringParm a, WvStringParm b); /** Replace any consecutive instances of character c with a single one */ WvString undupe(WvStringParm s, char c); /** Do gethostname() without a fixed-length buffer */ WvString hostname(); /** Get the fqdn of the local host, using gethostbyname() and gethostname() */ WvString fqdomainname(); /** Get the current working directory without a fixed-length buffer */ WvString wvgetcwd(); /** * Inserts SI-style spacing into a number * (eg passing 9876543210 returns "9 876 543 210") */ WvString metriculate(const off_t i); /** * Returns everything in line (exclusively) after a. * If a is not in line, "" is returned. */ WvString afterstr(WvStringParm line, WvStringParm a); /** * Returns everything in line (exclusively) before 'a'. * If a is not in line, line is returned. */ WvString beforestr(WvStringParm line, WvStringParm a); /** * Returns the string of length len starting at pos in line. * Error checking prevents seg fault. * If pos > line.len()-1 return "" * if pos+len > line.len() simply return from pos to end of line */ WvString substr(WvString line, unsigned int pos, unsigned int len); /** * Removes any trailing punctuation ('.', '?', or '!') from the line, and * returns it in a new string. Does not modify line. */ WvString depunctuate(WvStringParm line); // Converts a string in decimal to an arbitrary numeric type template bool wvstring_to_num(WvStringParm str, T &n) { bool neg = false; n = 0; for (const char *p = str; *p; ++p) { if (isdigit(*p)) { n = n * T(10) + T(*p - '0'); } else if ((const char *)str == p && *p == '-') { neg = true; } else return false; } if (neg) n = -n; return true; } /* * Before using the C-style string escaping functions below, please consider * using the functions in wvtclstring.h instead; they usualy lead to much more * human readable and manageable results, and allow representation of * lists of strings. */ struct CStrExtraEscape { char ch; const char *esc; }; extern const CStrExtraEscape CSTR_TCLSTR_ESCAPES[]; /// Converts data into a C-style string constant. // // If data is NULL, returns WvString::null; otherwise, returns an allocated // WvString containing the C-style string constant that represents the data. // // All printable characters including space except " and \ are represented with // escaping. // // The usual C escapes are performed, such as \n, \r, \", \\ and \0. // // All other characters are escaped in uppercase hex form, eg. \x9E // // The extra_escapes parameter allows for additional characters beyond // the usual ones escaped in C; setting it to CSTR_TCLSTR_ESCAPES will // escape { and } as \< and \>, which allows the resulting strings to be // TCL-string coded without ridiculous double-escaping. // WvString cstr_escape(const void *data, size_t size, const CStrExtraEscape extra_escapes[] = NULL); /// Converts a C-style string constant into data. // // This function does *not* include the trailing null that a C compiler would -- // if you want this null, put \0 at the end of the C-style string // // If cstr is correctly formatted and max_size is large enough for the // resulting data, returns true and size will equal the size of the // resulting data. If data is not NULL it will contain this data. // // If cstr is correctly formatted but max_size is too small for the resulting // data, returns false and size will equal the minimum value of min_size // for this function to have returned true. If data is non-NULL it will // contain the first max_size bytes of resulting data. // // If cstr is incorrectly formatted, returns false and size will equal 0. // // This functions works just as well on multiple, whitespace-separated // C-style strings as well. This allows you to concatenate strings produced // by cstr_escape, and the result of cstr_unescape will be the data blocks // concatenated together. This implies that the empty string corresponds // to a valid data block of length zero; however, a null string still returns // an error. // // The extra_escapes parameter must match that used in the call to // cstr_escape used to produce the escaped strings. // bool cstr_unescape(WvStringParm cstr, void *data, size_t max_size, size_t &size, const CStrExtraEscape extra_escapes[] = NULL); static inline bool is_int(const char *str) { if (!str) return false; if (*str == '-') ++str; if (!*str) return false; while (*str) if (!isdigit(*str++)) return false; return true; } /// Converts a pointer into a string, like glibc's %p formatter would /// do. WvString ptr2str(void* ptr); #endif // __WVSTRUTILS_H wvstreams-4.6.1/include/unifastregetgen.h0000644000175000001440000000347611036722347017577 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002-2005 Net Integration Technologies, Inc. */ #ifndef __UNIFASTREGETGEN_H #define __UNIFASTREGETGEN_H #include "unifiltergen.h" class UniConfValueTree; /** * A lightwight but slightly dangerous variant of UniCacheGen. * * UniCacheGen tries to make all operations asynchronous, by storing a local * cache of absolutely everything in the entire UniConf subtree that it wraps. * UniFastRegetGen, on the other hand, tries to be helpful without actually * wasting too much memory, but leaves many operations still synchronous. * * This is useful for programs that may need to access a variety of different * UniConf keys, don't need to worry *too* much about blocking occasionally * while waiting for UniConf, but would like most get() operations to be * fast. * * UniFastRegetGen makes subsequent get() operations on a key, after the * first one, be guaranteed asynchronous. It caches keys which you've * previously done get() on, and accepts notifications for those keys * (so the value is always up to date, but you'll never have to wait for it * again). It makes no attempt to optimize any other operations, including * set(), refresh/commit, or iterate. It ignores notifications for any * keys you haven't explicitly done get() on in the past. */ class UniFastRegetGen : public UniFilterGen { public: UniFastRegetGen(IUniConfGen *_inner); virtual ~UniFastRegetGen(); /***** Overridden members *****/ virtual WvString get(const UniConfKey &key); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); private: IUniConfGen *inner; UniConfValueTree *tree; protected: virtual void gencallback(const UniConfKey &key, WvStringParm value); }; #endif // __UNIFASTREGETGEN_H wvstreams-4.6.1/include/wvstreamsdebuggerserver.h0000644000175000001440000000344111036722347021364 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A server stream for WvStreamsDebugger connections */ #ifndef __WVSTREAMSDEBUGGERSERVER_H #define __WVSTREAMSDEBUGGERSERVER_H #include "wvstream.h" #include "wvstreamclone.h" #include "wvaddr.h" #include "wvistreamlist.h" #include "wvstreamsdebugger.h" #include "wvlog.h" class WvUnixAddr; class WvUnixListener; class WvTCPListener; class WvStreamsDebuggerServer : public WvStream { struct Connection : public WvStreamClone { WvStreamsDebugger debugger; WvString salt; Connection(IWvStream *s); void result_cb(WvStringParm cmd, WvStringList &results); void send(WvStringParm code, WvStringParm result); void send(WvStringParm code, WvStringList &results); void choose_salt(); }; // Username, salt, md5sum("%s%s", salt, password) typedef wv::function AuthCallback; WvLog log; WvUnixListener *unix_listener; void unix_listener_cb(IWvStream *s); void unix_listener_close_cb(); WvTCPListener *tcp_listener; void tcp_listener_cb(IWvStream *s); void tcp_listener_close_cb(); AuthCallback auth_cb; void auth_request_cb(Connection &s); void auth_response_cb(Connection &s); void ready_cb(Connection &s); WvIStreamList streams; public: WvStreamsDebuggerServer(const WvUnixAddr &unix_addr, AuthCallback _auth_cb = AuthCallback(), const WvIPPortAddr &tcp_addr = WvIPPortAddr()); ~WvStreamsDebuggerServer(); void set_auth_callback(AuthCallback _auth_cb) { auth_cb = _auth_cb; } }; #endif // __WVSTREAMSDEBUGGERSERVER_H wvstreams-4.6.1/include/wvuid.h0000644000175000001440000000224011036722347015527 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Portable standins for getuid() and friends. */ #ifndef __WVUID_H #define __WVUID_H #include "wvstring.h" #if WIN32 typedef WvString wvuid_t; #define WVUID_INVALID (WvString::null) #else // not WIN32 #include typedef uid_t wvuid_t; #define WVUID_INVALID ((wvuid_t)(-1)) #endif /** * Convert a uid object into a human-readable username. * Returns WvString::null if the uid isn't findable or doesn't exist. */ WvString wv_username_from_uid(wvuid_t uid); /** * Convert a human-readable username into a machine-usable uid. * Returns WVUID_INVALID if the username isn't findable or doesn't exist. */ wvuid_t wv_uid_from_username(WvString username); /** * Return the machine-usable uid corresponding to the current session user. * * Corresponds to getuid() in Unix; parallels for functions * like getgid() and geteuid() are not currently available. * * In Unix, this should never fail. In Windows, there is no guarantee that * it will work. It returns WVUID_INVALID on failure. */ wvuid_t wvgetuid(); #endif // __WVUID_H wvstreams-4.6.1/include/wvistreamlist.h0000644000175000001440000000540311077124114017303 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * FIXME: Suspiciously similar to wvstreamlist, and with tons of duplicated * code. Blech. */ #ifndef __WVISTREAMLIST_H #define __WVISTREAMLIST_H #include "wvstream.h" /** Create the WvStreamListBase class - a simple linked list of WvStreams */ DeclareWvList2(WvIStreamListBase, IWvStream); /** * WvStreamList holds a list of WvStream objects -- and its select() and * callback() functions know how to handle multiple simultaneous streams. */ class WvIStreamList : public WvStream, public WvIStreamListBase { public: WvIStreamList(); virtual ~WvIStreamList(); virtual bool isok() const; virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void execute(); void unlink(IWvStream *data) { sure_thing.unlink(data); WvIStreamListBase::unlink(data); } void add_after(WvLink *after, IWvStream *data, bool autofree, const char *id) { WvIStreamListBase::add_after(after, data, autofree, id); } void add(IWvStream *data, bool autofree, const char *id) { WvIStreamListBase::add(data, autofree, id); } void prepend(IWvStream *data, bool autofree, const char *id) { WvIStreamListBase::prepend(data, autofree, id); } public: bool auto_prune; // remove !isok() streams from the list automatically? static WvIStreamList globallist; protected: WvIStreamListBase sure_thing; private: // Create some undefined overrides to prevent accidentally using a // WvString as an id; these functions will keep a long-term reference to // the string, so you should probably use a string constant. void add_after(WvLink *after, IWvStream *data, bool autofree, WvString id); void add(IWvStream *data, bool autofree, WvString id); void prepend(IWvStream *data, bool autofree, WvString id); private: bool in_select; bool dead_stream; #ifndef _WIN32 static void onfork(pid_t p); #endif public: void append(IWvStream *s, bool auto_free, const char *id) { if (s->wsname() == NULL) s->set_wsname(id); WvIStreamListBase::append(s, auto_free, id); } void append(IWvStream *s, bool auto_free, WVSTRING_FORMAT_DECL) { if (s->wsname() == NULL) s->set_wsname(WvString(WVSTRING_FORMAT_CALL)); WvIStreamListBase::append(s, auto_free, s->wsname()); } public: const char *wstype() const { return "WvIStreamList"; } private: static void add_debugger_commands(); private: static WvString debugger_globallist_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *); }; #endif // __WVISTREAMLIST_H wvstreams-4.6.1/include/uniautogen.h0000644000175000001440000000057611036722347016561 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A UniConf moniker that uses an .ini file to look up which moniker it * should use to find the config file/subtree for a particular application. */ #ifndef __UNIAUTOGEN_H #define __UNIAUTOGEN_H class WvString; extern WvString uniautogen_moniker; #endif // __UNIAUTOGEN_H wvstreams-4.6.1/include/wvregex.h0000644000175000001440000002136011036722347016064 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Regular expression support though libc */ #ifndef __WVREGEX_H #define __WVREGEX_H #include "wverror.h" #include "wvstring.h" #include #include #define __WVRE_REG(n) __wvre_r##n #define __WVRE_DECL_FORM(n) WvString &__WVRE_REG(n) = WvRegex::__wvre_null_reg #define WVREGEX_REGS_DECL \ __WVRE_DECL_FORM( 0), __WVRE_DECL_FORM( 1), \ __WVRE_DECL_FORM( 2), __WVRE_DECL_FORM( 3), \ __WVRE_DECL_FORM( 4), __WVRE_DECL_FORM( 5), \ __WVRE_DECL_FORM( 6), __WVRE_DECL_FORM( 7), \ __WVRE_DECL_FORM( 8), __WVRE_DECL_FORM( 9), \ __WVRE_DECL_FORM(10), __WVRE_DECL_FORM(11), \ __WVRE_DECL_FORM(12), __WVRE_DECL_FORM(13), \ __WVRE_DECL_FORM(14), __WVRE_DECL_FORM(15), \ __WVRE_DECL_FORM(16), __WVRE_DECL_FORM(17), \ __WVRE_DECL_FORM(18), __WVRE_DECL_FORM(19) #define __WVRE_CALL_FORM(n) __WVRE_REG(n) #define WVREGEX_REGS_CALL \ __WVRE_CALL_FORM( 0), __WVRE_CALL_FORM( 1), \ __WVRE_CALL_FORM( 2), __WVRE_CALL_FORM( 3), \ __WVRE_CALL_FORM( 4), __WVRE_CALL_FORM( 5), \ __WVRE_CALL_FORM( 6), __WVRE_CALL_FORM( 7), \ __WVRE_CALL_FORM( 8), __WVRE_CALL_FORM( 9), \ __WVRE_CALL_FORM(10), __WVRE_CALL_FORM(11), \ __WVRE_CALL_FORM(12), __WVRE_CALL_FORM(13), \ __WVRE_CALL_FORM(14), __WVRE_CALL_FORM(15), \ __WVRE_CALL_FORM(16), __WVRE_CALL_FORM(17), \ __WVRE_CALL_FORM(18), __WVRE_CALL_FORM(19) /*! @brief WvRegex -- Unified support for regular expressions. Supports matching compiled regular expressions and capturing substrings in registers. !*/ class WvRegex: public WvErrorBase { private: bool have_preg; regex_t preg; bool match(WvStringParm string, int eflags, size_t nmatch, regmatch_t pmatch[]) const; virtual void seterr(int _errnum); bool _match(WvStringParm string, int eflags, int &match_start, int &match_end, WVREGEX_REGS_DECL) const { regmatch_t pmatch[21]; int nmatch = 1; #define __WVRE_COUNT_REGS(n) \ if ( &__WVRE_REG(n) != &__wvre_null_reg) ++nmatch __WVRE_COUNT_REGS( 0); __WVRE_COUNT_REGS( 1); __WVRE_COUNT_REGS( 2); __WVRE_COUNT_REGS( 3); __WVRE_COUNT_REGS( 4); __WVRE_COUNT_REGS( 5); __WVRE_COUNT_REGS( 6); __WVRE_COUNT_REGS( 7); __WVRE_COUNT_REGS( 8); __WVRE_COUNT_REGS( 9); __WVRE_COUNT_REGS(10); __WVRE_COUNT_REGS(11); __WVRE_COUNT_REGS(12); __WVRE_COUNT_REGS(13); __WVRE_COUNT_REGS(14); __WVRE_COUNT_REGS(15); __WVRE_COUNT_REGS(16); __WVRE_COUNT_REGS(17); __WVRE_COUNT_REGS(18); __WVRE_COUNT_REGS(19); if (!match(string, eflags, nmatch, pmatch)) return false; match_start = pmatch[0].rm_so; match_end = pmatch[0].rm_eo; #define __WVRE_STORE_REGS(n) \ if (&__WVRE_REG(n) != &__wvre_null_reg \ && pmatch[n+1].rm_so != -1 && pmatch[n+1].rm_eo != -1) \ { \ int len = pmatch[n+1].rm_eo-pmatch[n+1].rm_so; \ __WVRE_REG(n).setsize(len+1); \ memcpy(__WVRE_REG(n).edit(), &string[pmatch[n+1].rm_so], len); \ __WVRE_REG(n).edit()[len] = '\0'; \ } __WVRE_STORE_REGS( 0); __WVRE_STORE_REGS( 1); __WVRE_STORE_REGS( 2); __WVRE_STORE_REGS( 3); __WVRE_STORE_REGS( 4); __WVRE_STORE_REGS( 5); __WVRE_STORE_REGS( 6); __WVRE_STORE_REGS( 7); __WVRE_STORE_REGS( 8); __WVRE_STORE_REGS( 9); __WVRE_STORE_REGS(10); __WVRE_STORE_REGS(11); __WVRE_STORE_REGS(12); __WVRE_STORE_REGS(13); __WVRE_STORE_REGS(14); __WVRE_STORE_REGS(15); __WVRE_STORE_REGS(16); __WVRE_STORE_REGS(17); __WVRE_STORE_REGS(18); __WVRE_STORE_REGS(19); return true; } public: //! //! Flags that affect interpretation of the regex; used in Regex() and //! set() //! enum CFlags { // Use (obsolete) basic regex syntax (like grep). See regex(7). BASIC = 0, // Use extended regex syntax (like egrep). See regex(7). EXTENDED = REG_EXTENDED, // Case insensitive ICASE = REG_ICASE, // Do not collect match start and end or registers; faster NOSUB = REG_NOSUB, // Match-any-character operators don't match a newline. See regex(3) NEWLINE = REG_NEWLINE }; static const int default_cflags; //! //! Flags that affect matching of regex. Used in match() and //! continuable_match() //! enum EFlags { // Matching begining of line always fails (unless NEWLINE cflag is set) NOTBOL = REG_NOTBOL, // Matching end of line always fails (unless NEWLINE cflag is set) NOTEOL = REG_NOTEOL }; static const int default_eflags; //! //! Internal use only //! static WvString __wvre_null_reg; //! //! Construct an empty regex object. Matches will always fail until set() //! is called with a valid regex. //! WvRegex() : have_preg(false) {} //! //! Construct a regex object, compiling the given regex //! //! \param regex The new regular expression to match //! \param cflags CFlags used to compile the regular expression; //! the defaults are case sensitive, extended RE. //! WvRegex(WvStringParm regex, int cflags = default_cflags) : have_preg(false) { set(regex, cflags); } ~WvRegex(); //! //! Replace the current regex to match with a new one. //! //! \param regex The new regular expression to match //! \param cflags CFlags used to compile the regular expression; //! the defaults are case sensitive, extended RE. //! bool set(WvStringParm regex, int cflags = default_cflags); //! //! Match a given string against the compiled regular expression //! //! \param string The string to match //! \param (remaining) WvString registers to capture substring matches //! as specified in the RE //! //! \code //! extern WvString line; //! WvString match; //! if (re.match(line, match)) //! wvout->print("Matching substring is '%s'\n", match); //! \endcode //! bool match(WvStringParm string, WVREGEX_REGS_DECL) const { int match_start, match_end; return _match(string, default_eflags, match_start, match_end, WVREGEX_REGS_CALL); } //! //! Match a given string against the compiled regular expression //! //! \param string The string to match //! \param eflags EFlags that affect matching //! \param (remaining) WvString registers to capture substring matches //! as specified in the RE //! bool match(WvStringParm string, int eflags, WVREGEX_REGS_DECL) const { int match_start, match_end; return _match(string, eflags, match_start, match_end, WVREGEX_REGS_CALL); } //! //! Match a given string against the compiled regular expression, //! capturing the start and end positions of the matching string. //! //! \param string The string to match //! \param match_start If the match succeeds, the starting index of the //! match in string //! \param match_end If the match succeeds, the index of the character in //! string following the last character of the match //! \param (remaining) WvString registers to capture substring matches //! as specified in the RE //! //! \code //! extern WvString line; //! int start = 0; //! WvString match; //! int match_start, match_end; //! while (re.continuable_match(&line[start], //! match_start, match_end, match)) //! { //! wvout->print("Matching substring is '%s'@[%s,%s)\n", //! match, match_start, match_end); //! start += match_end; //! } //! \endcode //! bool continuable_match(WvStringParm string, int &match_start, int &match_end, WVREGEX_REGS_DECL) const { return _match(string, default_eflags, match_start, match_end, WVREGEX_REGS_CALL); } //! //! Match a given string against the compiled regular expression, //! capturing the start and end positions of the matching string. //! //! \param string The string to match //! \param eflags EFlags that affect matching //! \param match_start If the match succeeds, the starting index of the //! match in string //! \param match_end If the match succeeds, the index of the character in //! string following the last character of the match //! \param (remaining) WvString registers to capture substring matches //! as specified in the RE //! bool continuable_match(WvStringParm string, int eflags, int &match_start, int &match_end, WVREGEX_REGS_DECL) const { return _match(string, eflags, match_start, match_end, WVREGEX_REGS_CALL); } }; #endif // __WVREGEX_H wvstreams-4.6.1/include/wvscatterhash.h0000644000175000001440000001453611036722347017272 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A hash table container. */ #ifndef __WVSCATTERHASH_H #define __WVSCATTERHASH_H #include "wvhash.h" #include "wvsorter.h" #include "wvxplc.h" // for deletev. ick. #include #define REBUILD_LOAD_FACTOR 0.45 #define RESIZE_LOAD_FACTOR 0.4 #define IS_OCCUPIED(x) ((x) >> 1) #define IS_AUTO_FREE(x) ((x) == 3) #define IS_DELETED(x) ((x) == 1) class WvScatterHashBase { public: WvScatterHashBase(unsigned _numslots); virtual ~WvScatterHashBase() { deletev xslots; deletev xstatus; } static const unsigned null_idx = (unsigned)-1; static const unsigned prime_numbers[]; size_t count() const { return num; } bool isempty() const { return !num; } size_t slowcount() const; /******* IterBase ******/ class IterBase { public: IterBase(WvScatterHashBase &_table) : table(&_table) { } IterBase(const IterBase &other) : table(other.table), index(other.index) { } void rewind() { index = 0; } bool cur() { return index <= table->numslots; } void *vptr() { return get(); } bool next() { if (!table) return false; /* FIXME: Couldn't this be a *little* clearer? */ while (++index <= table->numslots && !IS_OCCUPIED(table->xstatus[index-1])) { } return index <= table->numslots; } bool get_autofree() const { return IS_AUTO_FREE(table->xstatus[index-1]); } void set_autofree(bool autofree) { table->xstatus[index-1] = autofree ? 3 : 2; } protected: void *get() const { return table->xslots[index-1]; } WvScatterHashBase *table; unsigned index; }; protected: virtual unsigned do_hash(const void *data) = 0; virtual void do_delete(void *data) = 0; friend class IterBase; typedef void *Slot; typedef unsigned char Status; Slot *xslots; Status *xstatus; int prime_index; unsigned numslots; unsigned genfind(const void *data, unsigned hash) const; Slot genfind_or_null(const void *data, unsigned hash) const; void _add(void *data, bool autofree); void _add(void *data, unsigned hash, bool autofree); void _remove(const void *data, unsigned hash); void _zap(); void _set_autofree(const void *data, unsigned hash, bool autofree); bool _get_autofree(const void *data, unsigned hash); virtual bool compare(const void *key, const void *elem) const = 0; private: void rebuild(); unsigned second_hash(unsigned hash) const { return (hash % (numslots - 1)) + 1; } unsigned curhash(unsigned hash, unsigned hash2, unsigned attempt) const //{ return (hash + attempt * attempt) % numslots; } { return (hash + attempt*hash2) % numslots; } size_t used; size_t num; }; template < class T, // element type class K, // key type class Accessor, // element to key template class Comparator = OpEqComp // comparison func > class WvScatterHash : public WvScatterHashBase { protected: typedef Comparator MyComparator; virtual bool compare(const void *key, const void *elem) const { return MyComparator::compare((const K *)key, Accessor::get_key((const T *)elem)); } unsigned hash(const T *data) { return WvHash(*Accessor::get_key(data)); } virtual unsigned do_hash(const void *data) { return hash((const T *)data); } virtual void do_delete(void *data) { delete (T *)data; } public: WvScatterHash(unsigned _numslots = 0) : WvScatterHashBase(_numslots) { } virtual ~WvScatterHash() { _zap(); } T *operator[] (const K &key) const { return (T *)(genfind_or_null(&key, WvHash(key))); } void add(const T *data, bool autofree = false) { _add((void *)data, hash(data), autofree); } void remove(const T *data) { _remove(Accessor::get_key(data), hash(data)); } void set_autofree(const K &key, bool autofree) { _set_autofree(key, WvHash(key), autofree); } void set_autofree(const T *data, bool autofree) { _set_autofree(Accessor::get_key(data), hash(data), autofree); } bool get_autofree(const K &key) { return _get_autofree(key, WvHash(key)); } bool get_autofree(const T *data) { return _get_autofree(Accessor::get_key(data), hash(data)); } void zap() { _zap(); } class Iter : public WvScatterHashBase::IterBase { public: Iter(WvScatterHash &_table) : IterBase(_table) { } Iter(const Iter &other) : IterBase(other) { } unsigned char *getstatus() { return &xstatus[index-1]; } T *ptr() const { return (T *)(get()); } WvIterStuff(T); }; typedef class WvSorter Sorter; }; #define DeclareWvScatterDict2(_classname_, _type_, _ftype_, _field_) \ __WvScatterDict_base(_classname_, _type_, _ftype_, &obj->_field_) #define DeclareWvScatterDict(_type_, _ftype_, _field_) \ DeclareWvScatterDict2(_type_##Dict, _type_, _ftype_, _field_) #define DeclareWvScatterTable2(_classname_, _type_) \ __WvScatterDict_base(_classname_, _type_, _type_, obj) #define DeclareWvScatterTable(_type_) \ DeclareWvScatterTable2(_type_##Table, _type_) #define __WvScatterDict_base(_classname_, _type_, _ftype_, _field_) \ template \ struct _classname_##Accessor \ { \ static const K *get_key(const T *obj) \ { return _field_; } \ }; \ \ typedef WvScatterHash<_type_, _ftype_, \ _classname_##Accessor<_type_, _ftype_> > _classname_ #endif //_WVSCATTERHASH_H wvstreams-4.6.1/include/unilistgen.h0000644000175000001440000000325711036722347016563 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniListGen is a UniConf generator to allow multiple generators to be * stacked in a priority sequence for get/set/etc. * */ #ifndef __UNICONFLISTGEN_H #define __UNICONFLISTGEN_H #include "uniconfgen.h" #include "wvscatterhash.h" /** * Accepts a list of UniConf generators, and stacks them, treating them as one * uniconf source. * * The standard way of using the list generator would be with a moniker. The * moniker takes the form of list:(tcl style string list). * * For example: list:readonly:ini:admin.ini ini:user.ini * * The list can also contain a list. This still uses tcl style string lists as * follows: * * list:readonly:ini:admin.ini list:{ini:user1.ini ini:user2.ini} ini:def.ini */ class UniListGen : public UniConfGen { public: UniListGen(UniConfGenList *_l); virtual ~UniListGen(); UniConfGenList *l; /***** Overridden members *****/ virtual void commit(); virtual bool refresh(); virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual bool isok(); virtual Iter *iterator(const UniConfKey &key); class IterIter; protected: /** * Called by first generator when a key changes. * The default implementation calls delta(key). */ virtual void gencallback(const UniConfKey &key, WvStringParm value); }; #endif // __UNICONFLISTGEN_H wvstreams-4.6.1/include/wvdiffiehellman.h0000644000175000001440000000140211036722347017534 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2003 Net Integration Technologies, Inc. * * Diffie-Hellman shared secret creation. */ #ifndef __WVDIFFIEHELLMAN_H #define __WVDIFFIEHELLMAN_H #include #include "wvstream.h" #include "wvlog.h" class WvDiffieHellman { public: WvDiffieHellman(const unsigned char *_key, int _keylen, BN_ULONG _generator); ~WvDiffieHellman() { DH_free(info); } void get_created_secret(WvBuf &outbuf, size_t len); int get_public_value(WvBuf &outbuf, int len); int pub_key_len(); bool create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf); protected: struct dh_st *info; BN_ULONG generator; private: WvLog log; }; #endif /* __WVDIFFIEHELLMAN_H */ wvstreams-4.6.1/include/fileutils.h0000644000175000001440000000011711036722347016372 0ustar wlachusers// this file exists only for backwards compatibility! #include "wvfileutils.h" wvstreams-4.6.1/include/wvtclstring.h0000644000175000001440000001052311036722347016762 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * FIXME: * It would be possible to represent arbitrary binary blobs using this * technique, but we'd have to avoid using null-terminated strings in a few * places, particularly in the input to wvtcl_escape(). * * We could even make encoded binary blobs printable (although that's not * _strictly_ necessary in all cases) by encoding non-printable characters * using \x## notation, if wvtcl_escape() or wvtcl_unescape() supported it. */ /** \file * Functions to handle "tcl-style" strings and lists. * * Using wvtcl_encode(), you can encode _any_ list of strings into a single * string, then reliably split the single string back into the list using * wvtcl_decode(). * * You can create recursive lists of lists by simply running wvtcl_encode() * on a list of strings returned from wvtcl_encode(). * * Example list encodings (all of the following lists have exactly 3 elements): * foo blah weasels * e1 elem2 {element 3} * x1 {} "element 3" * w x y\ z * * Example list of lists: * foo\ blah\ weasels {e1 elem2 {element 3}} {w x y\ z} */ #ifndef __WVTCLSTRING_H #define __WVTCLSTRING_H #include "wvbuf.h" class WvStringMask; // the default set of "nasties", ie. characters that need to be escaped if // they occur somewhere in a string. #define WVTCL_NASTY_SPACES_STR " \t\n\r" extern const WvStringMask WVTCL_NASTY_SPACES; // Another default set of nasties, but only splitting on newlines #define WVTCL_NASTY_NEWLINES_STR "\n\r" extern const WvStringMask WVTCL_NASTY_NEWLINES; // {, }, \, and " are always considered "nasty." #define WVTCL_ALWAYS_NASTY_CASE '{': case '}': case '\\': case '"' // the default set of split characters, ie. characters that separate elements // in a list. If these characters appear unescaped and not between {} or "" // in a list, they signify the end of the current element. #define WVTCL_SPLITCHARS_STR " \t\n\r" extern const WvStringMask WVTCL_SPLITCHARS; /** * tcl-escape a string. There are three ways to do this: * 1) Strings that need no escaping are unchanged. * 2) Strings containing characters in 'nasties' are usually encoded just * by enclosing the unmodified string in braces. * (For example, "foo blah" becomes "{foo blah}") * 3) Strings containing nasties _and_ unmatched braces are encoded using * backslash notation. (For example, " foo} " becomes "\ foo\}\ " */ WvString wvtcl_escape(WvStringParm s, const WvStringMask &nasties = WVTCL_NASTY_SPACES); /** * tcl-unescape a string. This is generally the reverse of wvtcl_escape, * except we can reverse any backslashified or embraced string, even if it * doesn't follow the "simplest encoding" rules used by wvtcl_escape. We * can also handle strings in double-quotes, ie. '"foo"' becomes 'foo'. */ WvString wvtcl_unescape(WvStringParm s); /** * encode a tcl-style list. This is easily done by tcl-escaping each * string in 'l', then appending the escaped strings together, separated by * the first char in splitchars. */ WvString wvtcl_encode(WvList &l, const WvStringMask &nasties = WVTCL_NASTY_SPACES, const WvStringMask &splitchars = WVTCL_SPLITCHARS); /** * Get a single tcl word from an input buffer, and return the rest of the * buffer untouched. If no word can be created from the buffer, return * a null string and leave the buffer unmodified. */ WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars = WVTCL_SPLITCHARS, bool do_unescape = true); /** * split a tcl-style list. There are some special "convenience" features * here, which allow users to create lists more flexibly than wvtcl_encode * would do. * * Elements of the list are separated by any number of any characters from * the 'splitchars' list. * * Quotes are allowed around elements: '"foo"' becomes 'foo'. These work * mostly like braces, except the string is assumed to be backslashified. * That is, '"\ "' becomes ' ', whereas '{\ }' becomes '\ ' (ie. the backslash * wouldn't be removed). * * Zero-length elements must be represented by {} * */ void wvtcl_decode(WvList &l, WvStringParm _s, const WvStringMask &splitchars = WVTCL_SPLITCHARS, bool do_unescape = true); #endif // __WVTCLSTRING_H wvstreams-4.6.1/include/wvglob.h0000644000175000001440000000262611036722347015701 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Globbing support (ie. filename wildcards) through WvRegex */ #ifndef __WVGLOB_H #define __WVGLOB_H #include "wvregex.h" /*! @brief WvGlob -- Unified support for filename globbing. !*/ class WvGlob : public WvRegex { private: static const bool normal_quit_chars[256]; static const bool brace_quit_chars[256]; static WvString glob_to_regex(const char *src, size_t &src_used, char *dst, size_t &dst_used, const bool quit_chars[256]); public: //! //! Construct an empty glob object. Matches will always fail until set() //! is called with a valid glob pattern. //! WvGlob(); //! //! Construct an glob object for the given pattern. //! WvGlob(WvStringParm glob); //! //! Replace the current regex to match with a new one. //! //! \param regex The new regular expression to match //! \param cflags CFlags used to compile the regular expression; //! the defaults are case sensitive, extended RE. //! bool set(WvStringParm glob); //! //! Convert a glob string to its regex equvilent. All wildcards //! (*, ?, {x,y,z}) are wrapped in parens for capturing into registers //! static WvString glob_to_regex(WvStringParm glob, WvString *errstr); }; #endif // __WVGLOB_H wvstreams-4.6.1/include/wvconf.h0000644000175000001440000002026111036722347015676 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Definition of the WvConfigFile, WvConfigSection, and WvConfigEntry classes, * which are used to read and write entries from a Windows-INI-style file. * * Created: Sept 12 1997 D. Coombs * */ #ifndef __WVCONF_H #define __WVCONF_H #include "strutils.h" #include "wvlinklist.h" #include "wvlog.h" #include "wvstringlist.h" #include "wvtr1.h" #ifdef __WVCONFEMU_H #warning "disabling wvconfemu transparent emulation" #undef WvConf #undef WvConfigSection #undef WvConfigSectionList #undef WvConfigEntry #undef WvConfigEntryList #endif class WvConf; class WvConfigEntry { public: WvConfigEntry(); WvConfigEntry(WvStringParm _name, WvStringParm _value); ~WvConfigEntry(); void set(WvStringParm _value) { value = _value; } WvString name; WvString value; }; DeclareWvList(WvConfigEntry); class WvConfigSection : public WvConfigEntryList { public: WvConfigSection(WvStringParm name); ~WvConfigSection(); WvConfigEntry *operator[] (WvStringParm s); const char *get(WvStringParm entry, const char *def_val = NULL); void set(WvStringParm entry, WvStringParm value); void set(WvConfigEntry *e, WvStringParm value); // add an entry to the end of the section, _assuming_ no duplicates exist void quick_set(WvStringParm entry, WvStringParm value); void dump(WvStream &fp); WvString name; }; // parameters are: userdata, section, entry, oldval, newval typedef wv::function WvConfCallback; class WvConfCallbackInfo { public: WvConfCallback callback; void *userdata, *cookie; const WvString section, entry; WvConfCallbackInfo(WvConfCallback _callback, void *_userdata, WvStringParm _section, WvStringParm _entry, void *_cookie) : callback(_callback), section(_section), entry(_entry) { userdata = _userdata; cookie = _cookie; } }; DeclareWvList(WvConfCallbackInfo); DeclareWvList(WvConfigSection); class WvAuthDaemon; class WvAuthDaemonSvc; /** * WvConf configuration file management class: used to read/write config * files that are formatted in the style of Windows .ini files. */ class WvConf : public WvConfigSectionList { public: WvConf(WvStringParm _filename, int _create_mode = 0666); ~WvConf(); bool isok() const { return !error; } bool isclean() const { return isok() && !dirty; } void save(WvStringParm filename); void save(); void flush(); WvConfigSection *operator[] (WvStringParm s); static int check_for_bool_string(const char *s); int parse_wvconf_request(char *request, char *§ion, char *&entry, char *&value); int getint(WvStringParm section, WvStringParm entry, int def_val); const char *get(WvStringParm section, WvStringParm entry, const char *def_val = NULL); WvString getraw(WvString wvconfstr, int &parse_error); int fuzzy_getint(WvStringList §, WvStringParm entry, int def_val); const char *fuzzy_get(WvStringList §, WvStringParm entry, const char *def_val = NULL); int fuzzy_getint(WvStringList §, WvStringList &entry, int def_val); const char *fuzzy_get(WvStringList & sect, WvStringList & ent, const char *def_val = NULL); void setint(WvStringParm section, WvStringParm entry, int value); void set(WvStringParm section, WvStringParm entry, const char *value); void setraw(WvString wvconfstr, const char *&value, int &parse_error); void maybesetint(WvStringParm section, WvStringParm entry, int value); void maybeset(WvStringParm section, WvStringParm entry, const char *value); void delete_section(WvStringParm section); // section and entry may be blank -- that means _all_ sections/entries! // the 'cookie' is a random value that must be unique between all // registered callbacks on a particular key. (Hint: maybe you should // use your 'this' pointer.) void add_callback(WvConfCallback callback, void *userdata, WvStringParm section, WvStringParm entry, void *cookie); void del_callback(WvStringParm section, WvStringParm entry, void *cookie); void run_callbacks(WvStringParm section, WvStringParm entry, WvStringParm oldvalue, WvStringParm newvalue); void run_all_callbacks(); // generic callback function for setting a bool to "true" when changed void setbool(void *userdata, WvStringParm section, WvStringParm entry, WvStringParm oldval, WvStringParm newval); // generic callback for adding an entry name to name list when changed void addname(void *userdata, WvStringParm section, WvStringParm entry, WvStringParm oldval, WvStringParm newval); // generic callback to create a file with a one-line backup string void addfile(void *userdata, WvStringParm section, WvStringParm entry, WvStringParm oldval, WvStringParm newval); void add_addfile(WvString *filename, WvStringParm sect, WvStringParm ent) { add_callback(wv::bind(&WvConf::addfile, this, _1, _2, _3, _4, _5), filename, sect, ent, new int); } void add_addname(WvStringList *list, WvStringParm sect, WvStringParm ent) { add_callback(wv::bind(&WvConf::addname, this, _1, _2, _3, _4, _5), list, sect, ent, list); } void del_addname(WvStringList *list, WvStringParm sect, WvStringParm ent) { del_callback(sect, ent, list); } void add_setbool(bool *b, WvStringParm section, WvStringParm entry) { add_callback(wv::bind(&WvConf::setbool, this, _1, _2, _3, _4, _5), b, section, entry, b); } void del_setbool(bool *b, WvStringParm section, WvStringParm entry) { del_callback(section, entry, b); } void load_file() // append the contents of the real config file { load_file(filename); } void load_file(WvStringParm filename); // append any config file // Gets a user's password and decrypts it. This isn't defined in wvconf.cc. WvString get_passwd(WvStringParm sect, WvStringParm user); WvString get_passwd(WvStringParm user) { return get_passwd("Users", user); } WvString get_passwd2(WvString pwenc); // Check the password passed in. This isn't defined in wvconf.cc // We use this function to check passwords since we may not know what // the password actually is! bool check_passwd(WvStringParm sect, WvStringParm user, WvStringParm passwd); bool check_passwd(WvStringParm user, WvStringParm passwd) { return check_passwd("Users", user, passwd); } // Check if the user exists. This isn't defined in wvconf.cc bool user_exists(WvStringParm sect, WvStringParm user); bool user_exists(WvStringParm user) { return user_exists("Users", user); } // Encrypts and sets a user's password. This isn't defined in wvconf.cc. void set_passwd(WvStringParm sect, WvStringParm user, WvStringParm passwd); void set_passwd(WvStringParm user, WvStringParm passwd) { set_passwd("Users", user, passwd); } WvString set_passwd2(WvStringParm passwd); // Converts all passwords to unencrypted format. Not defined in wvconf.cc. void convert_to_old_pw(); // needed by wvfast_user_import void setdirty() { dirty = true; } private: bool dirty; // true if changed since last flush() bool error; // true if something has gone wrong bool loaded_once; // true if load_file succeeded at least once int create_mode; // if we must create config file WvString filename; WvLog log; WvConfigSection globalsection; WvConfCallbackInfoList callbacks; char *parse_section(char *s); char *parse_value(char *s); /* The following is an ugly hack, but since WvConf is being * deprecated, we don't care. * * It seems that check_passwd() and user_exists() need to talk to a * WvAuthDaemon. However, making them virtual functions would break since * everyone else has to implement them. So we'll its pointer and accessors * here. */ private: WvAuthDaemon *wvauthd; // Authentication Daemon public: friend class WvAuthDaemonSvc; }; #endif // __WVCONF_H wvstreams-4.6.1/include/wvdelayedcallback.h0000644000175000001440000001072111042636572020036 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2003 Net Integration Technologies, Inc. * */ #ifndef __WVDELAYEDCALLBACK_H #define __WVDELAYEDCALLBACK_H #include "wvistreamlist.h" #include "wvtr1.h" /** * A WvCallback wrapper that delays until the next tick of the WvIStreamList * main loop. * * There are restrictions on the type of the wrapped callback though: * 1. The return type must be void * 2. All parameter types must be copy-constructible value types * * Example: setcallback(wv::delayed(mycallback)); * * FIXME: Because operator() makes a copy of the inner callback and thaw() * destroys the copy, nesting WvDelayedCallback doesn't work as you might * expect. That is, don't do: wv::delayed(wv::delayed(mycallback)). * It creates a copy of the inner WvDelayedCallback, but that copy * gets frozen, then destroyed before it has a chance to thaw! Anyway, * it's a stupid thing to do anyway, so don't. */ template class WvDelayedCallback { private: Functor func; WvStream *stream; wv::function frozen; public: WvDelayedCallback(const Functor& _func): func(_func), stream(new WvStream), frozen(0) { WvIStreamList::globallist.append(stream, true, "WvDelayedCallback"); } WvDelayedCallback(const WvDelayedCallback &other): func(other.func), stream(new WvStream), frozen(0) { WvIStreamList::globallist.append(stream, true, "WvDelayedCallback"); } ~WvDelayedCallback() { stream->close(); } void operator()() { stream->setcallback(func); stream->alarm(0); } template void operator()(P1 &p1) { stream->setcallback(wv::bind(func, p1)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2) { stream->setcallback(wv::bind(func, p1, p2)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3) { stream->setcallback(wv::bind(func, p1, p2, p3)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4) { stream->setcallback(wv::bind(func, p1, p2, p3, p4)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) { stream->setcallback(wv::bind(func, p1, p2, p3, p4, p5)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) { stream->setcallback(wv::bind(func, p1, p2, p3, p4, p5, p6)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) { stream->setcallback(wv::bind(func, p1, p2, p3, p4, p5, p6, p7)); stream->alarm(0); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) { stream->setcallback(wv::bind(func, p1, p2, p3, p4, p5, p6, p7, p8)); stream->alarm(0); } }; /* * We put the following in the wv:: namespace so that they match wv::bind * and wv::function from wvtr1.h. */ namespace wv { /** * A convenience function for constructing WvDelayedCallback objects * from wv::functions without explicitly specifying the type. * Example: * typedef wv::function Func; * Func f = wv::delayed(wv::bind(mycallback, 5, _1)); * f(10); */ template inline T delayed(T cb) { return WvDelayedCallback(cb); } /** * A convenience function for constructing WvDelayedCallback objects * from function pointers without explicitly specifying the type. * Example: * typedef wv::function Func; * Func f = wv::delayed(mycallback); * f(10); */ template inline wv::function delayed(T *cb) { return WvDelayedCallback< wv::function >(cb); } } #endif wvstreams-4.6.1/include/wvcrashlog.h0000644000175000001440000000105311036722347016551 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A "Log Receiver" that logs messages to a file */ #ifndef __WVCRASHLOG_H #define __WVCRASHLOG_H #include "wvlogrcv.h" /// WvLogRcv that sticks log messages in the wvcrash_ring_buffer class WvCrashLog : public WvLogRcv { public: WvCrashLog(WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); protected: virtual void _make_prefix(time_t now_sec); virtual void _mid_line(const char *str, size_t len); }; #endif wvstreams-4.6.1/include/wvargs.h0000644000175000001440000002754011036722347015714 0ustar wlachusers/* -*- Mode: C++ -*- * Copyright (C) 2004-2005 Net Integration Technologies, Inc. * * WvStreams interface for command-line argument processing */ #ifndef __WVARGS_H #define __WVARGS_H #include "wvstring.h" #include "wvstringlist.h" #include "wvtr1.h" class WvArgsOption; class WvArgsData; /*! @brief WvArgs - Sane command-line argument processing for WvStreams WvArgs allows you to specify a series of typed or callback-enabled command-line arguments. Once all of these arguments are specified, the WvArgs::process(..) function can be called to perform the actual argument processing. Sample usage: @code #include "wvargs.h" static void callback(void *userdata, WvStringParm value) { wvout->print("callback value = %s, userdata = %s\n", value, (const char *)userdata); } int main(int argc, char **argv) { WvString str_opt = "default"; bool bool_opt = false; int num_opt = 0; WvArgs args; args.add_option('s', "str", "Pass a string option", "string", str_opt); args.add_set_bool_option('b', "bool", "Set a boolean option", bool_opt); args.add_option('n', "num", "Pass a numeric option", "integer", num_opt); args.add_option('c', "callback", "Callback option", WvArgs::ArgCallback(callback), (void *)"demo"); WvStringList remaining_args; args.process(argc, argv, &remaining_args); wvout->print("str_opt=%s, bool_opt=%s, num_opt=%s\n", str_opt, bool_opt, num_opt); WvStringList::Iter i(remaining_args); for (i.rewind(); i.next(); ) wvout->print("rem: %s\n", *i); return 0; } @endcode !*/ class WvArgs { public: //! //! The callback type used for switches that do not take a parameter. //! It returns true if the switch was parsed correctly. //! typedef wv::function NoArgCallback; //! //! The callback type used for switches that take a parameter //! It returns true if the switch was parsed correctly. //! typedef wv::function ArgCallback; private: WvArgsData *data; WvString args_doc; WvString version; WvString email; WvString header; WvString footer; public: WvArgs(); ~WvArgs(); //! //! Process the command line arguments passed to main() using the //! options provided through calls to add_option(..). If //! remaining_args is provided, any remaining arguments after the //! command line switches will be appended to this list. //! bool process(int argc, char **argv, WvStringList *remaining_args = NULL); //! Set the --version string void set_version(WvStringParm version); //! Set the e-mail address for bug reports void set_email(WvStringParm email); //! Set the introductory help message, printed at the beginning of --help void set_help_header(WvStringParm header); //! Set the descriptive help message, printed at the end of --help void set_help_footer(WvStringParm footer); //! //! Output the short usage message based on the provided options. //! Useful when a bad value is passed as the parameter of a switch. //! void print_usage(int argc, char **argv); //! //! Output the long usage message based on the provided options. //! void print_help(int argc, char **argv); //! //! Add a boolean option, which, when specified, sets the specified //! boolean variable to true. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! //! \param val The boolean variable to set to true when the switch //! is specified //! void add_set_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val); //! //! Add a boolean option, which, when spefied, sets the specified //! boolean variable to false. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! //! \param val The boolean variable to set to false when the switch //! is specified //! void add_reset_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val); //! //! Add a boolean option, which, when spefied, changes the value //! of the boolean variable from false to true or from true to false. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! //! \param val The boolean variable to change when the switch //! is specified //! void add_flip_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val); //! //! Add a switch that takes an integer argument //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The integer varible that gets the value of the argument //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, int &val); //! //! Add a switch that takes a long argument //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The long varible that gets the value of the argument //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, long &val); //! //! Add a switch that takes a float argument //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The float varible that gets the value of the argument //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, float &val); //! //! Add a switch that takes a double argument //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The double varible that gets the value of the argument //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, double &val); //! //! Add a switch that takes a string argument //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The string varible that gets the value of the argument //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, WvString &val); //! //! Add a switch that takes a string argument; the argument is //! appended to a string list. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param val The string list to which the argument is appended //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, WvStringList &val); //! //! Add a switch which does not take an argument which invokes a //! callback when it is specified. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! //! \param cb The callback function to invoke when the switch is //! encountered //! \param ud A generic userdata pointer to pass to the callback //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, NoArgCallback cb, void *ud = NULL); //! //! Add a switch which takes an argument which invokes a //! callback when it is specified. //! //! \param short_option The single-character version of the switch; //! 0 for none //! \param long_option The full-word version of the switch; //! NULL for none //! \param desc The description of the option; NULL for none //! \param arg_desc The (short) description of the argument; //! NULL for none //! //! \param cb The callback function to invoke when the switch is //! encountered //! \param ud A generic userdata pointer to pass to the callback //! void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, ArgCallback cb, void *ud = NULL); //! //! Add a required argument to the list of parameters. WvArgs will //! return an error when run if it is not specified. //! //! \param The description of the parameter //! void add_required_arg(WvStringParm desc, bool multiple = false); //! //! Add an optional argument to the list of parameters. //! //! \param The description of the parameter //! void add_optional_arg(WvStringParm desc, bool multiple = false); //! //! Remove an option by specifying its short form. //! //! \note If an option has both a short and a long form they can only //! both be removed with two seperate calls to //! void remove_option(char short_option); //! //! Remove an option by specifying its long form. //! //! \note If an option has both a short and a long form they can only //! both be removed with two seperate calls to //! void remove_option(WvStringParm long_option); //! //! Remove all options //! void remove_all_options(); //! //! An alias for remove_all_options() //! void zap() { remove_all_options(); } //! These flags control the behaviour of WvArgs. By default, they are //! all set to false. enum flags_t { NO_EXIT_ON_ERRORS, // Do not exit when an error is encountered FLAGS_SIZE // Number of flags that exist }; //! //! Get and set flags. //! bool get_flag(const flags_t flag) const; void set_flag(const flags_t flag, const bool value); }; #endif // __WVARGS_H wvstreams-4.6.1/include/uniconfdaemon.h0000644000175000001440000000172211036722347017222 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Manages a UniConf daemon. */ #ifndef __UNICONFDAEMON_H #define __UNICONFDAEMON_H #include "wvlog.h" #include "wvistreamlist.h" #include "uniconf.h" #include "wvaddr.h" class UniConfDaemon : public WvIStreamList { UniConf cfg; WvLog log, debug; bool authenticate; IUniConfGen *permgen; public: /** * Create a UniConfDaemon to serve the Uniconf tree cfg. If auth is * true, require authentication through PAM before accepting connections. */ UniConfDaemon(const UniConf &cfg, bool auth, IUniConfGen *permgen); virtual ~UniConfDaemon(); virtual void close(); void accept(WvStream *stream); /** * Start listening on a socket described by the given WvListener * moniker. */ void listen(WvStringParm lmoniker); private: void listencallback(IWvStream *s); }; #endif // __UNICONFDAEMON_H wvstreams-4.6.1/include/wvstream.h0000644000175000001440000006107311057766345016263 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Provides basic streaming I/O support. */ #ifndef __WVSTREAM_H #define __WVSTREAM_H #include "iwvstream.h" #include "wvtimeutils.h" #include "wvstreamsdebugger.h" #include #include #include "wvattrs.h" /** * Unified support for streams, that is, sequences of bytes that may or * may not be ready for read/write at any given time. * * We provide typical read and write routines, as well as a select() function * for each stream. */ class WvStream: public IWvStream { IMPLEMENT_IOBJECT(WvStream); WvString my_wsname; WSID my_wsid; WvAttrs attrs; public: /** * If this is set, select() doesn't return true for read unless the * given stream also returns true for write. */ WvStream *read_requires_writable; /** * If this is set, select() doesn't return true for write unless the * given stream also returns true for read. */ WvStream *write_requires_readable; /** If this is set, enables the use of continue_select(). */ bool uses_continue_select; /** Specifies the stack size to reserve for continue_select(). */ size_t personal_stack_size; /** * This will be true during callback execution if the * callback was triggered by the alarm going off. */ bool alarm_was_ticking; /** True if noread()/nowrite()/close() have been called, respectively. */ bool stop_read, stop_write, closed; /** Basic constructor for just a do-nothing WvStream */ WvStream(); virtual ~WvStream(); /** * Close the stream if it is open; isok() becomes false from now on. * Note!! If you override this function in a derived class, you must * call it yourself from your destructor. WvStream::~WvStream() * can only call WvStream::close() because of the way virtual * functions work in C++. */ virtual void close(); /** Override seterr() from WvError so that it auto-closes the stream. */ virtual void seterr(int _errnum); void seterr(WvStringParm specialerr) { WvErrorBase::seterr(specialerr); } void seterr(WVSTRING_FORMAT_DECL) { seterr(WvString(WVSTRING_FORMAT_CALL)); } /** return true if the stream is actually usable right now */ virtual bool isok() const; /** read a data block on the stream. Returns the actual amount read. */ virtual size_t read(void *buf, size_t count); /** * Reads up to 'count' bytes of data from the stream into the buffer. * Returns the actual amount read. * * If 'count' is greater than the amount of free space available * in the buffer, only reads at most that amount. You should * specify a reasonable upper bound on how much data should * be read at once. */ virtual size_t read(WvBuf &outbuf, size_t count); /** * Puts data back into the stream's internal buffer. We cheat so that * there's no restriction on how much (or what) data can be unread(). * This is different from WvBuf::unget() (which is rather restrictive). */ virtual void unread(WvBuf &outbuf, size_t count); /** * Write data to the stream. Returns the actual amount written. * Since WvStream has an output buffer, it *always* successfully "writes" * the full amount (but you might have to flush the buffers later so it * actually gets sent). */ virtual size_t write(const void *buf, size_t count); /** * Writes data to the stream from the given buffer. * Returns the actual amount written. * * If count is greater than the amount of data available in * the buffer, only writes at most that amount. */ virtual size_t write(WvBuf &inbuf, size_t count = INT_MAX); /** * set the maximum size of outbuf, beyond which a call to write() will * return 0. I need to do this for tape backups, since all I can do * is write to the loopback as fast as I can, which causes us to run * out of memory and get SIGABRT'd. (dcoombs: 12/15/2000) * * FIXME: there must be a better way. This confuses the semantics of * write(); can you trust it to always write all the bytes, or not? */ void outbuf_limit(size_t size) { max_outbuf_size = size; } virtual void noread(); virtual void nowrite(); virtual void maybe_autoclose(); virtual bool isreadable(); virtual bool iswritable(); /** * unbuffered I/O functions; these ignore the buffer, which is * handled by read(). Don't call these functions explicitly unless * you have a _really_ good reason. * * This is what you would override in a derived class. */ virtual size_t uread(void *buf, size_t count) { return 0; /* basic WvStream doesn't actually do anything! */ } /** * unbuffered I/O functions; these ignore the buffer, which is * handled by write(). Don't call these functions explicitly unless * you have a _really_ good reason. * * This is what you would override in a derived class. */ virtual size_t uwrite(const void *buf, size_t count) { return count; /* basic WvStream doesn't actually do anything! */ } /** * Read up to one line of data from the stream and return a * pointer to the internal buffer containing this line. If the * end-of-line 'separator' is encountered, it is removed from the * string. If there is not a full line available, returns * NULL. You can read what we have so far by calling read(). * * Readahead specifies the maximum amount of data that the stream * is allowed to read in one shot. * * It is expected that there will be no NULL characters on the * line. * * wait_msec is provided so that legacy code does not break. But * it really should be 0. */ char *getline(time_t wait_msec = 0, char separator = '\n', int readahead = 1024) { return blocking_getline(wait_msec, separator, readahead); } /** Auto-convert int to time_t. */ char *getline(int wait_msec, char separator = '\n', int readahead = 1024) { return getline(time_t(wait_msec), separator, readahead); } /** Auto-convert double to time_t. */ char *getline(double wait_msec, char separator = '\n', int readahead = 1024) { return getline(time_t(wait_msec), separator, readahead); } private: /** We will prohibit someone from calling getline with a char or * bool as the first parameter. This will attempt to detect dumb * mistakes. */ char *getline(char, int i = 0); char *getline(bool, int i = 0); public: /** * This is a version of getline() that allows you to block for * more data to arrive. * * This should be used carefully, as blocking is generally * unexpected in WvStreams programs. * * If wait_msec < 0, it will wait forever for the 'separator' * (often a bad idea!). If wait_msed == 0, this is the equivalent * of getline(). */ char *blocking_getline(time_t wait_msec, int separator = '\n', int readahead = 1024); /** * This is a version of blocking_getline() that uses * continue_select to avoid blocking other streams. */ char *continue_getline(time_t wait_msec, int separator = '\n', int readahead = 1024); /** * force read() to not return any bytes unless 'count' bytes can be * read at once. (Useful for processing Content-Length headers, etc.) * Use count==0 to disable this feature. * * WARNING: getline() sets queuemin to 0 automatically! */ void queuemin(size_t count) { queue_min = count; } /** * drain the input buffer (read and discard data until select(0) * returns false) */ void drain(); /** * force write() to always buffer output. This can be more efficient * if you write a lot of small segments and want to "coagulate" them * automatically. To flush the output buffer, use flush() or select(). */ void delay_output(bool is_delayed) { outbuf_delayed_flush = is_delayed; want_to_flush = !is_delayed; } /** * if true, force write() to call flush() each time, the default behavour. * otherwise, flush() is granted special meaning when explicitly invoked * by the client and write() may empty the output buffer, but will not * explicitly flush(). */ void auto_flush(bool is_automatic) { is_auto_flush = is_automatic; } /** * flush the output buffer, if we can do it without delaying more than * msec_timeout milliseconds at a time. (-1 means wait forever) * * Returns true if the flushing finished (the output buffer is empty). */ virtual bool flush(time_t msec_timeout); virtual bool should_flush(); /** * flush the output buffer automatically as select() is called. If * the buffer empties, close the stream. If msec_timeout seconds pass, * close the stream. After the stream closes, it will become !isok() * (and a WvStreamList can delete it automatically) */ void flush_then_close(int msec_timeout); /** * pre_select() sets up for eventually calling ::select(). * It adds the right fds to the read, write, and except lists in the * SelectInfo struct. * * Returns true if we already know this stream is ready, and there's no * need to actually do a real ::select(). Some streams, such as timers, * can be implemented by _only_ either returning true or false here after * doing a calculation, and never actually adding anything to the * SelectInfo. * * You can add your stream to any of the lists even if readable, * writable, or isexception isn't set. This is what force_select() * does. You can also choose not to add yourself to the list if you know * it would be useless right now. * * pre_select() is only called if isok() is true. * * pre_select() is allowed to reduce msec_timeout (or change it if it's * -1). However, it's not allowed to _increase_ msec_timeout. */ virtual void pre_select(SelectInfo &si); /** * A more convenient version of pre_select() usable for overriding the * 'want' value temporarily. */ void pre_select(SelectInfo &si, const SelectRequest &r) { SelectRequest oldwant = si.wants; si.wants = r; pre_select(si); si.wants = oldwant; } /** * Like pre_select(), but still exists even if you override the other * pre_select() in a subclass. Sigh. */ void xpre_select(SelectInfo &si, const SelectRequest &r) { pre_select(si, r); } /** * post_select() is called after ::select(), and returns true if this * object is now ready. Usually this is done by checking for this object * in the read, write, and except lists in the SelectInfo structure. If * you want to do it in some other way, you should usually do it in * pre_select() instead. * * You may also want to do extra maintenance functions here; for example, * the standard WvStream::post_select tries to flush outbuf if it's * nonempty. WvTCPConn might retry connect() if it's waiting for a * connection to be established. */ virtual bool post_select(SelectInfo &si); /** * Like post_select(), but still exists even if you override the other * post_select() in a subclass. Sigh. */ bool xpost_select(SelectInfo &si, const SelectRequest &r) { return post_select(si, r); } /** * A more convenient version of post_select() usable for overriding the * 'want' value temporarily. */ bool post_select(SelectInfo &si, const SelectRequest &r) { SelectRequest oldwant = si.wants; si.wants = r; bool val = post_select(si); si.wants = oldwant; return val; } /** * Return true if any of the requested features are true on the stream. * If msec_timeout < 0, waits forever (bad idea!). ==0, does not wait. * Otherwise, waits for up to msec_timeout milliseconds. * * **NOTE** * select() is _not_ virtual! To change the select() behaviour * of a stream, override the pre_select() and/or post_select() * functions. * * This version of select() sets forceable==true, so force_select * options are taken into account. * * You almost always use this version of select() with callbacks, like * this: if (stream.select(1000)) stream.callback(); * * If you want to read/write the stream in question, try using the other * variant of select(). * * DEPRECATED. Call runonce() instead. */ bool select(time_t msec_timeout) { return _select(msec_timeout, false, false, false, true); } /** * Exactly the same as: * if (select(timeout)) callback(); * * ...except that the above is deprecated, because it assumes callbacks * aren't called automatically and that the return value of one-parameter * select() is actually meaningful. * * Update your main loop to call runonce() instead of the above. * * Almost all modern programs should use msec_timeout = -1. */ void runonce(time_t msec_timeout = -1) { if (select(msec_timeout)) callback(); } /** * This version of select() sets forceable==false, so we use the exact * readable/writable/isexception options provided. * * You normally use this variant of select() when deciding whether you * should read/write a particular stream. For example: * * if (stream.select(1000, true, false)) * len = stream.read(buf, sizeof(buf)); * * This variant of select() is probably not what you want with * most WvStreamLists, unless you know exactly what you're doing. * * WARNING: the difference between the one-parameter and multi-parameter * versions of select() is *incredibly* confusing. Make sure you use the * right one! * * DEPRECATED. Call isreadable() or iswritable() instead, if * msec_timeout was going to be zero. Other values of msec_timeout are * not really recommended anyway. */ bool select(time_t msec_timeout, bool readable, bool writable, bool isex = false) { return _select(msec_timeout, readable, writable, isex, false); } /** * Use get_select_request() to save the current state of the * selection state of this stream. That way, you can call * force_select() and undo_force_select() to restore this properly. */ IWvStream::SelectRequest get_select_request(); /** * Use force_select() to force one or more particular modes (readable, * writable, or isexception) to true when selecting on this stream. * * If an option is set 'true', we will select on that option when someone * does a select(). If it's set 'false', we don't change its force * status. (To de-force something, use undo_force_select().) */ void force_select(bool readable, bool writable, bool isexception = false); /** * Undo a previous force_select() - ie. un-forces the options which * are 'true', and leaves the false ones alone. */ void undo_force_select(bool readable, bool writable, bool isexception = false); /** * return to the caller from execute(), but don't really return exactly; * this uses WvCont::yield() to return to the caller of callback() * without losing our place in execute() itself. So, next time someone * calls callback(), it will be as if continue_select() returned. * * NOTE: execute() will won't be called recursively this way, but any * other member function might get called, or member variables changed, * or the state of the world updated while continue_select() runs. Don't * assume that nothing has changed after a call to continue_select(). * * NOTE 2: if you're going to call continue_select(), you should set * uses_continue_select=true before the first call to callback(). * Otherwise your WvCont won't get created. * * NOTE 3: if msec_timeout >= 0, this uses WvStream::alarm(). */ bool continue_select(time_t msec_timeout); /** * you MUST run this from your destructor if you use continue_select(), or * very weird things will happen if someone deletes your object while in * continue_select(). */ void terminate_continue_select(); /** * get the remote address from which the last data block was received. * May be NULL. The pointer becomes invalid upon the next call to read(). */ virtual const WvAddr *src() const; /** * define the callback function for this stream, called whenever * the callback() member is run, and passed the 'userdata' pointer. */ void setcallback(IWvStreamCallback _callfunc); /** Sets a callback to be invoked when the stream is readable. */ IWvStreamCallback setreadcallback(IWvStreamCallback _callback); /** Sets a callback to be invoked when the stream is writable. */ IWvStreamCallback setwritecallback(IWvStreamCallback _callback); /** Sets a callback to be invoked when the stream is in exception * state. */ IWvStreamCallback setexceptcallback(IWvStreamCallback _callback); /** Sets a callback to be invoked on close(). */ IWvStreamCallback setclosecallback(IWvStreamCallback _callback); /** * set the callback function for this stream to an internal routine * that auto-forwards all incoming stream data to the given output * stream. */ void autoforward(WvStream &s); /** Stops autoforwarding. */ void noautoforward(); static void autoforward_callback(WvStream &input, WvStream &output); /** * A wrapper that's compatible with WvCont, but calls the "real" callback. */ void *_callwrap(void *); /** * Actually call the registered callfunc and execute(). */ void _callback(); /** * if the stream has a callback function defined, call it now. * otherwise call execute(). */ virtual void callback(); /** * set an alarm, ie. select() will return true after this many ms. * The alarm is cleared when callback() is called. */ void alarm(time_t msec_timeout); /** * return the number of milliseconds remaining before the alarm will go * off; -1 means no alarm is set (infinity), 0 means the alarm has * been hit and will be cleared by the next callback(). */ time_t alarm_remaining(); /** * print a preformatted WvString to the stream. * see the simple version of write() way up above. */ size_t write(WvStringParm s) { return write(s.cstr(), s.len()); } size_t print(WvStringParm s) { return write(s); } size_t operator() (WvStringParm s) { return write(s); } /** preformat and write() a string. */ size_t print(WVSTRING_FORMAT_DECL) { return write(WvString(WVSTRING_FORMAT_CALL)); } size_t operator() (WVSTRING_FORMAT_DECL) { return write(WvString(WVSTRING_FORMAT_CALL)); } const char *wsname() const { return my_wsname; } void set_wsname(WvStringParm wsname) { my_wsname = wsname; } void set_wsname(WVSTRING_FORMAT_DECL) { set_wsname(WvString(WVSTRING_FORMAT_CALL)); } const char *wstype() const { return "WvStream"; } WSID wsid() const { return my_wsid; } static IWvStream *find_by_wsid(WSID wsid); virtual WvString getattr(WvStringParm name) const { return attrs.get(name); } // ridiculous hackery for now so that the wvstream unit test can poke // around in the insides of WvStream. Eventually, inbuf will go away // from the base WvStream class, so nothing like this will be needed. #ifdef __WVSTREAM_UNIT_TEST public: size_t outbuf_used() { return outbuf.used(); } size_t inbuf_used() { return inbuf.used(); } void inbuf_putstr(WvStringParm t) { inbuf.putstr(t); } #endif protected: void setattr(WvStringParm name, WvStringParm value) { attrs.set(name, value); } // builds the SelectInfo data structure (runs pre_select) // returns true if there are callbacks to be dispatched // // all of the fields are filled in with new values // si.msec_timeout contains the time until the next alarm expires void _build_selectinfo(SelectInfo &si, time_t msec_timeout, bool readable, bool writable, bool isexcept, bool forceable); // runs the actual select() function over the given // SelectInfo data structure, returns the number of descriptors // in the set, and sets the error code if a problem occurs int _do_select(SelectInfo &si); // processes the SelectInfo data structure (runs post_select) // returns true if there are callbacks to be dispatched bool _process_selectinfo(SelectInfo &si, bool forceable); // tries to empty the output buffer if the stream is writable // not quite the same as flush() since it merely empties the output // buffer asynchronously whereas flush() might have other semantics // also handles autoclose (eg. after flush) bool flush_outbuf(time_t msec_timeout); // called once flush() has emptied outbuf to ensure that any other // internal stream buffers actually do get flushed before it returns virtual bool flush_internal(time_t msec_timeout); // the real implementations for these are actually in WvFDStream, which // is where they belong. By IWvStream needs them to exist for now, so // it's a hack. In standard WvStream they return -1. virtual int getrfd() const; virtual int getwfd() const; // FIXME: this one is so bad, I'm not touching it. Quick hack to // make it work anyway. friend class WvHTTPClientProxyStream; WvDynBuf inbuf, outbuf; IWvStreamCallback callfunc; wv::function call_ctx; IWvStreamCallback readcb, writecb, exceptcb, closecb; size_t max_outbuf_size; bool outbuf_delayed_flush; bool is_auto_flush; // Used to guard against excessive flushing when using delay_flush bool want_to_flush; // Used to ensure we don't flush recursively. bool is_flushing; size_t queue_min; // minimum bytes to read() time_t autoclose_time; // close eventually, even if output is queued WvTime alarm_time; // select() returns true at this time WvTime last_alarm_check; // last time we checked the alarm_remaining /** * The callback() function calls execute(), and then calls the user- * specified callback if one is defined. Do not call execute() directly; * call callback() instead. * * The default execute() function does nothing. * * Note: If you override this function in a derived class, you must * call the parent execute() yourself from the derived class. */ virtual void execute() { } // every call to select() selects on the globalstream. static WvStream *globalstream; static void debugger_streams_display_header(WvStringParm cmd, WvStreamsDebugger::ResultCallback result_cb); static void debugger_streams_display_one_stream(WvStream *s, WvStringParm cmd, WvStreamsDebugger::ResultCallback result_cb); static void debugger_streams_maybe_display_one_stream(WvStream *s, WvStringParm cmd, const WvStringList &args, WvStreamsDebugger::ResultCallback result_cb); private: /** The function that does the actual work of select(). */ bool _select(time_t msec_timeout, bool readable, bool writable, bool isexcept, bool forceable); void legacy_callback(); /** Prevent accidental copying of WvStream. These don't actually exist. */ WvStream(const WvStream &s); WvStream& operator= (const WvStream &s); static void add_debugger_commands(); static WvString debugger_streams_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *); static WvString debugger_close_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *); }; /** * Console streams... * * This can be reassigned while the program is running, if desired, * but MUST NOT be NULL. */ extern WvStream *wvcon; // tied stdin and stdout stream extern WvStream *wvin; // stdin stream extern WvStream *wvout; // stdout stream extern WvStream *wverr; // stderr stream #endif // __WVSTREAM_H wvstreams-4.6.1/include/wvipraw.h0000644000175000001440000000372211036722347016076 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * */ #ifndef __WVIPRAW_H #define __WVIPRAW_H #include "wvfdstream.h" #include "wvaddr.h" #include /** * WvIPRawStream can send and receive packets on a connectionless IP socket. * * In the constructor, the socket is attached using bind() to the given * _local address. If the address is 0.0.0.0, all addresses on the local * host are used; if the port is 0, an available port number is chosen * automatically. * * If the _rem address is 0.0.0.0, the port is not connect()ed. That means * it can receive packets from anywhere and send them to anywhere. The * src() and setdest() functions are useful for this. If _rem is not 0.0.0.0, * connect() is called and the socket will only accept data to/from the * specified remote UDP address. * * Buffering: all the usual WvStream-style input buffering is available, * including getline(), but because input packets may get lost it is of * limited usefulness. Buffering will cause particular confusion if the * socket is not connect()ed. */ class WvIPRawStream : public WvFDStream { public: /** connect a new socket */ WvIPRawStream(const WvIPAddr &_local, const WvIPAddr &_rem, int ip_protocol = IPPROTO_RAW); virtual ~WvIPRawStream(); const WvAddr *local() const; /** * return the remote address (source of incoming packets, target of * outgoing packets). This is the last host sent to or received from, * whichever was more recent. */ virtual const WvAddr *src() const; void setdest(const WvIPAddr &_remaddr) { remaddr = _remaddr; } void enable_broadcasts(); protected: WvIPAddr localaddr, remaddr; virtual size_t uread(void *buf, size_t count); virtual size_t uwrite(const void *buf, size_t count); public: const char *wstype() const { return "WvIPRawStream"; } }; #endif // __WVIPRAW_H wvstreams-4.6.1/include/wvshmzone.h0000644000175000001440000000143311036722347016434 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Shared memory zones. */ #ifndef __WVSHMZONE_H #define __WVSHMZONE_H #include "wverror.h" /** * Represents a shared-memory zone via mmap(). * * If you create one of these, its buf element will be * shared across fork() and you can use it for various things * such as a circular queue, semaphore, etc. * */ class WvShmZone : public WvErrorBase { public: /** * Creates a shared memory zone. * * "size" is the size of the zone in bytes */ WvShmZone(size_t size); ~WvShmZone(); private: int fd; public: int size; union { void *buf; char *cbuf; unsigned char *ucbuf; }; }; #endif // __WVSHMZONE_h wvstreams-4.6.1/include/wvwin32task.h0000755000175000001440000000377511036722347016614 0ustar wlachusers/* -*- Mode: C++ -*- */ #ifndef __WVWIN32TASK_H #define __WVWIN32TASK_H #include "wvstring.h" #include "wvlinklist.h" #include #define WVTASK_MAGIC 0x123678 class WvTaskMan; class WvTask { friend class WvTaskMan; typedef void TaskFunc(void *userdata); static int taskcount, numtasks, numrunning; int magic_number, *stack_magic; WvString name; int tid; size_t stacksize; bool running, recycled; WvTaskMan &man; LPVOID mystate; // used for resuming the task TaskFunc *func; void *userdata; static VOID CALLBACK MyFiberProc(PVOID lpParameter); WvTask(WvTaskMan &_man, size_t _stacksize = 64*1024); public: virtual ~WvTask(); void start(WvStringParm _name, TaskFunc *_func, void *_userdata); bool isrunning() const { return running; } void recycle(); int get_tid() const { return tid; } WvString get_name() const { return name; } }; DeclareWvList(WvTask); /** Provides co-operative multitasking support among WvTask instances. */ class WvTaskMan { friend class WvTask; static WvTaskMan *singleton; static int links; static int magic_number; static WvTaskList free_tasks; static void get_stack(WvTask &task, size_t size); static void stackmaster(); static void _stackmaster(); static void do_task(); static WvTask *stack_target; static WvTask *current_task; static LPVOID toplevel; WvTaskMan(); virtual ~WvTaskMan(); public: /// get/dereference the singleton global WvTaskMan static WvTaskMan *get(); static void unlink(); WvTask *start(WvStringParm name, WvTask::TaskFunc *func, void *userdata, size_t stacksize = 256*1024); // run() and yield() return the 'val' passed to run() when this task // was started. static int run(WvTask &task, int val = 1); static int yield(int val = 1); static WvTask *whoami() { return current_task; } }; #endif // __WVWIN32TASK_H wvstreams-4.6.1/include/wvhex.h0000644000175000001440000000452111036722347015536 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Hex encoder and hex decoder. */ #ifndef __WVHEX_H #define __WVHEX_H #include "wvencoder.h" /** * A hex encoder. * * The input data is transformed into a sequence of hexadecimal * characters. * * Supports reset(). * */ class WvHexEncoder : public WvEncoder { char alphabase; public: /** * Creates a hex encoder. * * "use_uppercase" is if true, outputs hex codes A through Z * in upper case, otherwise output them in lower case * (the default) */ WvHexEncoder(bool use_uppercase = false); virtual ~WvHexEncoder() { } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported }; /** * A hex decoder. * * The input hex characters are paired and decoded into the * corresponding byte stream. Whitespace is skipped as is the * case of the hex codes A through Z. Other characters cause the * encoder to flag an error. * * Supports reset(). * */ class WvHexDecoder : public WvEncoder { bool issecond; int first; public: /** Creates a hex decoder. */ WvHexDecoder(); virtual ~WvHexDecoder() { } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported }; /** \file * Hex functions for compatibility with older code */ /** * Write the contents of the binary string of length 'len' pointed to by 'ibuf' * into the output buffer 'obuf' in hexadecimal format. * * For example, if len==4, ibuf=="ABCDEF", then obuf will contain "41424344" * with a terminating NULL character. * * This is useful to turn arbitrary binary into a simple printable format, so * that it can (for example) be written to a WvConf configuration file. * * obuf must be a buffer with at least (len * 2) + 1 bytes available. (two * digits for each byte of ibuf, plus a terminating NULL). */ void hexify(char *obuf, const void *ibuf, size_t len); /** * Reverse the operation performed by hexify(). obuf must be a buffer large * enough to contain the entire binary output string; you can calculate this * size with (strlen(ibuf) / 2). obuf will NOT be automatically NULL-terminated. */ void unhexify(void *obuf, const char *ibuf); #endif // __WVHEX_H wvstreams-4.6.1/include/uniconfkey.h0000644000175000001440000003033211077124114016537 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * UniConfKeys are paths in the UniConf hierarchy. */ #ifndef __UNICONFKEY_H #define __UNICONFKEY_H #include "wvstring.h" #include "wvlinklist.h" #include /** * Represents a UniConf key which is a path in a hierarchy structured much * like the traditional Unix filesystem. * * - Segments in the path are delimited by slashes. * - The empty string refers to the current level of the tree (eg. root). * - Keys are case insensitive yet preserve case information. * - Paired slashes are converted to single slashes. * - Trailing slashes are discarded. * * The following paths are equivalent when canonicalized: * * - foo/key (the canonical representation) * - Foo/Key (also canonical but preserves case) * - /foo/key (converted to foo/key) * - foo//key (converted to foo/key) * - foo/key/ (converted to foo/key) * * Keys that may contain slashes or nulls should be escaped in some fashion * prior to constructing a UniConfKey object. Simply prefixing slashes with * backslashes is inadequate because UniConfKey does not give any special * meaning to backslash. */ class UniConfKey { class Segment : public WvString { public: Segment() : WvString(WvString::empty) { } Segment(WvStringParm str) : WvString((!str)? WvString::empty: str) { } Segment(const Segment &segment) : WvString(segment) { } bool iswild() const { return *this == "*" || *this == "..."; } }; class SegmentVector { int _size, _used; Segment *vec; public: SegmentVector(int size) : _size(size), _used(0), vec(new Segment[_size]) { } ~SegmentVector() { deletev vec; } void resize(int size, int shift = 0) { if (size <= _size) { if (shift > 0) { for (int i=_used-1; i>=0; --i) vec[i+shift] = vec[i]; _used += shift; } return; } Segment *old_vec = vec; vec = new Segment[size]; if (old_vec) { int limit = size-shift; if (limit > _size) limit = _size; if (limit > _used) limit = _used; for (int i=0; i= _used) _used = index + 1; } void replace(int index, WvStringParm string) { replace(index, Segment(string)); } const Segment &operator [](int index) const { return vec[index]; } }; struct Store { SegmentVector segments; int ref_count; Store(int size, int _ref_count, WvStringParm key = WvString::null); }; Store *store; int left, right; static Store EMPTY_store; /*!< represents "" (root) */ static Store ANY_store; /*!< represents "*" */ static Store RECURSIVE_ANY_store; /*!< represents "..." */ UniConfKey(Store *_store, int _left, int _right) : store(_store), left(_left), right(_right) { store->ref_count++; } void unique(); void normalize(); UniConfKey &collapse(); public: static UniConfKey EMPTY; /*!< represents "" (root) */ static UniConfKey ANY; /*!< represents "*" */ static UniConfKey RECURSIVE_ANY; /*!< represents "..." */ /** Constructs an empty UniConfKey (the 'root'). */ UniConfKey() : store(&EMPTY_store), left(0), right(0) { store->ref_count++; } /** * Constructs a UniConfKey from a string. * * See the rules above for information about how the key string * is canonicalized. * * "key" is the key as a string */ UniConfKey(WvStringParm key) : store(new Store(4, 1, key)), left(0), right(store->segments.used()) { } /** * Constructs a UniConfKey from a string. * * See the rules above for information about how the key string * is canonicalized. This constructor only exists to help out the * C++ compiler with its automatic type conversions. * * "key" is the key as a string */ UniConfKey(const char *key) : store(new Store(4, 1, WvFastString(key))), left(0), right(store->segments.used()) { } /** Constructs a UniConfKey from an int. */ UniConfKey(int key) : store(new Store(1, 1, WvFastString(key))), left(0), right(store->segments.used()) { } /** * Copies a UniConfKey. * "other" is the key to copy */ UniConfKey(const UniConfKey &other) : store(other.store), left(other.left), right(other.right) { store->ref_count++; } /** * Constructs a UniConfKey by concatenating two keys. * "path" is the initial part of the new path * "key" is the tail of the new path */ UniConfKey(const UniConfKey &path, const UniConfKey &key); ~UniConfKey() { if (--store->ref_count == 0) delete store; } /** * Appends a path to this path. * "other" is the path */ void append(const UniConfKey &other); /** * Prepends a path to this path. * "other" is the path */ void prepend(const UniConfKey &other); /** * Returns true if this path has zero segments (also known as root). * Returns: numsegments() == 0 */ bool isempty() const { return right == left; } /** Returns true if the key contains a wildcard. */ bool iswild() const; /** Returns true if the key has a trailing slash. */ bool hastrailingslash() const { return right > left && !store->segments[right-1]; } /** * Returns the number of segments in this path. * * The number of segments is equal to the number of slashes * in the path unless the path is "/" (the root), which has * zero segments. * * Returns: the number of segments */ int numsegments() const { return right - left; } /** * Returns the specified segment of the path. * "i" is the segment index * Returns: the segment */ UniConfKey segment(int n) const { return range(n, n + 1); } /** * Returns the path formed by the first n segments of this path and * removes them from the key. * Returns: the path */ UniConfKey pop(int n = 1); /** * Returns the path formed by the n first segments of this path. * "n" is the number of segments * Returns: the path */ UniConfKey first(int n = 1) const { return range(0, n); } /** * Returns the path formed by the n last segments of this path. * "n" is the number of segments * Returns: the path */ UniConfKey last(int n = 1) const { return range(numsegments() - n, INT_MAX); } /** * Returns the path formed by removing the first n segments of * this path. * "n" is the number of segments * Returns: the path */ UniConfKey removefirst(int n = 1) const { return range(n, INT_MAX); } /** * Returns the path formed by removing the last n segments of * this path. * "n" is the number of segments * Returns: the path */ UniConfKey removelast(int n = 1) const { return range(0, numsegments() - n); } /** * Returns a range of segments. * "i" is the first segment index, beginning if <= 0 * "j" is the last segment index, end if >= numsegments() * Returns: the path, empty if j <= i */ UniConfKey range(int i, int j) const; /** * Returns the canonical string representation of the path. * * If the UniConfKey was constructed in part or whole from * strings, then the string returned here will have the same * case information as those strings but the arrangement of * slashes may differ. That is, the identity * UniConfKey(string).printable() == string does not hold. * * Returns: the path as a string */ WvString printable() const; operator WvString() const { return printable(); } /** * Returns a (const char *) of printable() directly. */ const char *cstr() const { return printable(); } /** * Assigns this path to equal another. * "other" is the other path */ UniConfKey &operator= (const UniConfKey &other) { if (--store->ref_count == 0) delete store; store = other.store; left = other.left; right = other.right; ++store->ref_count; return *this; } /** * Compares two paths lexicographically. * Uses case-insensitive matching on the path string to produce * a total ordering of all paths. * "other" is the other path * Returns: 0 if *this == other, < 0 if *this < other, else > 0 */ int compareto(const UniConfKey &other) const; /** * Determines if the key matches a pattern. * Patterns are simply keys that may have path segments consiting * entirely of "*". Optional path segments are indicated by * the segment "..." which matches zero or more segments. * * Using wildcards to represent part of a segment is not supported yet. * "pattern" is the pattern * Returns: true if the key matches, false otherwise */ bool matches(const UniConfKey &pattern) const; /** * Returns true if 'key' is a the same, or a subkey, of this UniConfKey. */ bool suborsame(const UniConfKey &key) const; bool suborsame(const UniConfKey &key, UniConfKey &subkey) const; /** * If this UniConfKey is a subkey of 'key', then return the subkey * portion. Behaviour is undefined when this is not the same. Use * suborsame() to check. */ UniConfKey subkey(const UniConfKey &key) const; /** * Determines if two paths are equal. * "other" is the other path * Returns: true in that case */ bool operator== (const UniConfKey &other) const { return compareto(other) == 0; } /** * Determines if two paths are unequal. * "other" is the other path * Returns: true in that case */ bool operator!= (const UniConfKey &other) const { return compareto(other) != 0; } /** * Determines if this path precedes the other lexicographically. * "other" is the other path * Returns: true in that case */ bool operator< (const UniConfKey &other) const { return compareto(other) < 0; } class Iter; friend unsigned WvHash(const UniConfKey &k); }; DeclareWvList(UniConfKey); /** An iterator over the segments of a key. */ class UniConfKey::Iter { const UniConfKey &key; int seg, max; UniConfKey curseg; public: Iter(const UniConfKey &_key) : key(_key) { } void rewind() { seg = -1; max = key.numsegments(); } bool cur() { return seg >= 0 && seg < max; } bool next() { seg++; curseg = key.segment(seg); return cur(); } const UniConfKey *ptr() const { return &curseg; } WvIterStuff(const UniConfKey); }; #endif // __UNICONFKEY_H wvstreams-4.6.1/include/wvassert.h0000644000175000001440000000462711057766345016273 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Helper classes and functions to add more information to WvCrashes. */ #ifndef __WVASSERT_H #define __WVASSERT_H #include #include "wvcrash.h" #include "wvstring.h" // WvCrash allows you to print a programme's last will and testament. // That is, a little note about what it was hoping to do before it // died. // // This helper class lets you write a will, and when it gets // destroyed, it will restore the old will from before. This lets you // safely nest them. class WvCrashWill { public: // Leave a will behind. WvCrashWill(const char *will); WvCrashWill(WVSTRING_FORMAT_DECL); // Restore the will that was there before you created this object. ~WvCrashWill(); // Rewrite the will you're leaving behind. void rewrite(const char *will); void rewrite(WVSTRING_FORMAT_DECL); private: WvString old_will; }; #if !defined(__GLIBC__) # define wvassert(expr, args...) assert(expr) # define wvassert_perror(errnum) perror(errnum) #elif defined(NDEBUG) # define wvassert(expr, args...) (__ASSERT_VOID_CAST (0)) # define wvassert_perror(errnum) (__ASSERT_VOID_CAST (0)) #else // Not NDEBUG static inline void __wvcrash_leave_will() { } static inline void __wvcrash_leave_will(const char *will) { wvcrash_leave_will(will); } static inline void __wvcrash_leave_will(WVSTRING_FORMAT_DECL) { wvcrash_leave_will(WvFastString(WVSTRING_FORMAT_CALL)); } // Use this function instead of assert(). You may also leave parameters // at the end, which allow you to log messages. For instance: // // wvassert(a == b, "a: '%s'\n b: '%s'", a, b); # define wvassert(expr, args...) \ (__ASSERT_VOID_CAST ((expr) ? 0 : \ (__wvcrash_leave_will (args), \ (__assert_fail (__STRING(expr), __FILE__, __LINE__, \ __ASSERT_FUNCTION), 0)))) // Use this function instead of assert_perror(). You may also leave // parameters at the end, which allow you to log messages. For instance: // // wvassert(errno, "Error trying to read file: '%s'", filename); # define wvassert_perror(errnum, args...) \ (__ASSERT_VOID_CAST (!(errnum) ? 0 : \ (__wvcrash_leave_will (args), \ (__assert_perror_fail ((errnum), __FILE__, __LINE__, \ __ASSERT_FUNCTION), 0)))) #endif // NDEBUG #endif // WVASSERT_H wvstreams-4.6.1/include/wvfileutils.h0000644000175000001440000000577211077124114016754 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * Various little file functions... * */ #ifndef __WVFILEUTILS_H #define __WVFILEUTILS_H #include "wvstring.h" #include "wvstringlist.h" /** * Like mkdir(), but has the same parameters in both Unix and Windows. */ int wvmkdir(WvStringParm _dir, int create_mode = 0700); /** * Create a directory and any subdirectories required along the way. * (Equivalent to mkdir -p). * * The default permissions on created directories is 0700, but this can be * changed at will. */ int mkdirp(WvStringParm _dir, int create_mode = 0700); /** * Safely remove an entire filesystem directory hierarchy. * (Equivalent to rm -rf). Just like "rm -rf", it may or may not successfully * delete everything. It's your job to check that afterwards. */ void rm_rf(WvStringParm _dir); /** * Copy from src to dst preserving permissions and time stamp. This does not * preserve ownership, however. * * Two versions of this are provided. One for giving two filenames/paths, and * another for giving two starting directories and a relative path from there. */ bool fcopy(WvStringParm src, WvStringParm dst); bool fcopy(WvStringParm srcdir, WvStringParm dstdir, WvStringParm relname); /** * Create the file if it doesn't exist, or update the file's modification and * access times if it does. * (Equivalent to touch). */ bool ftouch(WvStringParm file, time_t mtime = 0); /** * Reads the contents of a symlink. Returns the contents, or * WvString::null on error. */ WvString wvreadlink(WvStringParm path); /** * Check whether two files have the same date/time stamp. This can be used as a * quick check whether files are unchanged / the same, though obviously it * doesn't verify that they are indeed the same file. * * Two versions are provided, one for giving two files, and another for giving * two starting directories and a relative path from there. */ bool samedate(WvStringParm file1, WvStringParm file2); bool samedate(WvStringParm dir1, WvStringParm dir2, WvStringParm relname); /** * Runs fnmatch against everything in the patterns list. We also interpret * .cvsignore-style '!' patterns, which makes us very fancy. */ #ifndef _WIN32 bool wvfnmatch(WvStringList &patterns, WvStringParm name, int flags = 0); #endif /** * Replacement for tmpfile() that works correctly in win32 as well as Unix. */ FILE *wvtmpfile(); /* Returns a unique filename suitable for a temporary file. Obviously there is * the caveat that someone else may claim this file name before you open it: * do not use this routine where that race may be a real concern (this would * apply only to security-sensitive code) */ WvString wvtmpfilename(WvStringParm prefix); #ifndef _WIN32 /** * Basically our own implementation of the NetBSD lchmod() call. */ int wvchmod(const char *path, mode_t mode); #endif /** * A simple helper function to get the current umask. */ #ifndef _WIN32 mode_t get_umask(); #endif #endif // __WVFILEUTILS_H wvstreams-4.6.1/include/wvbuf.h0000644000175000001440000002005711036722347015530 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Specializations of the generic buffering API and a few new buffers. */ #ifndef __WVBUFFER_H #define __WVBUFFER_H #include "wvstring.h" #include "wvbufbase.h" /***** Specialization for 'unsigned char' buffers *****/ /** * Specialization of WvBufBase for unsigned char type * buffers intended for use with raw memory buffers. * Refines the interface to add support for untyped pointers. * Adds some useful string operations. */ template <> class WvBufBase : public WvBufBaseCommonImpl { public: explicit WvBufBase(WvBufStore *store) : WvBufBaseCommonImpl(store) { } /** * Copies a WvString into the buffer, excluding the null-terminator. * "str" is the string */ void putstr(WvStringParm str); void putstr(WVSTRING_FORMAT_DECL) { putstr(WvString(WVSTRING_FORMAT_CALL)); } /** * Returns the entire buffer as a null-terminated WvString. * * If the buffer contains null characters, they will seem to * prematurely terminate the string. * * After this operation, ungettable() >= length of the string. * * Returns: the buffer contents as a string */ WvString getstr(); /** * Returns the first len characters in the buffer. * * This is equivalent to doing a get(len), but returns it as a WvString * instead of as an unsigned char *. */ WvString getstr(size_t len); /*** Get/put characters as integer values ***/ /** * Returns a single character from the buffer as an int. * * The same constraints apply as for get(1). * * Returns: the character */ int getch() { return int(get()); } /** * Puts a single character into the buffer as an int. * * The same constraints apply as for alloc(1). * * "ch" is the character */ void putch(int ch) { put((unsigned char)ch); } /** * Peeks a single character from the buffer as an int. * * The same constraints apply as for peek(offset, 1). * * "offset" is the offset * Returns: the character */ int peekch(int offset = 0) { return int(peek(offset)); } /** * Returns the number of characters that would have to be read * to find the first instance of the character. * "ch" is the character * Returns: the number of bytes, or zero if the character is not * in the buffer */ size_t strchr(int ch); /** * Returns the number of leading buffer elements that match * any of those in the list. * "bytelist" is the list bytes to search for * "numbytes" is the number of bytes in the list * Returns: the number of leading buffer elements that match */ size_t match(const void *bytelist, size_t numbytes) { return _match(bytelist, numbytes, false); } /** * Returns the number of leading buffer elements that match * any of those in the list. * "chlist" is a string of characters to search for * Returns: the number of leading buffer elements that match */ size_t match(const char *chlist) { return match(chlist, strlen(chlist)); } /** * Returns the number of leading buffer elements that do not * match any of those in the list. * "bytelist" is the list bytes to search for * "numbytes" is the number of bytes in the list * Returns: the number of leading buffer elements that don't match */ size_t notmatch(const void *bytelist, size_t numbytes) { return _match(bytelist, numbytes, true); } /** * Returns the number of leading buffer elements that do not * match any of those in the list. * "chlist" is a string of characters to search for * Returns: the number of leading buffer elements that don't match */ size_t notmatch(const char *chlist) { return notmatch(chlist, strlen(chlist)); } /*** Overload put() and move() to accept void pointers ***/ void put(unsigned char value) { WvBufBaseCommonImpl::put(value); } void put(const void *data, size_t count) { WvBufBaseCommonImpl::put( (const unsigned char*)data, count); } void move(void *data, size_t count) { WvBufBaseCommonImpl::move( (unsigned char*)data, count); } void poke(void *data, int offset, size_t count) { WvBufBaseCommonImpl::poke( (unsigned char*)data, offset, count); } private: // moved here to avoid ambiguities between the match variants size_t _match(const void *bytelist, size_t numbytes, bool reverse); }; /***** Declarations for some commonly used memory buffers *****/ /** * The in place raw memory buffer type. * Refines the interface to add support for untyped pointers. */ class WvInPlaceBuf : public WvInPlaceBufBase { public: WvInPlaceBuf(void *_data, size_t _avail, size_t _size, bool _autofree = false) : WvInPlaceBufBase((unsigned char*)_data, _avail, _size, _autofree) { } explicit WvInPlaceBuf(size_t _size) : WvInPlaceBufBase(_size) { } WvInPlaceBuf() : WvInPlaceBufBase() { } void reset(void *_data, size_t _avail, size_t _size, bool _autofree = false) { WvInPlaceBufBase::reset( (unsigned char*)_data, _avail, _size, _autofree); } }; /** * The const in place raw memory buffer type. * Refines the interface to add support for untyped pointers. */ class WvConstInPlaceBuf : public WvConstInPlaceBufBase { public: WvConstInPlaceBuf(const void *_data, size_t _avail) : WvConstInPlaceBufBase( (const unsigned char*)_data, _avail) { } WvConstInPlaceBuf() : WvConstInPlaceBufBase() { } void reset(const void *_data, size_t _avail) { WvConstInPlaceBufBase::reset( (const unsigned char*)_data, _avail); } }; /** * The circular in place raw memory buffer type. * Refines the interface to add support for untyped pointers. */ class WvCircularBuf : public WvCircularBufBase { public: WvCircularBuf(void *_data, size_t _avail, size_t _size, bool _autofree = false) : WvCircularBufBase((unsigned char*)_data, _avail, _size, _autofree) { } explicit WvCircularBuf(size_t _size) : WvCircularBufBase(_size) { } WvCircularBuf() : WvCircularBufBase() { } void reset(void *_data, size_t _avail, size_t _size, bool _autofree = false) { WvCircularBufBase::reset( (unsigned char*)_data, _avail, _size, _autofree); } }; /** The base raw memory buffer type. */ typedef WvBufBase WvBuf; /** The dynamically resizing raw memory buffer type. */ typedef WvDynBufBase WvDynBuf; /** The empty raw memory buffer type. */ typedef WvNullBufBase WvNullBuf; /** The raw memory buffer cursor type. */ typedef WvBufCursorBase WvBufCursor; /** The raw memory buffer view type. */ typedef WvBufViewBase WvBufView; /** A raw memory read-only buffer backed by a constant WvString */ class WvConstStringBuffer : public WvConstInPlaceBuf { WvString xstr; public: /** * Creates a new buffer backed by a constant string. * * "_str" is the string */ explicit WvConstStringBuffer(WvStringParm _str); /** Creates a new empty buffer backed by a null string. */ WvConstStringBuffer(); /** * Resets the buffer contents to a new string. * * "_str" is the new string */ void reset(WvStringParm _str); /** * Returns the string that backs the array * * Returns: the string */ WvString str() { return xstr; } }; #endif // __WVBUFFER_H wvstreams-4.6.1/include/wvwordwrap.h0000644000175000001440000000226611036722347016623 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A very simple word wrapping encoder. */ #ifndef __WVWORDWRAP_H #define __WVWORDWRAP_H #include "wvencoder.h" /** * Trivial word wrapper. * Recognizes newlines in input stream as end of line. * Words are output until no more will fit, in which case a newline * is output and the word is presented on the next line. Wrapped * word delimiter characters are discarded such that a wrapped word * will always be placed at the beginning of a line. */ class WvWordWrapEncoder : public WvEncoder { const int maxwidth; char *line; int width; // current visual position int curindex; // current index in line array int wordindex; // index of beginning of word in line array bool inword; // if true, we're in a word public: WvWordWrapEncoder(int maxwidth); virtual ~WvWordWrapEncoder(); protected: // on flush, outputs a partial line with remaining chars virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); virtual bool _reset(); // supported private: void flushline(WvBuf &outbuf); }; #endif // __WVWORDWRAP_H wvstreams-4.6.1/include/wvfile.h0000644000175000001440000000257411036722347015677 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A simple class to access filesystem files using WvStreams. */ #ifndef __WVFILE_H #define __WVFILE_H #include "wvfdstream.h" #include #ifdef _WIN32 #define O_NONBLOCK 0 #define O_LARGEFILE 0 #define fcntl(a,b,c) #endif /** * WvFile implements a stream connected to a file or Unix device. We * include no support for operations like seek(). Since files are not * really streams, you probably do not need WvStream support for seekable * files; just use standard C I/O functions in that case. * * WvFile is primarily useful for Unix device files, which have defined * select() behaviour for example. */ class WvFile : public WvFDStream { public: /** Create an empty WvFile that you'll open later with open() */ WvFile(); /** Create a WvFile from an existing fd. Not available in win32. */ WvFile(int rwfd); /** Create a WvFile given options like ::open() */ WvFile(WvStringParm filename, int mode, int create_mode = 0666); bool open(WvStringParm filename, int mode, int create_mode = 0666); bool open(int _rwfd); bool readable, writable; virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); public: const char *wstype() const { return "WvFile"; } }; #endif // __WVFILE_H wvstreams-4.6.1/include/wvdsa.h0000644000175000001440000000300111036722347015511 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * DSA cryptography abstractions. */ #ifndef __WVDSA_H #define __WVDSA_H #include "wverror.h" #include "wvencoder.h" #include "wvencoderstream.h" struct dsa_st; /** * An DSA public key or public/private key pair that can be used for * encryption. * * Knows how to encode/decode itself into a string of hex digits * for easy transport. */ class WvDSAKey : public WvErrorBase { WvString pub, prv; void init(WvStringParm keystr, bool priv); static WvString hexifypub(struct dsa_st *dsa); static WvString hexifyprv(struct dsa_st *dsa); public: struct dsa_st *dsa; WvDSAKey(const WvDSAKey &k); WvDSAKey(struct dsa_st *_dsa, bool priv); // note: takes ownership /** * Populate the DSA key with a hexified() key */ WvDSAKey(WvStringParm keystr, bool priv); /** * Create a new DSA key of bits strength. */ WvDSAKey(int bits); ~WvDSAKey(); virtual bool isok() const; /** * Retrieve the private key as a hexified string * returns WvString::null if there is only a public * key. */ WvString private_str() const { return prv; } /** * Retrieve the public key as a hexified string */ WvString public_str() const { return pub; } /** * Retrieve the public or private key in PEM encoded * format. */ WvString getpem(bool privkey); }; #endif // __WVDSA_H wvstreams-4.6.1/include/wvfdstream.h0000644000175000001440000000604711036722347016564 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Base class for streams built on Unix file descriptors. */ #ifndef __WVFDSTREAM_H #define __WVFDSTREAM_H #include "wvstream.h" /** * Base class for streams built on Unix file descriptors. * * WvFDStream distinguishes between read and write file descriptors * at creation time. Additionally, the reading and writing halves * may be independently shut down by calling noread() or nowrite(). * */ class WvFdStream : public WvStream { protected: /** The file descriptor for reading. */ int rfd; /** The file descriptor for writing. */ int wfd; /** Have we actually shut down the read/write sides? */ bool shutdown_read, shutdown_write; /** * Sets the file descriptor for both reading and writing. * Convenience method. */ void setfd(int fd) { rfd = wfd = fd; } public: /** * Creates a WvStream from an existing file descriptor. * "rwfd" is the file descriptor for reading and writing */ WvFdStream(int rwfd = -1); /** * Creates a WvStream from two existing file descriptors. * * The file decriptors may be the same. * * "rfd" is the file descriptor for reading * "wfd" is the file descriptor for writing */ WvFdStream(int rfd, int wfd); /** Destroys the stream and invokes close(). */ virtual ~WvFdStream(); /** * Returns the Unix file descriptor for reading from this stream. * Returns: the file descriptor, or -1 if none */ int getrfd() const { return rfd; } /** * Returns the Unix file descriptor for writing to this stream. * Returns: the file descriptor, or -1 if none */ int getwfd() const { return wfd; } /** * Returns the Unix file descriptor for reading and writing. * * Asserts that the file descriptors for reading and writing * are the same before returning. * * Returns: the file descriptor, or -1 if none */ int getfd() const { assert(rfd == wfd); return rfd; } /** Make the fds on this stream blocking or non-blocking. */ void set_nonblock(bool nonblock); /** Make the fds on this stream close-on-exec or not. */ void set_close_on_exec(bool close_on_exec); /***** Overridden members *****/ /** * Closes the file descriptors. * * If it is undesirable for the file descriptors to be closed by * this stream, duplicate the file descriptors using dup() before * creating the stream. * */ virtual void close(); virtual bool isok() const; virtual size_t uread(void *buf, size_t count); virtual size_t uwrite(const void *buf, size_t count); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void maybe_autoclose(); public: const char *wstype() const { return "WvFdStream"; } }; typedef WvFdStream WvFDStream; #endif // __WVFDSTREAM_H wvstreams-4.6.1/include/unitransaction.h0000644000175000001440000000226411036722347017440 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Allows one to wrap a UniConf tree with a transaction model. Use * UniTransaction::commit() to commit, and * UniTransaction::refresh() to rollback. */ #ifndef _UNITRANSACTION_H #define _UNITRANSACTION_H #include "unibachelorgen.h" #include "uniconfroot.h" #include "unitransactiongen.h" #include "uniunwrapgen.h" /** * Wraps an existing UniConf tree with a transaction generator. */ class UniTransaction : public UniConfRoot { friend class UniConf; friend class UniConf::Iter; friend class UniConf::RecursiveIter; public: UniTransaction(const UniConf &base) : UniConfRoot(new UniTransactionGen(new UniBachelorGen( new UniUnwrapGen(base))), false) { } // C++ would auto-generate a "copy constructor" for this function, but // what we really want is just to wrap a new transaction around the // base, just like any other UniConf object. UniTransaction(const UniTransaction &base) : UniConfRoot(new UniTransactionGen(new UniBachelorGen( new UniUnwrapGen(base))), false) { } }; #endif /* _UNITRANSACTION_H */ wvstreams-4.6.1/include/wvmagicloopback.h0000644000175000001440000000126111036722347017543 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. */ #ifndef __WVMAGICLOOPBACK_H #define __WVMAGICLOOPBACK_H #include "wvmagiccircle.h" #include "wvloopback.h" class WvMagicLoopback : public WvStream { public: WvMagicLoopback(size_t size); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual size_t uread(void *buf, size_t len); virtual size_t uwrite(const void *buf, size_t len); private: WvMagicCircle circle; WvLoopback loop; public: const char *wstype() const { return "WvMagicLoopback"; } }; #endif // __WVMAGICLOOPBACK_H wvstreams-4.6.1/include/wvprotostream.h0000644000175000001440000000341111036722347017326 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVPROTOSTREAM_H #define __WVPROTOSTREAM_H #include "wvstreamclone.h" class WvLog; /** * WvProtoStream is a framework that makes it easy to communicate using * common command-response driven protocols. This is supposed to be * flexible enough to handle FTP, HTTP, SMTP, tunnelv, Weaver rcmd, and * many others. */ class WvProtoStream : public WvStreamClone { public: class Token { public: WvString data; size_t length; Token(); Token(const unsigned char *_data, size_t _length); void fill(const unsigned char *_data, size_t _length); ~Token(); }; DeclareWvList(Token); WvDynBuf tokbuf; bool log_enable; WvProtoStream(WvStream *_cloned, WvLog *_debuglog = NULL); virtual ~WvProtoStream(); /** override uwrite() so we can log all output */ virtual size_t uwrite(const void *buffer, size_t size); // Routines to convert an input line into a set of Tokens. virtual Token *next_token(); WvString next_token_str(); WvString token_remaining(); virtual TokenList *tokenize(); size_t list_to_array(TokenList *tl, Token **array); Token *tokline(const char *line); /** Convert token strings to enum values */ int tokanal(const Token &t, const char **lookup, bool case_sensitive = false); // finite state machine int state; virtual void do_state(Token &t1); virtual void switch_state(int newstate); /** pass input through to the state machine, one line at a time */ virtual void execute(); protected: WvLog *logp; public: const char *wstype() const { return "WvProtoStream"; } }; #endif // __WVPROTOSTREAM_H wvstreams-4.6.1/include/unitempgen.h0000644000175000001440000000232711036722347016552 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that stores keys in memory. */ #ifndef __UNITEMPGEN_H #define __UNITEMPGEN_H #include "uniconfgen.h" #include "uniconftree.h" #include "wvstringcache.h" /** * A UniConf generator that stores keys in memory. * * Maintains a dirtyness indicator that is set whenever the contents * are changed. Also dispatches notifications on such changes. */ class UniTempGen : public UniConfGen { WvStringCache scache; public: UniConfValueTree *root; /*!< the root of the tree */ bool dirty; /*!< set whenever the tree actually changes */ UniTempGen(); virtual ~UniTempGen(); /***** Overridden members *****/ virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual void flush_buffers() { }; virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); virtual void commit(); virtual bool refresh(); protected: void notify_deleted(const UniConfValueTree *node, void *); }; #endif // __UNITEMPGEN_H wvstreams-4.6.1/include/wvpushdir.h0000644000175000001440000000175011202637334016425 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvPushDir -- A simple class to check the existance of a dir * and to properly return the formatted path of the diir */ #ifndef __WVPUSHDIR_H #define __WVPUSHDIR_H #include "wverror.h" #include #include #include #include class WvPushDir : public WvError { DIR *dir_handle; char *old_dir; public: void* operator new(size_t) { abort(); } WvPushDir(WvStringParm new_dir) { #ifdef MACOS old_dir = static_cast(calloc(PATH_MAX, sizeof(char *))); getcwd(old_dir, PATH_MAX);; #else old_dir = get_current_dir_name(); #endif dir_handle = opendir(old_dir); if (chdir(new_dir) == -1) errnum = errno; } ~WvPushDir() { chdir(old_dir); closedir(dir_handle); free(old_dir); } }; #endif /// __WVPUSHDIR_H wvstreams-4.6.1/include/wvsorter.h0000644000175000001440000000716411036722347016276 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * An iterator that can sort anything that has an iterator, includes the * right member functions, and uses WvLink objects - at the moment, * this includes WvList- and WvHashTable-based objects. */ #ifndef __WVSORTER_H #define __WVSORTER_H #include "wvxplc.h" #include "wvlink.h" // the base class for sorted list iterators. // It is similar to IterBase, except for rewind(), next(), and cur(). // The sorting is done in rewind(), which makes an array of WvLink // pointers and calls qsort. "lptr" is a pointer to the current WvLink * // in the array, and next() increments to the next one. // NOTE: we do not keep "prev" because it makes no sense to do so. // I guess Sorter::unlink() will be slow... // ...so we didn't implement it. class WvSorterBase { public: typedef int (CompareFunc)(const void *a, const void *b); void *list; void **array; void **lptr; WvSorterBase(void *_list) { list = _list; array = lptr = NULL; } ~WvSorterBase() { if (array) deletev array; } bool next() { return *(++lptr) != 0; } bool cur() { return *lptr != 0; } protected: template void rewind(CompareFunc *cmp); static int magic_compare(const void *_a, const void *_b); static CompareFunc *actual_compare; }; // the actual type-specific sorter. Set _list_ and _iter_ to be your // common base class (eg. WvListBase and WvListBase::IterBase) if possible, // so we don't need to generate a specific rewind(cmp) function for each // specific type of list. Since rewind(cmp) is the only non-inline function // in a sorter, that means you only need one of them per top-level container // type (ie. one for WvList and one for HashTable), not one per data type // you might store in such a container. template class WvSorter : public WvSorterBase { public: typedef int (RealCompareFunc)(const _type_ *a, const _type_ *b); RealCompareFunc *cmp; WvSorter(_list_ &_list, RealCompareFunc *_cmp) : WvSorterBase(&_list) { cmp = _cmp; } _type_ *ptr() const { return (_type_ *)(*lptr); } // declare standard iterator accessors WvIterStuff(_type_); void rewind() { WvSorterBase::rewind<_list_,_iter_>((CompareFunc *)cmp); } }; // Note that this is largely the same as WvLink::SorterBase::rewind(), // except we iterate through a bunch of lists instead of a single one. template void WvSorterBase::rewind(CompareFunc *cmp) { int n, remaining; if (array) deletev array; array = lptr = NULL; _iter_ i(*(_list_ *)list); // count the number of elements n = 0; for (i.rewind(); i.next(); ) n++; typedef void *VoidPtr; array = new VoidPtr[n+2]; void **aptr = array; *aptr++ = NULL; // initial link is NULL, to act like a normal iterator for (remaining = n, i.rewind(); i.next() && remaining; remaining--) { *aptr = i.vptr(); aptr++; } // weird: list length changed? // (this can happen with "virtual" lists like ones from WvDirIter) if (remaining) n -= remaining; *aptr = NULL; // sort the array. "Very nearly re-entrant" (unless the compare function // ends up being called recursively or something really weird...) CompareFunc *old_compare = actual_compare; actual_compare = cmp; qsort(array+1, n, sizeof(void *), magic_compare); actual_compare = old_compare; lptr = array; } #endif // __WVSORTER_H wvstreams-4.6.1/include/wvinterface.h0000644000175000001440000001024611036722347016713 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * Provides support for managing network interfaces. */ #ifndef __WVINTERFACE_H #define __WVINTERFACE_H #include "wvaddr.h" #include "wvhashtable.h" #include "wvlog.h" struct ifreq; struct iwreq; struct rtentry; /** * A WvInterface manages a particular network interface. It is _allowed_ * to have more than one WvInterface instance referring to the same * physical interface, because that is more convenient. */ class WvInterface { WvAddr *my_hwaddr; WvIPNet *my_ipaddr; WvLog err; /** used by addroute()/delroute() */ void fill_rte(struct rtentry *rte, char ifname[17], const WvIPNet &dest, const WvIPAddr &gw, int metric); int really_addroute(const WvIPNet &dest, const WvIPAddr &gw, const WvIPAddr &src, int metric, WvStringParm table, bool shutup); public: WvString name; bool valid; WvInterface(WvStringParm _name); ~WvInterface(); /** forget all stored information about the address(es) of this interface */ void rescan(); /** get the hardware address of this interface */ const WvAddr &hwaddr(); /** get the local IP net of this interface */ const WvIPNet &ipaddr(); /** get the point-to-point IP address of this interface */ const WvIPAddr dstaddr(); /** get the current kernel flags */ int getflags(); /** toggle kernel flags on this netdevice. Be careful! */ int setflags(int clear, int set); /** set the interface state up or down. */ bool isup(); void up(bool enable); /** turn promiscuous (see-all-packets) mode on or off. */ bool ispromisc(); void promisc(bool enable); /** turn point-to-point mode on or off.*/ int ptp(bool enable, const WvIPNet &addr); /** * Sets the local address, netmask, and broadcast of this interface * and set a route to the local net. * * Returns 0 on success, else an error code. */ int setipaddr(const WvIPNet &addr); /** * Sets the MTU of the interface. * * Returns 0 on success, else an error code. */ int setmtu(int mtu); /** * Set the hardware address of this interface * * Returns 0 on success, else an error code. */ int sethwaddr(const WvAddr &addr); /** add a route to the given network through this interface. */ int addroute(const WvIPNet &dest, int metric = 0, WvStringParm table = "default"); int addroute(const WvIPNet &dest, const WvIPAddr &gw, const WvIPAddr &src, int metric = 0, WvStringParm table = "default"); /** delete a route to the given network through this interface. */ int delroute(const WvIPNet &dest, int metric = 0, WvStringParm table = "default"); int delroute(const WvIPNet &dest, const WvIPAddr &gw, int metric = 0, WvStringParm table = "default"); /** add an ARP entry on this interface */ bool isarp(); int addarp(const WvIPNet &proto, const WvAddr &hw, bool proxy); /** get/set information about an interface */ int req(int ioctl_num, struct ifreq *ifr); /** get/set information about a wireless interface */ int req(int ioctl_num, struct iwreq *ifr); }; DeclareWvDict2(WvInterfaceDictBase, WvInterface, WvString, name); class WvInterfaceDict { public: WvLog log; static WvInterfaceDictBase slist; static int links; class Iter : public WvInterfaceDictBase::Iter { public: Iter(WvInterfaceDict &l) : WvInterfaceDictBase::Iter(l.slist) { } }; class Sorter : public WvInterfaceDictBase::Sorter { public: Sorter(WvInterfaceDict &l, WvInterfaceDictBase::Sorter::RealCompareFunc *f) : WvInterfaceDictBase::Sorter(l.slist, f) { } }; WvInterfaceDict(); ~WvInterfaceDict(); void update(); WvString islocal(const WvAddr &addr); bool on_local_net(const WvIPNet &addr); WvInterface *operator[] (WvStringParm str) { return slist[str]; } //operator WvInterfaceDictBase () // { return slist; } }; #endif // __WVINTERFACE_H wvstreams-4.6.1/include/uniclientconn.h0000644000175000001440000001056611036722347017253 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a connection between the UniConf client and daemon. */ #ifndef __UNICONFCONN_H #define __UNICONFCONN_H #include "uniconfkey.h" #include "uniconfgen.h" #include "wvstreamclone.h" #include "wvistreamlist.h" #include "wvbuf.h" #include "wvlog.h" #define UNICONF_PROTOCOL_VERSION UniClientConn::NUM_COMMANDS #define DEFAULT_UNICONF_DAEMON_TCP_PORT 4111 #define DEFAULT_UNICONF_DAEMON_SSL_PORT 4112 /** * Represents a connection to a UniConf daemon via any WvStream. * Makes several operations much simpler, such as TCL * encoding/decoding of lists, filling of the operation buffer and * comparison for UniConf operations. */ class UniClientConn : public WvStreamClone { WvDynBuf msgbuf; protected: WvLog log; bool closed; int version; public: WvConstStringBuffer payloadbuf; /*!< holds the previous command payload */ /* This table is _very_ important!!! * * With UniConf, we promise to never remove or modify the behaviour of * any of the commands listed here. If you want to modify anything, * you'd better just add a new command instead. We keep track of the * version of the UniConf protocol by the number of commands supported * by the server. * * @see UniClientConn::cmdinfos */ enum Command { NONE = -2, /*!< used to signal no command received */ INVALID = -1, /*!< used to signal invalid command */ // requests REQ_NOOP, /*!< noop ==> OK v18 */ REQ_GET, /*!< get ==> VAL ... OK / FAIL v18 */ REQ_SET, /*!< set ==> OK / FAIL v18 */ REQ_SETV, /*!< setv v19 */ REQ_REMOVE, /*!< del ==> OK / FAIL v18 */ REQ_SUBTREE, /*!< subt ==> VAL ... OK / FAIL v18 */ REQ_HASCHILDREN, /*!< hchild => HCHILD TRUE / FALSE v18 */ REQ_COMMIT, /*!< commit => OK v18 */ REQ_REFRESH, /*!< refresh => OK / FAIL v18 */ REQ_QUIT, /*!< quit ==> OK v18 */ REQ_HELP, /*!< help ==> TEXT ... OK / FAIL v18 */ // command completion replies REPLY_OK, /*!< OK v18 */ REPLY_FAIL, /*!< FAIL v18 */ REPLY_CHILD, /*!< HCHILD TRUE / FALSE v18 */ REPLY_ONEVAL, /*!< ONEVAL v18 */ // partial replies PART_VALUE, /*!< VAL v18 */ PART_TEXT, /*!< TEXT v18 */ // events EVENT_HELLO, /*!< HELLO v18 */ EVENT_NOTICE, /*!< NOTICE v18 */ }; static const int NUM_COMMANDS = EVENT_NOTICE + 1; struct CommandInfo { const char *name; const char *description; }; static const CommandInfo cmdinfos[NUM_COMMANDS]; /** Create a wrapper around the supplied WvStream. */ UniClientConn(IWvStream *_s, WvStringParm dst = WvString::null); virtual ~UniClientConn(); virtual void close(); /** * Reads a command from the connection. * "command" is the command that was read. * The payload is stored in UniClientConn::payloadbuf. * Returns: the command code, NONE, or INVALID */ Command readcmd(); Command readcmd(WvString &command); /** * Reads the next argument from the command payload. * Returns: the argument or WvString::null */ WvString readarg(); /** * Writes a command to the connection. * "command" is the command * "payload" is the payload */ void writecmd(Command command, WvStringParm payload = WvString::null); /** * Writes a REPLY_OK message. * "payload" is the payload, defaults to "" */ void writeok(WvStringParm payload = ""); /** * Writes a REPLY_FAIL message. * "payload" is the payload, defaults to "" */ void writefail(WvStringParm payload = ""); /** * Writes a PART_VALUE message. * "key" is the key * "value" is the value */ void writevalue(const UniConfKey &key, WvStringParm value); /** * Writes a PART_VALUE message. * "key" is the key * "value" is the value */ void writeonevalue(const UniConfKey &key, WvStringParm value); /** * Writes a PART_TEXT message. * "text" is the text */ void writetext(WvStringParm text); private: /** Reads a message from the connection. */ WvString readmsg(); /** Writes a message to the connection. */ void writemsg(WvStringParm message); }; #endif // __UNICONFCONN_H wvstreams-4.6.1/include/wvlockfile.h0000644000175000001440000000172011036722347016540 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A simple lockfile class using WvStreams. */ #ifndef __WVLOCKFILE_H #define __WVLOCKFILE_H #include "wvfile.h" class WvLockFile { public: WvLockFile(WvStringParm _lockname); /** Check to make sure no lock is established or that it's owned by us. */ bool isok(); /** Creates the lockfile with the current pid. Returns success/failure. */ bool lock(); /** * Removes the lockfile if present. If there's no lockfile after, * returns true, otherwise false. */ bool unlock(); /** * Returns one of three things: * -1 if the lockfile exists, but is inaccessible. * 0 if there is no lockfile, or the process is not running. * >0 The pid of the known-running process that owns the lock. */ pid_t readpid(); protected: WvString lockname; }; #endif // __WVLOCKFILE_H wvstreams-4.6.1/include/uniconfdaemonconn.h0000644000175000001440000000271011036722347020076 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a UniConf daemon session. */ #ifndef __UNICONFDAEMONCONN_H #define __UNICONFDAEMONCONN_H #include "uniconf.h" #include "uniclientconn.h" #include "unipermgen.h" #include "wvlog.h" #include "wvhashtable.h" #define NUM_WATCHES 113 #define CONTINUE_SELECT_AT 100 class UniConfDaemon; /** * Retains all state and behavior related to a single UniConf daemon * connection. */ class UniConfDaemonConn : public UniClientConn { public: UniConfDaemonConn(WvStream *s, const UniConf &root); virtual ~UniConfDaemonConn(); virtual void close(); virtual void execute(); protected: UniConf root; virtual void do_invalid(WvStringParm c); virtual void do_malformed(UniClientConn::Command); virtual void do_noop(); virtual void do_reply(WvStringParm reply); virtual void do_get(const UniConfKey &key); virtual void do_set(const UniConfKey &key, WvStringParm value); virtual void do_remove(const UniConfKey &key); virtual void do_subtree(const UniConfKey &key, bool recursive); virtual void do_haschildren(const UniConfKey &key); virtual void do_commit(); virtual void do_refresh(); virtual void do_quit(); virtual void do_help(); virtual void addcallback(); virtual void delcallback(); void deltacallback(const UniConf &cfg, const UniConfKey &key); }; #endif // __UNICONFDAEMONCONN_H wvstreams-4.6.1/include/wvlistener.h0000644000175000001440000000675411044160724016603 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A base implementation for "listeners", streams that spawn other streams * from (presumably) incoming connections. */ #ifndef __WVLISTENER_H #define __WVLISTENER_H #include "iwvlistener.h" #include "wvstreamclone.h" // FIXME needed *only* for CompatCallback #include "wvattrs.h" class WvListener : public IWvListener { IMPLEMENT_IOBJECT(WvListener); WvAttrs attrs; public: IWvStream *cloned; IWvListenerCallback acceptor; IWvListenerWrapper wrapper; WvListener(IWvStream *_cloned); virtual ~WvListener(); virtual void addwrap(IWvListenerWrapper _wrapper); virtual IWvListenerCallback onaccept(IWvListenerCallback _cb); IWvStream *wrap(IWvStream *s); void runonce(time_t msec_delay); // // IWvStream default implementation. // virtual void close() { if (cloned) cloned->close(); } virtual bool isok() const { return WvErrorBase::isok() && cloned && cloned->isok(); } virtual void callback(); int getfd() const { return getrfd(); } virtual int getrfd() const { return cloned ? cloned->getrfd() : -1; } virtual int getwfd() const { return cloned ? cloned->getwfd() : -1; } virtual const WvAddr *src() const { return cloned ? cloned->src() : NULL; } virtual void pre_select(SelectInfo &si) { if (cloned) cloned->pre_select(si); } virtual bool post_select(SelectInfo &si) { return cloned ? cloned->post_select(si) : false; } virtual size_t read(void *buf, size_t count) { return 0; } virtual size_t write(const void *buf, size_t count) { return 0; } virtual size_t read(WvBuf &outbuf, size_t count) { return 0; } virtual size_t write(WvBuf &inbuf, size_t count = INT_MAX) { return 0; } virtual void noread() { } virtual void nowrite() { } virtual void maybe_autoclose() { } virtual bool isreadable() { return false; } virtual bool iswritable() { return false; } virtual bool flush(time_t msec_timeout) { return false; } virtual bool should_flush() { return false; } virtual IWvStreamCallback setreadcallback(IWvStreamCallback _cb) { return 0; } virtual IWvStreamCallback setwritecallback(IWvStreamCallback _cb) { return 0; } virtual IWvStreamCallback setexceptcallback(IWvStreamCallback _cb) { return 0; } virtual IWvStreamCallback setclosecallback(IWvStreamCallback _cb) { return 0; } virtual const char *wsname() const { return "Listener"; } virtual void set_wsname(WvStringParm name) { } void set_wsname(WVSTRING_FORMAT_DECL) { set_wsname(WvString(WVSTRING_FORMAT_CALL)); } virtual const char *wstype() const { return "Listener"; } virtual WSID wsid() const { return 0; } virtual void outbuf_limit(size_t size) { } virtual WvString getattr(WvStringParm name) const; }; /** * This is a listener that doesn't work. You can use it for returning * weird errors. */ class WvNullListener : public WvListener { public: WvNullListener() : WvListener(NULL) { // nothing to do } virtual IWvStream *accept() { return NULL; } virtual bool isok() const { return false; } virtual const WvAddr *src() const; }; #endif // __WVLISTENER_H wvstreams-4.6.1/include/wvcallbacklist.h0000644000175000001440000000702611036722347017405 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVCALLBACKLIST_H #define __WVCALLBACKLIST_H #include #include template class WvCallbackList { private: std::map list; /* The idea of copying this gives me a headache. */ WvCallbackList(const WvCallbackList &); WvCallbackList& operator=(const WvCallbackList&); public: WvCallbackList() { } void add(const InnerCallback &cb, void *cookie) { assert(list.find(cookie) == list.end()); list.insert(std::make_pair(cookie, cb)); } void del(void *cookie) { typename std::map::iterator it = list.find(cookie); assert(it != list.end()); list.erase(it); } bool isempty() const { return list.empty(); } void operator()() const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(); } template void operator()(P1 &p1) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1); } template void operator()(P1 &p1, P2 &p2) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2); } template void operator()(P1 &p1, P2 &p2, P3 &p3) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3, p4); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3, p4, p5); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3, p4, p5, p6); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3, p4, p5, p6, p7); } template void operator()(P1 &p1, P2 &p2, P3 &p3, P4 &p4, P5 &p5, P6 &p6, P7 &p7, P8 &p8) const { typename std::map::const_iterator it; for (it = list.begin(); it != list.end(); ++it) it->second(p1, p2, p3, p4, p5, p6, p7, p8); } }; #endif /* __WVCALLBACKLIST_H */ wvstreams-4.6.1/include/wvqtstreamclone.h0000644000175000001440000000617211036722347017637 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVQTSTREAMCLONE_H #define __WVQTSTREAMCLONE_H #include #include #include #include #include #include "wvstreamclone.h" /** * Wraps another WvStream and attaches it to the normal Qt event loop. * * If you are using this object exclusively to manage all of your * streams, then you do not need to have a normal WvStreams * select()/callback() loop in your application at all. * * However, should you leave the Qt event loop and wish to continue * using this WvStream, call qt_detach() first, then run a normal * WvStreams event loop. If you do not do this, events may be * lost! Later, you may resume the Qt event loop at any time * by leaving your WvStreams event loop and calling qt_attach(). * * Multiple instances of this object may coexist to wrap different * WvStream's or WvStreamList's. * */ class WvQtStreamClone : public QObject, public WvStreamClone { Q_OBJECT int msec_timeout; SelectInfo si; bool pending_callback; bool first_time; bool select_in_progress; int last_max_fd; QIntDict notify_readable; QIntDict notify_writable; QIntDict notify_exception; QTimer select_timer; public: /** * WvQtStreamClone takes ownership of the stream you give it * just like WvStreamClone. See comments there. * * Timeout sets the time between polls with select(). * A value less than zero is regarded as an infinite timeout. */ WvQtStreamClone(IWvStream *_cloned = NULL, int msec_timeout = -1); virtual ~WvQtStreamClone(); // Call this to stop managing this stream via the Qt event loop. // Afterwards you may run a normal WvStream event loop based // on this object. void qt_detach(); // Call this to resume managing this stream via the Qt event loop. // This is the default state when the object is constructed. void qt_attach(); // Changes the timeout // You may need to adjust the timeout when using badly behaved streams void set_timeout(int msec_timeout); private: // Called before the Qt event loop does its select() void pre_poll(); // Called after the Qt event loop has finished its notifications void post_poll(); private slots: /** These things mark the beginning of a select pass **/ // Qt event loop hook (happens before each iteration) void qt_begin_event_loop_hook(); /** These things mark the end of a select pass **/ // Qt select timeout expired void select_timer_expired(); // Called when a file descriptor has been marked readable void fd_readable(int fd); // Called when a file descriptor has been marked writable void fd_writable(int fd); // Called when a file descriptor has been marked with an exception void fd_exception(int fd); // Needed or certain assertions fail ;) virtual void execute(); public: virtual void setclone(IWvStream *clone); }; #endif // __WVQTSTREAMCLONE_H wvstreams-4.6.1/include/wvconfemu.h0000644000175000001440000001607611036722347016416 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Basic WvConf emulation layer for UniConf. */ #ifndef __WVCONFEMU_H #define __WVCONFEMU_H #include "uniconfroot.h" #include "wvstringtable.h" #include "wvsorter.h" #define WvConf WvConfEmu #define WvConfigSection WvConfigSectionEmu #define WvConfigSectionList WvConfigSectionListEmu #define WvConfigEntry WvConfigEntryEmu #define WvConfigEntryList WvConfigEntryListEmu class WvConfEmu; class WvConfigEntryEmu; class WvConfigSectionEmu; class WvAuthDaemon; class WvAuthDaemonSvc; typedef WvConfEmu WvConfigSectionListEmu; typedef WvConfigSectionEmu WvConfigEntryListEmu; class WvConfigEntryEmu { public: const WvString name; WvString value; WvConfigEntryEmu(WvStringParm _name, WvStringParm _value): name(_name), value(_value) {} }; DeclareWvDict(WvConfigEntryEmu, WvString, name); class WvConfigSectionEmu { private: const UniConf uniconf; WvConfigEntryEmuDict entries; WvStringTable &values; public: const WvString name; WvConfigSectionEmu(const UniConf& _uniconf, WvStringParm _name, WvStringTable *_values): uniconf(_uniconf), entries(42), values(*_values), name(_name) {} WvConfigEntryEmu *operator[] (WvStringParm s); const char *get(WvStringParm entry, const char *def_val = NULL); void set(WvStringParm entry, WvStringParm value); void quick_set(WvStringParm entry, WvStringParm value); bool isempty() const; class Iter; friend class Iter; typedef WvSorter Sorter; }; DeclareWvDict(WvConfigSectionEmu, WvString, name); class WvConfigSectionEmu::Iter { private: WvConfigSectionEmu& sect; UniConf::RecursiveIter iter; WvLink link; WvConfigEntryEmu* entry; public: Iter(WvConfigSectionEmu& _sect): sect(_sect), iter(_sect.uniconf), link(NULL, false), entry(NULL) { assert(&_sect); } ~Iter(); void rewind(); WvLink *next(); WvLink *cur(); WvConfigEntryEmu* ptr() const; void* vptr() const; WvIterStuff(WvConfigEntryEmu); }; // parameters are: userdata, section, entry, oldval, newval typedef wv::function WvConfCallback; class WvConfEmu { private: struct CallbackInfo { WvConfCallback callback; void* userdata; WvString section; WvString key; void* cookie; CallbackInfo(WvConfCallback _callback, void* _userdata, WvStringParm _section, WvStringParm _key, void* _cookie): callback(_callback), userdata(_userdata), section(_section), key(_key), cookie(_cookie) {} }; WvConfigSectionEmuDict sections; bool hold; bool dirty; WvList callbacks; WvStringTable values; void notify(const UniConf &_uni, const UniConfKey &_key); public: const UniConf uniconf; WvConfEmu(const UniConf &_uniconf); ~WvConfEmu(); void zap(); bool isclean() const; bool isok() const; void load_file(WvStringParm filename); void save(WvStringParm filename, int _create_mode = 0666); void save(); void flush(); WvConfigSectionEmu *operator[] (WvStringParm sect); void add_callback(WvConfCallback callback, void *userdata, WvStringParm section, WvStringParm key, void *cookie); void del_callback(WvStringParm section, WvStringParm key, void *cookie); void add_setbool(bool *b, WvStringParm _section, WvStringParm _key); void del_setbool(bool *b, WvStringParm _section, WvStringParm _key); // The addname callback will add the key "ent" in "sect" to the "list" // whenever "ent" changes. If ent is empty, add any key in the sect to // the list when one is added/deleted/changed void add_addname(WvStringList *list, WvStringParm sect, WvStringParm ent); void del_addname(WvStringList *list, WvStringParm sect, WvStringParm ent); WvString getraw(WvString wvconfstr, int &parse_error); int getint(WvStringParm section, WvStringParm entry, int def_val); const char *get(WvStringParm section, WvStringParm entry, const char *def_val = NULL); int fuzzy_getint(WvStringList §, WvStringParm entry, int def_val); const char *fuzzy_get(WvStringList §, WvStringParm entry, const char *def_val = NULL); void setraw(WvString wvconfstr, const char *&value, int &parse_error); void setint(WvStringParm section, WvStringParm entry, int value); void set(WvStringParm section, WvStringParm entry, const char *value); void maybesetint(WvStringParm section, WvStringParm entry, int value); void maybeset(WvStringParm section, WvStringParm entry, const char *value); void delete_section(WvStringParm section); // Gets a user's password and decrypts it. This isn't defined in wvconf.cc. WvString get_passwd(WvStringParm sect, WvStringParm user); WvString get_passwd(WvStringParm user) { return get_passwd("Users", user); } WvString get_passwd2(WvString pwenc); // Check the password passed in. This isn't defined in wvconf.cc // We use this function to check passwords since we may not know what // the password actually is! // If s is not null and has continue_select enabled, check_passwd will // pause if the password is incorrect (the pause length depends on how // many password failures have occurred recently). bool check_passwd(WvStringParm sect, WvStringParm user, WvStringParm passwd, WvStream *s); bool check_passwd(WvStringParm user, WvStringParm passwd, WvStream *s) { return check_passwd("Users", user, passwd, s); } // Check if the user exists. This isn't defined in wvconf.cc bool user_exists(WvStringParm sect, WvStringParm user); bool user_exists(WvStringParm user) { return user_exists("Users", user); } // Encrypts and sets a user's password. This isn't defined in wvconf.cc. void set_passwd(WvStringParm sect, WvStringParm user, WvStringParm passwd); void set_passwd(WvStringParm user, WvStringParm passwd) { set_passwd("Users", user, passwd); } WvString set_passwd2(WvStringParm passwd); // Converts all passwords to unencrypted format. Not defined in wvconf.cc. void convert_to_old_pw(); static int check_for_bool_string(const char *s); class Iter; friend class Iter; private: /* The following is an ugly hack, but since WvConf is being * deprecated, we don't care. * * It seems that check_passwd() and user_exists() need to talk to a * WvAuthDaemon. However, making them virtual functions would break since * everyone else has to implement them. So we'll its pointer and accessors * here. */ private: WvAuthDaemon *wvauthd; // Authentication Daemon public: friend class WvAuthDaemonSvc; }; class WvConfEmu::Iter { WvConfEmu& conf; UniConf::Iter iter; WvLink link; public: Iter(WvConfEmu& _conf): conf(_conf), iter(conf.uniconf), link(NULL, false) {} void rewind(); WvLink *next(); WvConfigSectionEmu* ptr() const; WvIterStuff(WvConfigSectionEmu); }; #endif // __WVCONFEMU_H wvstreams-4.6.1/include/wvdiriter.h0000644000175000001440000000413011202637334016404 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Directory iterator. Recursively uses opendir and readdir, so you don't * have to. Basically implements 'find'. * */ #ifndef __WVDIRITER_H #define __WVDIRITER_H #include #include #include #include "wvstring.h" #include "wvlinklist.h" #include "strutils.h" struct WvDirEnt : public stat /***************************/ { // we already have everything from struct stat, but let's also include // some variations on the filename for convenience. WvString fullname; // contains: startdir/path/file WvString name; // contains: file WvString relname; // contains: path/file }; class WvDirIter /*************/ { private: bool recurse; bool go_up; bool skip_mounts; bool found_top; WvDirEnt topdir; WvDirEnt info; WvString relpath; struct Dir { Dir( DIR * _d, WvString _dirname ) : d( _d ), dirname( _dirname ) {} ~Dir() { if( d ) closedir( d ); } DIR * d; WvString dirname; }; DeclareWvList( Dir ); DirList dirs; DirList::Iter dir; public: // the sizeof(stat) helps an assert() in wvdiriter.cc. WvDirIter( WvStringParm dirname, bool _recurse = true, bool _skip_mounts = false, size_t sizeof_stat = sizeof(struct stat) ); ~WvDirIter(); bool isok() const; bool isdir() const; void rewind(); bool next(); // calling up() will abandon the current level of recursion, if, for // example, you decide you don't want to continue reading the contents // of the directory you're in. After up(), next() will return the next // entry after the directory you've abandoned, in its parent. void up() { go_up = true; } const WvDirEnt *ptr() const { return &info; } WvIterStuff(const WvDirEnt); int depth() const { return( dirs.count() ); } }; #endif wvstreams-4.6.1/include/uniunwrapgen.h0000644000175000001440000000525411036722347017123 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004 Net Integration Technologies, Inc. * * A totally evil UniConfGen that "unwraps" a UniConf object by turning it * back into a UniConfGen. */ #ifndef __UNIUNWRAPGEN_H #define __UNIUNWRAPGEN_H #include "uniconf.h" /** * Deprecated: a UniConfGen that delegates all requests to an inner UniConf. * This is sort of like UniFilterGen, except that it has the extremely * questionable behaviour of turning a UniConf (which normally wraps a * UniConfGen) back into a UniConfGen. The problem is that IUniConfGen has * a stable API/ABI, while the UniConf object itself does not. * * On the other hand, we get some free features by doing this: in particular, * since a UniConf object can have multiple owners, it can be wrapped by * multiple UniUnwrapGen objects, which is almost as good as a UniConfGen * having multiple owners. Also, you can implement "symlinks" (mount a * subtree of your UniConf hierarchy somewhere else), "chroot" (export * only a subtree to clients, making sure they can't access above that point * in the tree), and other creative things. * * FIXME: a much cleaner way to do this would be to move the * callback-multiplexing and subtree-accessing parts of UniConfRoot into their * own generators, so that we could use these features without going through * a UniConfRoot. */ class UniUnwrapGen : public UniConfGen { UniConf xinner; UniConfKey xfullkey; public: UniUnwrapGen(const UniConf &inner); virtual ~UniUnwrapGen(); void setinner(const UniConf &inner); /** Returns the inner generator. */ const UniConf &inner() const { return xinner; } /***** Overridden methods *****/ virtual void commit(); virtual bool refresh(); virtual void flush_buffers() { } virtual void prefetch(const UniConfKey &key, bool recursive); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual bool isok(); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); private: /** * Called by inner generator when a key changes. * The default implementation calls delta(key). */ virtual void gencallback(const UniConfKey &key, WvStringParm value); /** Like xinner[key], but skips calling [] if key.isnull(). */ UniConf _sub(const UniConfKey &key); class Iter; class RecursiveIter; bool refreshing, committing; }; #endif //__UNIUNWRAPGEN_H wvstreams-4.6.1/include/wvwinstreamclone.h0000755000175000001440000000233411036722347020007 0ustar wlachusers/* -*- Mode: C++ -*- */ #pragma once #include "wvstreamclone.h" #include #include #define WIN32_LEAN_AND_MEAN //#define NOMINMAX #include #define WM_SELECT (WM_USER) #define WM_DONESELECT (WM_USER+1) class WvWinStreamClone : public WvStreamClone { public: WvWinStreamClone(WvStream *_cloned); ~WvWinStreamClone(); static DWORD Initialize(); private: // types typedef std::map SocketEventsMap; typedef std::map WndStreamMap; typedef std::vector WndVector; // class members static ATOM s_aClass; static WndVector s_wndpool; static WndStreamMap s_wndmap; const static UINT_PTR TIMER_ID = 12345; static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // instance members SelectInfo m_si; int m_msec_timeout; HWND m_hWnd; bool m_pending_callback; bool m_select_in_progress; void pre_poll(); void post_poll(); void select_set(SocketEventsMap &sockmap, fd_set *set, long event ); void select_callback(SOCKET socket, int event, int error); HWND alloc_wnd(); void free_wnd(HWND w); public: void setclone(IWvStream *newclone); }; wvstreams-4.6.1/include/unireadonlygen.h0000644000175000001440000000131411036722347017415 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A read only generator wrapper. */ #ifndef __UNIREADONLYGEN_H #define __UNIREADONLYGEN_H #include "unifiltergen.h" /** * A generator that wraps another generator and makes it read only. * * To mount, use the moniker "readonly:" followed by the * moniker of the generator to wrap. * */ class UniReadOnlyGen : public UniFilterGen { public: UniReadOnlyGen(IUniConfGen *inner) : UniFilterGen(inner) { } /***** Overridden members *****/ virtual void flush_buffers() { } virtual void set(const UniConfKey &key, WvStringParm value) { }; }; #endif // __UNICONFREADONLY_H wvstreams-4.6.1/include/wvlogfile.h0000644000175000001440000000267411036722347016402 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A "Log Receiver" that logs messages to a file */ #ifndef __WVLOGFILE_H #define __WVLOGFILE_H #include "wvfile.h" #include "wvlogrcv.h" /// Basic WvLogRcv that logs to a file. Always logs to the same file. /// No auto-rotation of log files. class WvLogFileBase : public WvLogRcv, public WvFile { public: WvLogFileBase(WvStringParm _filename, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); // run fsync() every so many log messages. 0 never fsyncs. int fsync_every; protected: WvLogFileBase(WvLog::LogLevel _max_level); virtual void _make_prefix(time_t now_sec); virtual void _mid_line(const char *str, size_t len); virtual void _end_line(); int fsync_count; }; /// A more advanced WvLogFileBase. Logs to a file named .. /// Deletes old log files after 'keep_for' days. class WvLogFile : public WvLogFileBase { public: WvLogFile(WvStringParm _filename, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS, int _keep_for = 7, bool _force_new_line = false, bool _allow_append = true); WvString start_log(); private: virtual void _make_prefix(time_t now_sec); int keep_for, last_day; WvString filename; bool allow_append; public: const char *wstype() const { return "WvLogFileBase"; } }; #endif // __WVLOGFILE_H wvstreams-4.6.1/include/wvpipe.h0000644000175000001440000001054011036722347015705 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Provides support for piping data to/from subprocesses. */ #ifndef __WVPIPE_H #define __WVPIPE_H #include "wvfdstream.h" #include "wvsubproc.h" /** * Implementation of a WvPipe stream. These allow you to create a new * process, attaching its stdin/stdout to a WvStream. * * Unlike pipes created with the popen() system call, you can capture * both stdin and stdout for the given process. This is because we * actually use the socketpair() call instead. If you try this, * however, you must be very careful to always use the select() call * before reading from the stream. (Think what would happen if both * ends of the pipe do a read() simultaneously!) * * Note that we do not go as far as actually using a pty. That means * programs which deliberately open /dev/tty will not be redirected. * * When the WvPipe is destroyed, it makes sure that the child process * is killed. Since it tries to do it politely (SIGTERM, wait up to * 2 seconds, SIGKILL) it can take up to 2 seconds to destroy a * WvPipe. */ class WvPipe : public WvFDStream { WvSubProc proc; protected: void setup(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, int stdin_fd, int stdout_fd, int stderr_fd, WvStringList *env); public: /** * default pipe constructor; if you just want to use a pipe, use this. * For each of stdin, stdout, and stderr of the child process, it can * do one of three things: * - leave it alone (ie. the same as for the parent process) * - redirect it through the WvPipe (eg. if writable==true) * - redirect it to any open file descriptor (std*_fd are only * used if the corresponding bool is false, however) * Note that you need either writable or readable set to true if you * want the pipe to close automatically (for instance, when it's * appened to the globallist). Use the ignore_read() callback if * you really don't care about its output. */ WvPipe(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2, WvStringList *env = NULL); /** * This constructor does much the same thing as the previous one, * except that std*_str are WvStreams instead. The target process * accesses the 'fd' member of the stream (NOT using * the WvStream read() and write() functions). * * Again, we only redirect to the given WvStreams if the corresponding * bool is false; otherwise, we redirect to the pipe. * * It is okay for the same WvStream to occur more than once. Also, * you must naturally make sure that the stream doesn't disappear * before WvPipe does! */ WvPipe(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, WvFDStream *stdin_str, WvFDStream *stdout_str = NULL, WvFDStream *stderr_str = NULL, WvStringList *env = NULL); /** * This constructor is the same again, except that it uses the features * of the WvFDStream class to get all its fds from one place. */ WvPipe(const char *program, const char **argv, bool writable, bool readable, bool catch_stderr, WvFDStream *stdio_str, WvStringList *env = NULL); /** kill the child process and close the stream. */ virtual ~WvPipe(); /** * send the child a signal * (signal names are defined in signal.h) */ void kill(int signum); /** wait for child to die. Returns exit_status() */ int finish(bool wait_children = true); /** returns true if child is dead. */ bool child_exited(); /** returns true if child is dead because of a signal. */ bool child_killed() const; /** * returns the exit status: * if child_killed()==true, the signal that killed the child. * if child_killed()==false, the return code of the program. */ int exit_status(); // returns pid int getpid() const { return proc.pid; }; // callback to ignore everything. see comment in wvpipe.cc. static void ignore_read(WvStream &s); public: const char *wstype() const { return "WvPipe"; } }; #endif // __WVPIPE_H wvstreams-4.6.1/include/wvstringtable.h0000644000175000001440000000164611036722347017275 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStrings are used a lot more often than WvStringTables, so the Table need * not be defined most of the time. Include this file if you need it. * */ #ifndef __WVSTRINGTABLE_H #define __WVSTRINGTABLE_H #include "wvstring.h" #include "wvscatterhash.h" DeclareWvScatterTable2(WvStringTableBase, WvString); class WvStringTable : public WvStringTableBase { // copy constructor: not defined anywhere! WvStringTable(const WvStringTable &t); public: WvStringTable(unsigned _numslots = 0) : WvStringTableBase(_numslots) {}; WvString join(const char *joinchars = " \t") const; void split(WvStringParm s, const char *splitchars = " \t\r\n", int limit = 0); void splitstrict(WvStringParm s, const char *splitchars = " \t\r\n", int limit = 0); }; #endif // __WVSTRINGTABLE_H wvstreams-4.6.1/include/xplc/0000755000175000001440000000000011202637334015164 5ustar wlachuserswvstreams-4.6.1/include/xplc/ICategoryManager.h0000644000175000001440000000355711077372756020546 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2003, Net Integration Technologies, Inc. * * 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 __XPLC_ICATEGORYMANAGER_H__ #define __XPLC_ICATEGORYMANAGER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include #include /** \interface ICategoryManager ICategoryManager.h xplc/ICategoryManager.h * * Let you register categories and obtain information about them. */ class ICategoryManager: public IObject { UNSTABLE_INTERFACE public: /** * Register a component with a category. Both are specified by * UUIDs. */ virtual void registerComponent(const UUID& category, const UUID& component, const char* extrastring) = 0; /** * Get a category object for the specified category. */ virtual ICategory* getCategory(const UUID&) = 0; }; DEFINE_IID(ICategoryManager, {0xb5f218a5, 0xb50a, 0x4e8c, {0x9e, 0x0e, 0x69, 0x2e, 0x17, 0xf0, 0xe2, 0x99}}); #endif /* __XPLC_ICATEGORYMANAGER_H__ */ wvstreams-4.6.1/include/xplc/factory.h0000644000175000001440000000430311077372756017022 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_FACTORY_H__ #define __XPLC_FACTORY_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include #include typedef IObject*(*FactoryFunc)(); /** * Generic factory class. Implements IFactory by calling the function * pointer that its constructor takes. */ class GenericFactory: public IFactory { IMPLEMENT_IOBJECT(GenericFactory); private: FactoryFunc factory; public: /** * Set up the generic factory. The generic factory will use the * function that the specified pointer indicates to answer to * IFactory::createObject requests. */ GenericFactory(FactoryFunc aFactory); /* IFactory */ virtual IObject* createObject(); }; #endif /* __XPLC_FACTORY_H__ */ wvstreams-4.6.1/include/xplc/uuid.h0000644000175000001440000001233011202637334016302 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2004, Stéphane Lajoie * * 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 __XPLC_UUID_H__ #define __XPLC_UUID_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * Universally Unique IDentifiers. * * A UUID is a sequence of 16 bytes that is unique throughout the * universe, and which can uniquely identify anything you might want. * It will never have a name conflict with any other UUID. To come up * with a UUID of your own, run the 'uuidgen' program that comes with * many Unix and Windows systems. Although any UUID is guaranteed to * be unique, there is a downside: it's almost impossible for a human * to read, understand, or remember the contents of a UUID. For a * less unique, human-readable alternative to UUIDs, see IMoniker. * * A UUID is what is known as a "strong name". It is like the name of * a class in a C++ program, or of a global variable, but the "strong" * part refers to how this name, unlike the name of a C++ class, is * unique and refers precisely to this one thing. C++ names are "weak * names", it is very easy to create two different things with the * same name, for example, classes named "String" are very common, and * two different "String" classes could not be used in the same * program. When making a single program, it is possible to avoid * these conflicts, but with a component system, you never know how * components will be used together, thus the need for strong names. * * The UUID is the standard way of looking up and indexing objects in * XPLC. All "well-known" objects you need to look for (such as the * standard XPLC moniker and category services, and other objects you * create yourself) will have a UUID you can look up using the service * manager. Note that objects referenced by a UUID are necessarily * "singletons" - that is, objects of a class that is only * instantiated once in any program. For example, a factory that * produces HelloWorld objects would have its own UUID - so you can * ask for a HelloWorldFactory and get "the" HelloWorldFactory - but * the HelloWorld objects it produces would not be findable by UUID. * (If they all had the same UUID, it wouldn't be very Universally * Unique, would it? And if they all had different UUIDs, how would * you know which UUID to look for?) * * Also: when you retrieve a different interface from an IObject using * its getInterface() method, you do so by looking up the UUID of that * interface, also known as an IID (which is just a nickname for UUID, * they are identical in meaning). Every interface must have an IID, * but the IID is the same for all objects implementing that * interface. However, you can have multiple objects implementing a * particular interface, and each of those objects will have its own * UUID. */ #if defined WIN32 || defined SOLARIS typedef unsigned long u_int32_t; typedef unsigned short u_int16_t; typedef unsigned char u_int8_t; #else #include #endif //@{ #ifndef GUID_DEFINED #define GUID_DEFINED /** * The structure underlying UUIDs. This is similar to the Windows * definition, for compatibility reasons. */ typedef struct _GUID { //@{ u_int32_t Data1; u_int16_t Data2; u_int16_t Data3; u_int8_t Data4[8]; //@} } GUID; #endif #ifndef UUID_DEFINED #define UUID_DEFINED typedef GUID UUID; #ifndef uuid_t #define uuid_t UUID #endif #endif //@} /// The NULL UUID. Nothing will ever have this UUID, I promise. static const UUID UUID_null = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; /** \struct XPLC_IID uuid.h xplc/uuid.h * * An Interface IDentifier. Every interface (abstract classes derived from * IObject) must have a unique IID, so that getInterface() can ask for that * interface. * * Generate a UUID for your IID using 'uuidgen', then declare your IID * using DEFINE_IID(ClassName). If you need to obtain the UUID corresponding * to that interface in the future, call the static function * XPLC_IID::get(). */ template struct XPLC_IID { }; /** * Used to define the IID of an interface. */ #define DEFINE_IID(iface, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11) \ static const UUID iface##_IID = u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11; \ template <> \ struct XPLC_IID { \ static const UUID& get() { \ return iface##_IID; \ } \ } #endif /* __XPLC_UUID_H__ */ wvstreams-4.6.1/include/xplc/IStaticServiceHandler.h0000644000175000001440000000323411077372756021534 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_ISTATICSERVICEHANDLER_H__ #define __XPLC_ISTATICSERVICEHANDLER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** * Service handler for statically linked components. */ class IStaticServiceHandler: public IServiceHandler { UNSTABLE_INTERFACE public: /** Adds an object to the static service handler. */ virtual void addObject(const UUID&, IObject*) = 0; /** Removes an object from the static service handler. */ virtual void removeObject(const UUID&) = 0; }; DEFINE_IID(IStaticServiceHandler, {0x0a599d64, 0x0684, 0x4c44, {0x8a, 0xbc, 0xab, 0xfd, 0x5d, 0xe0, 0x22, 0x59}}); #endif /* __XPLC_ISTATICSERVICEHANDLER_H__ */ wvstreams-4.6.1/include/xplc/IServiceHandler.h0000644000175000001440000000356211077372756020370 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_ISERVICEHANDLER_H__ #define __XPLC_ISERVICEHANDLER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * The service handler interface. */ #include /** \interface IServiceHandler IServiceHandler.h xplc/IServiceHandler.h * * Interface to an object which can be used to find other objects, * given their UUIDs. This is the most basic way to find objects in * %XPLC, no matter where they are. */ class IServiceHandler: public IObject { UNSTABLE_INTERFACE public: /** * Get the object corresponding to the given UUID. The returned object * is already addRef()ed. Returns NULL if there is no matching object. */ virtual IObject* getObject(const UUID&) = 0; }; /// IServiceHandler's IID DEFINE_IID(IServiceHandler, {0xe897384f, 0x3ba6, 0x46e3, {0xad, 0x06, 0x53, 0x76, 0x21, 0xa6, 0x0a, 0x03}}); #endif /* __XPLC_ISERVICEHANDLER_H__ */ wvstreams-4.6.1/include/xplc/core.h0000644000175000001440000000501011077372756016277 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2004, Pierre Phaneuf * * 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 __XPLC_CORE_H__ #define __XPLC_CORE_H__ #include extern "C" IServiceManager* XPLC_getServiceManager(); static const UUID XPLC_staticServiceHandler = {0xf8c76062, 0xf241, 0x4f38, {0x80, 0x8d, 0x73, 0x88, 0x31, 0x22, 0x89, 0xd8}}; static const UUID XPLC_moduleLoader = {0x59e3fa68, 0x807c, 0x4ecb, {0xbc, 0x26, 0xb8, 0x08, 0x37, 0xcb, 0x32, 0x7e}}; static const UUID XPLC_moduleManagerFactory = {0x251c9dfc, 0xc76b, 0x454e, {0xaa, 0xcb, 0x95, 0x8e, 0x06, 0x35, 0xe2, 0x72}}; static const UUID XPLC_genericFactory = {0x414a69c6, 0x3c9e, 0x49f7, {0xab, 0x08, 0xe5, 0x5c, 0x7b, 0x6c, 0x23, 0x34}}; static const UUID XPLC_monikers = {0x5ed8cb8f, 0x6938, 0x40f2, {0x92, 0x7c, 0x2f, 0x4c, 0xe2, 0x89, 0x3c, 0x0b}}; static const UUID XPLC_newMoniker = {0x9ec8028c, 0x45e3, 0x40ff, {0x97, 0xfc, 0x0b, 0x35, 0xca, 0x6e, 0xdc, 0xb5}}; static const UUID XPLC_categoryManager = {0xa7b3c486, 0x3725, 0x4500, {0xa4, 0x4c, 0x59, 0x13, 0x1d, 0x65, 0x9e, 0x20}}; #endif /* __XPLC_CORE_H__ */ wvstreams-4.6.1/include/xplc/module.h0000644000175000001440000000717511077372756016652 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2002, Stéphane Lajoie * * 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 __XPLC_MODULE_H__ #define __XPLC_MODULE_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * Structures and definitions related to the XPLC module ABI * (Application Binary Interface). */ #include #ifdef UNSTABLE #include #endif /** * XPLC module magic number. Used to ensure that we are dealing with a * valid XPLC module. */ #define XPLC_MODULE_MAGIC 0x58504c43UL /** * The current XPLC module ABI version. */ //@{ #ifdef UNSTABLE #define XPLC_MODULE_VERSION_MAJOR UINT_MAX #define XPLC_MODULE_VERSION_MINOR 0 #else #define XPLC_MODULE_VERSION_MAJOR 0 #define XPLC_MODULE_VERSION_MINOR 0 #endif //@} /** * Defines attributes required for exported symbols. */ #ifdef WIN32 #define ENTRYPOINT extern "C" __declspec(dllexport) #else #define ENTRYPOINT extern "C" #endif /** * Entry for a component. Modules have an array of these, where the * function pointed at by getObject will be used to obtain an * interface pointer when the requested UUID matches the one in uuid. */ struct XPLC_ComponentEntry { //@{ const UUID& uuid; IObject* (*getObject)(); //@} }; /** * Entry for a category registration. Modules have an array of these, * used to indicate the category information for the module. */ struct XPLC_CategoryEntry { //@{ const UUID& category; const UUID& uuid; const char* const string; //@} }; /** * Information for an XPLC module. */ struct XPLC_ModuleInfo { /** * XPLC module magic number. This is to ensure that it is in fact a * valid XPLC module that has been loaded. */ unsigned long magic; /** * The XPLC module ABI version that this module conforms to. This * should always be the first member of the XPLC_ModuleInfo * structure, as the meaning of the following members depend on it. */ unsigned int version_major; /** * The XPLC module ABI sub-version that this module conforms * to. This is used for optional and backward-compatible changes in * the module ABI. */ unsigned int version_minor; /** * Description string for the module. */ const char* description; /** * List of components supported by the module. This is a pointer to * the list of components that will be made available by this * module. */ const XPLC_ComponentEntry* const components; /** * List of category registrations for the module. */ const XPLC_CategoryEntry* const categories; }; /** * Definition of the XPLC module information structure. This structure * should be initialized appropriately in a loadable XPLC module. */ ENTRYPOINT const XPLC_ModuleInfo XPLC_Module; #endif /* __XPLC_MODULE_H__ */ wvstreams-4.6.1/include/xplc/xplc.h0000644000175000001440000000715511077372756016331 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_XPLC_H__ #define __XPLC_XPLC_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * The XPLC helper class for the C++ binding. */ #include #include #include /** \class XPLC xplc.h xplc/xplc.h * * The XPLC helper class. This class is part of the XPLC C++ binding * in order to provide a more natural C++ feel to the use of XPLC. */ class XPLC { private: xplc_ptr servmgr; public: XPLC(): servmgr(XPLC_getServiceManager()) {} /** * Create an XPLC object using an existing service manager * reference. */ XPLC(IServiceManager* _servmgr): servmgr(do_addRef(_servmgr)) {} /** * Adds a directory to the module loader path. */ void addModuleDirectory(const char* directory); /** * Obtain an XPLC object. Obtains an object with the provided UUID * from the service manager. */ IObject* get(const UUID& uuid) { return servmgr->getObject(uuid); } /** * Templated variant of XPLC::get() that will do a getInterface() * for you. */ template Interface* get(const UUID& uuid) { return mutate(servmgr->getObject(uuid)); } /** * Object creation helper. Obtains an object with the provided UUID * from the service manager, tries to get the IFactory interface * from the object and calls its createObject() method. */ IObject* create(const UUID& cid); /** * Templated variant of XPLC::create() that will do a getInterface() * for you. */ template Interface* create(const UUID& cid) { return mutate(create(cid)); } /** * Object creation helper that operates from a moniker. Works like * XPLC::create(const UUID&), but finds the object using a moniker * instead. */ IObject* create(const char*); /** * Templated variant of XPLC::create(const char*) that will do a * getInterface() for you. */ template Interface* create(const char* aMoniker) { return mutate(create(aMoniker)); } }; #endif /* __XPLC_XPLC_H__ */ wvstreams-4.6.1/include/xplc/utils.h0000644000175000001440000001424411077372756016520 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2001, Stéphane Lajoie * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_UTILS_H__ #define __XPLC_UTILS_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * Various utility functions, macros and templates. */ #include #include #include /** * Utility structure used for the interface map. */ struct UUID_Info { //@{ const UUID* iid; ptrdiff_t delta; //@} }; /** * Start the interface map for "component". */ #define UUID_MAP_BEGIN(component) const UUID_Info component::xplc_iobject_uuids[] = { /** * Add an entry to an interface map. */ #define UUID_MAP_ENTRY(iface) { &iface##_IID, reinterpret_cast(static_cast(reinterpret_cast(1))) - 1 }, /** * Add an entry to an interface map for an ambiguous interface. The * second parameter is the interface that should be used to * disambiguate. */ #define UUID_MAP_ENTRY_2(iface, iface2) { &iface##_IID, reinterpret_cast(static_cast(reinterpret_cast(1))) - 1 }, /** * Marks the end of an interface map. */ #define UUID_MAP_END { 0, 0 } }; class WeakRef; /** * Helper internal structure. Used for implementing IMPLEMENT_IOBJECT. */ struct IObjectImplInternal { /** * Holds the reference count. */ unsigned int refcount; /** * Pointer to a weak reference object. This object is lazily * instantiated, so the pointer is NULL until a weak reference is * needed. */ WeakRef* weakref; IObjectImplInternal(): refcount(1), weakref(0) { } /** * Used to implement IObject::getInterface(). */ IObject* getInterface(void* self, const UUID& uuid, const UUID_Info* uuidlist); }; #ifndef xplcdelete /** * Internal macro. This macro is needed to cooperate correctly with * the "delete detector". */ #define xplcdelete delete #endif /** * Helper macro to implement the IObject methods automatically. Put * this at the beginning of your class, specifiying the class name as * the parameter, and it will automatically implement all the IObject * methods. You also need to define an interface map. * * \sa UUID_MAP_BEGIN, UUID_MAP_ENTRY, UUID_MAP_ENTRY_2, UUID_MAP_END */ #define IMPLEMENT_IOBJECT(component) \ private: \ IObjectImplInternal xplc_iobject_internal; \ static const UUID_Info xplc_iobject_uuids[]; \ typedef component ThisXPLCComponent; \ public: \ virtual unsigned int addRef() { \ return ++xplc_iobject_internal.refcount; \ } \ virtual unsigned int release() { \ if(--xplc_iobject_internal.refcount) \ return xplc_iobject_internal.refcount; \ /* protect against re-entering the destructor */ \ xplc_iobject_internal.refcount = 1; \ if(xplc_iobject_internal.weakref) { \ xplc_iobject_internal.weakref->release(); \ xplc_iobject_internal.weakref->object = 0; \ } \ xplcdelete this; \ return 0; \ } \ virtual IObject* getInterface(const UUID& uuid) { \ return xplc_iobject_internal.getInterface(this, uuid, xplc_iobject_uuids); \ } \ virtual IWeakRef* getWeakRef() { \ if(!xplc_iobject_internal.weakref) \ xplc_iobject_internal.weakref = new WeakRef(reinterpret_cast(reinterpret_cast(this) + xplc_iobject_uuids->delta)); \ xplc_iobject_internal.weakref->addRef(); \ return xplc_iobject_internal.weakref; \ } /** \class WeakRef * * Common implementation of a weak reference. */ class WeakRef: public IWeakRef { IMPLEMENT_IOBJECT(WeakRef); public: /** The object that the weak reference is pointing at. */ IObject* object; virtual IObject* getObject() { if(object) object->addRef(); return object; } /** * Initialize a weak reference. */ WeakRef(IObject* aObj): object(aObj) { } }; /** * %XPLC equivalent to dynamic_cast. This templated function is a * typesafe way to call the getInterface method of a component and * cast it properly. If the component does not support the interface, * a NULL pointer will be returned. */ template Interface* get(IObject* aObj) { if(!aObj) return 0; return static_cast(aObj->getInterface(XPLC_IID::get())); } /** * A version of get() that releases its parameter. This templated * function is very similar to the "get" one, except that it * automatically releases the inbound reference, without regard * whether the getInterface actually yielded something. */ template Interface* mutate(IObject* aObj) { Interface* rv; if(!aObj) return 0; rv = static_cast(aObj->getInterface(XPLC_IID::get())); aObj->release(); return rv; } #endif /* __XPLC_UTILS_H__ */ wvstreams-4.6.1/include/xplc/uuidops.h0000644000175000001440000000725711077372756017056 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2004, Stéphane Lajoie * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_UUIDOPS_H__ #define __XPLC_UUIDOPS_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include #if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ #define _SYS_GUID_OPERATOR_EQ_ /** * Equality operator for UUIDs. */ inline int operator==(const UUID& uuid1, const UUID& uuid2) { return (&uuid1 == &uuid2) || ((static_cast(&uuid1.Data1)[0] == static_cast(&uuid2.Data1)[0]) && (static_cast(&uuid1.Data1)[1] == static_cast(&uuid2.Data1)[1]) && (static_cast(&uuid1.Data1)[2] == static_cast(&uuid2.Data1)[2]) && (static_cast(&uuid1.Data1)[3] == static_cast(&uuid2.Data1)[3])); } /** * Inequality operator for UUIDs. */ inline int operator!=(const UUID& uuid1, const UUID& uuid2) { return (&uuid1 != &uuid2) && ((static_cast(&uuid1.Data1)[0] != static_cast(&uuid2.Data1)[0]) || (static_cast(&uuid1.Data1)[1] != static_cast(&uuid2.Data1)[1]) || (static_cast(&uuid1.Data1)[2] != static_cast(&uuid2.Data1)[2]) || (static_cast(&uuid1.Data1)[3] != static_cast(&uuid2.Data1)[3])); } #endif /** * Converts a printable C string to a UUID. The string is of the form * "9c318f06-52ec-4a62-b5fb-9279216e8586" (without the quotes), but * will also tolerate opening and closing braces before and after. * * This is the form produced by the 'uuidgen' program and is used in * the Windows registry. */ const UUID UuidFromString(const char* str); /** * Fill the given pointer with a printable string representing the * given UUID. The string is of the form * "9c318f06-52ec-4a62-b5fb-9279216e8586" (without the quotes). * * 'str' should point to at least 39 bytes of available memory. * Always returns 'str', which has been null-terminated. */ char* UuidToString(const UUID& uuid, char* str); #endif /* __XPLC_UUIDOPS_H__ */ wvstreams-4.6.1/include/xplc/IWeakRef.h0000644000175000001440000000315611077372756017015 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Pierre Phaneuf * * 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 __XPLC_IWEAKREF_H__ #define __XPLC_IWEAKREF_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IWeakRef IWeakRef.h xplc/IWeakRef.h * * Represents a weak reference to another object. */ class IWeakRef: public IObject { UNSTABLE_INTERFACE public: /** * Obtains an addRef()'d strong reference to the referenced * object. If the object has been destroyed, this will return * NULL. Do not forget to release() the strong reference when you * are done with it. */ virtual IObject* getObject() = 0; }; DEFINE_IID(IWeakRef, {0x6a97f962, 0xeeec, 0x48e2, {0xb4, 0x68, 0x56, 0x60, 0x57, 0x3f, 0xd9, 0x24}}); #endif /* __XPLC_IWEAKREF_H__ */ wvstreams-4.6.1/include/xplc/IObject.h0000644000175000001440000001106711077372756016677 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2002, Stéphane Lajoie * * 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 __XPLC_IOBJECT_H__ #define __XPLC_IOBJECT_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * This file contains the %XPLC foundation interface. */ #include #ifndef UNSTABLE /** * Used to mark an interface as unstable. Add an UNSTABLE_INTERFACE * declaration to your object if you don't want people to use your * interface without knowing the interface might change from * underneath them. They will then have to \#define UNSTABLE if they * want their program to compile. */ #define UNSTABLE_INTERFACE static bool UNSTABLE_INTERFACE = true; #else #define UNSTABLE_INTERFACE #endif class IWeakRef; /** \interface IObject IObject.h xplc/IObject.h * * The basic interface which is included by all other %XPLC interfaces * and objects. It provides a standard method to say you're using an * object, to say you're done, and to retrieve other %XPLC interfaces * from the object. * * Usually you will not implement these functions yourself; use * the IMPLEMENT_IOBJECT macro instead. * * \sa IMPLEMENT_IOBJECT, mutate(), get(), xplc_ptr, XPLC */ class IObject { UNSTABLE_INTERFACE public: /** * Indicate you are using this object. This increases the reference * count of the object by one. Usually, when the reference count * reaches zero, the object is freed automatically. * * This called a "strong reference", because they will prevent the * object from being destroyed. They should thus be used carefully, * as they control the lifetime of the object. For example, you do * not need to call addRef() on object passed as parameters, unless * you intend on keeping them. * * addRef() is often called automatically for you in %XPLC, but * you'll have to call release() by hand sometimes unless you use * xplc_ptr. */ virtual unsigned int addRef() = 0; /** * Indicate that you are finished using this object. This decreases * the reference count of the object by one. Usually, when the * reference count reaches zero, the object is freed automatically. * * You will usually need to manually release() any object given to * you by any other %XPLC function, unless you give the object to * someone else who will call release. * * If you use xplc_ptr, it will do this for you. */ virtual unsigned int release() = 0; /** * Returns the requested %XPLC interface. Will return NULL if the * interface is not supported. The returned interface has been * addRef()ed, so you will need to release() it when done. Note * that the interface returned may be a pointer to the same object * or a different one - that's none of your business. Asking for the * IObject interface should always return the same pointer for a * given logical object, so this can be used for comparison by * identity. * * You should probably use the convenient mutate() and get() * functions instead of this, or use an xplc_ptr, which mutates the * object for you. */ virtual IObject* getInterface(const UUID&) = 0; /** * Return a weak reference to this object. A weak reference points * at the object, but does not control the lifetime of the object. * An object can thus still be deleted while someone holds a weak * reference. You will still need to release() the weak reference * when you are done with it. * * \sa IWeakRef */ virtual IWeakRef* getWeakRef() = 0; }; /// IObject's IID DEFINE_IID(IObject, {0x8ca76e98, 0xb653, 0x43d7, {0xb0, 0x56, 0x8b, 0x9d, 0xde, 0x9a, 0xbe, 0x9d}}); #endif /* __XPLC_IOBJECT_H__ */ wvstreams-4.6.1/include/xplc/IMonikerService.h0000644000175000001440000000340011077372756020406 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_IMONIKERSERVICE_H__ #define __XPLC_IMONIKERSERVICE_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IMonikerService IMonikerService.h xplc/IMonikerService.h * * An interface for registering objects so they can be retrieved using * a moniker. * * You can obtain the %XPLC standard moniker service by getting the * XPLC_monikers UUID from the service manager. */ class IMonikerService: public IMoniker { UNSTABLE_INTERFACE public: /** * Register an object to be retrieved with a moniker. */ virtual void registerObject(const char* prefix, const UUID& uuid) = 0; }; DEFINE_IID(IMonikerService, {0x0ee2cc09, 0xd7d5, 0x44ee, {0xbc, 0x63, 0xf2, 0xb9, 0x03, 0x7d, 0xb9, 0x82}}); #endif /* __XPLC_IMONIKERSERVICE_H__ */ wvstreams-4.6.1/include/xplc/ICategoryIterator.h0000644000175000001440000000346311077372756020761 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2004, Pierre Phaneuf * * 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 __XPLC_ICATEGORYITERATOR_H__ #define __XPLC_ICATEGORYITERATOR_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface ICategoryIterator ICategoryIterator.h xplc/ICategoryIterator.h * * Allows iteration over a category. */ class ICategoryIterator: public IObject { UNSTABLE_INTERFACE public: /** Returns the UUID of the category entry. */ virtual const UUID& getUuid() = 0; /** Returns the string associated with the category entry. */ virtual const char* getString() = 0; /** Advances to the next category entry. */ virtual void next() = 0; /** Tests if the iterator is past the last item. The iterator is * invalid when this method returns true. */ virtual bool done() = 0; }; DEFINE_IID(ICategoryIterator, {0x87e48aae, 0xa1da, 0x4d9c, {0xa7, 0xc0, 0x7a, 0x5b, 0x88, 0xf4, 0x01, 0x7a}}); #endif /* __XPLC_ICATEGORYITERATOR_H__ */ wvstreams-4.6.1/include/xplc/IFactory.h0000644000175000001440000000307011077372756017073 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_IFACTORY_H__ #define __XPLC_IFACTORY_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IFactory IFactory.h xplc/IFactory.h * * Common object creation interface. */ class IFactory: public IObject { UNSTABLE_INTERFACE public: /** * Creates an object. * * The object returned by IFactory::createObject() is already * addRef()'d. */ virtual IObject* createObject() = 0; }; DEFINE_IID(IFactory, {0xcd386b27, 0x0ea1, 0x4e1b, {0xba, 0x08, 0xb8, 0x5e, 0xe4, 0xda, 0xad, 0x69}}); #endif /* __XPLC_IFACTORY_H__ */ wvstreams-4.6.1/include/xplc/IModuleLoader.h0000644000175000001440000000301111077372756020033 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Pierre Phaneuf * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * * 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 __XPLC_IMODULELOADER_H__ #define __XPLC_IMODULELOADER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IModuleLoader IModuleLoader.h xplc/IModuleLoader.h * * The interface to control the module loader. */ class IModuleLoader: public IObject { UNSTABLE_INTERFACE public: virtual IModule* loadModule(const char* modulename) = 0; }; DEFINE_IID(IModuleLoader, {0xa4143690, 0xfc54, 0x43f4, {0x9d, 0x7e, 0x50, 0x3c, 0x71, 0xff, 0xa5, 0x01}}); #endif /* __XPLC_IMODULELOADER_H__ */ wvstreams-4.6.1/include/xplc/ICategory.h0000644000175000001440000000267411077372756017252 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_ICATEGORY_H__ #define __XPLC_ICATEGORY_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include #include /** * Represents a category. */ class ICategory: public IObject { UNSTABLE_INTERFACE public: /** Gets an iterator for the category. */ virtual ICategoryIterator* getIterator() = 0; }; DEFINE_IID(ICategory, {0x90abfe8d, 0x50a9, 0x44d8, {0x96, 0x03, 0x29, 0x9c, 0x8b, 0x21, 0x9e, 0x5d}}); #endif /* __XPLC_ICATEGORYMANAGER_H__ */ wvstreams-4.6.1/include/xplc/IModuleManagerFactory.h0000644000175000001440000000261311077372756021536 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2004, Pierre Phaneuf * * 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 __XPLC_IMODULEMANAGERFACTORY_H__ #define __XPLC_IMODULEMANAGERFACTORY_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include class IModuleManagerFactory: public IObject { UNSTABLE_INTERFACE public: virtual IServiceHandler* createModuleManager(const char* directory) = 0; }; DEFINE_IID(IModuleManagerFactory,{0x9c88d2d0, 0xc61f, 0x41b7, {0x9d, 0x4d, 0xd2, 0xc6, 0xc0, 0x97, 0x94, 0x55}}); #endif /* __XPLC_IMODULEMANAGERFACTORY_H__ */ wvstreams-4.6.1/include/xplc/IMoniker.h0000644000175000001440000000440211077372756017070 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_IMONIKER_H__ #define __XPLC_IMONIKER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IMoniker IMoniker.h xplc/IMoniker.h * * An interface for obtaining an IObject given a moniker string. * * A moniker can be used to obtain a particular object using a * human-readable string to describe it, rather than having to know * the object's UUID. Human-readable strings are, unfortunately, not * guaranteed to be universally unique, so you might (theoretically) * not get the object you want. * * You can retrieve the standard %XPLC moniker service from the service * manager using the XPLC_monikers UUID, which can then be used to * resolve monikers and register your own using the IMonikerService * interface it provides. * * Note that XPLC::get() and XPLC::create() are a convenient interface * to the %XPLC moniker system. */ class IMoniker: public IObject { UNSTABLE_INTERFACE public: /** * Given a moniker string, return the IObject it refers to, or NULL if * no objects match. The returned object is already addRef()'d. */ virtual IObject* resolve(const char* moniker) = 0; }; DEFINE_IID(IMoniker, {0x6c0bb432, 0x7c32, 0x4614, {0xa5, 0xab, 0xb2, 0x5d, 0x92, 0x23, 0xda, 0xa2}}); #endif /* __XPLC_IMONIKER_H__ */ wvstreams-4.6.1/include/xplc/delete.h0000644000175000001440000000746711077372756016633 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2004, Net Integration Technologies, Inc. * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_DELETE_H__ #define __XPLC_DELETE_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * Include this file right after IObject.h (or instead of) to detect * accidental uses of "delete" on an %XPLC interface. Use "xplcdelete" * instead of "delete" when you know what you are doing. */ #include #include #ifdef __XPLC_IOBJECT_H__ #error " has to be included before ." #endif #include /** * \defgroup DeleteDetector This is the "delete detector". */ /// \ingroup DeleteDetector class CheckIObject {}; class CheckIObjectOk {}; /// \ingroup DeleteDetector class CheckIObjectOkVector {}; template class ConversionIObject { public: //@{ typedef char Yes; /// \ingroup DeleteDetector struct No { char dummy[2]; }; static T* from; static Yes test(const IObject*); static No test(...); //@} }; template struct XPLC_CTAssert; template<> /// \ingroup DeleteDetector struct XPLC_CTAssert {}; template inline void operator&&(CheckIObject, const T* obj) { static_cast(sizeof(XPLC_CTAssert<(sizeof(ConversionIObject::test(ConversionIObject::from)) != sizeof(typename ConversionIObject::Yes))>)); delete obj; } template inline void operator&&(CheckIObjectOk, const T* obj) { delete obj; } template inline void operator&&(CheckIObjectOkVector, const T* obj) { delete[] obj; } /** * Undefine xplcdelete. defines xplcdelete, we should * undo this, in case it has been included before. */ #undef xplcdelete /** * Macro used to indicate a valid use of the delete keyword with an * XPLC interface. In some cases, you really need to use delete on an * object that derives from IObject. In those cases, use "xplcdelete" * instead of "delete". */ #define xplcdelete CheckIObjectOk() && /** * Overriding the delete keyword. This replaces the delete keyword * with an invocation of the operator&& using a specific marker class * as the left operand, allowing it to be templated on the right * operand. */ #define delete CheckIObject() && /** * Remplacement for delete[]. Because we cannot capture usage of * delete[] using macros, we have to add a replacement for it, * unfortunately. */ #define deletev CheckIObjectOkVector() && #endif /* __XPLC_DELETE_H__ */ wvstreams-4.6.1/include/xplc/trace.h0000644000175000001440000000503711077372756016456 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_TRACE_H__ #define __XPLC_TRACE_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #ifdef DEBUG #include /* * Mix-in template that trace constructors, destructors and refcount * to stderr. */ template class TraceComponent: public Component { public: TraceComponent() { fprintf(stderr, "%s: instantiated (%p)\n", __PRETTY_FUNCTION__, this); } virtual unsigned int addRef() { unsigned int refcount = Component::addRef(); fprintf(stderr, "%s = %i (%p)\n", __PRETTY_FUNCTION__, refcount, this); return refcount; } virtual unsigned int release() { unsigned int refcount = Component::release(); fprintf(stderr, "%s = %i (%p)\n", __PRETTY_FUNCTION__, refcount, this); return refcount; } virtual ~TraceComponent() { fprintf(stderr, "%s: destroyed (%p)\n", __PRETTY_FUNCTION__, this); } }; #else /* DEBUG */ #error "this header should not be used other than for debugging" #endif /* else DEBUG */ #endif /* __XPLC_TRACE_H__ */ wvstreams-4.6.1/include/xplc/IServiceManager.h0000644000175000001440000000552311077372756020364 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_ISERVICEMANAGER_H__ #define __XPLC_ISERVICEMANAGER_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * The service manager interface. */ #include #include /** \interface IServiceManager IServiceManager.h xplc/IServiceManager.h * * The %XPLC service manager interface. * * To do anything with %XPLC, you need to use the service manager. You * can obtain it by calling XPLC_getServiceManager(). * * The service manager knows how to find objects from their UUID. It * does so by searching a list of service handlers (objects that * implement the IServiceHandler interface), querying them in turn * until the object is found. * * The service handlers are those who know how to find objects through * various means. For example, one might get objects from a statically * defined list of objects, another might search a directory for * plugins, etc... * * If you want to provide an IServiceHandler, you should register with * the service manager. */ class IServiceManager: public IServiceHandler { UNSTABLE_INTERFACE public: /** * Register a handler to be handled by this manager. */ virtual void addHandler(IServiceHandler*) = 0; /** Register a handler to be handled by this manager, explicitly * adding it to the beginning of the list (highest priority). */ virtual void addFirstHandler(IServiceHandler*) = 0; /** Register a handler to be handled by this manager, explicitly * adding it to the end of the list (lowest priority). */ virtual void addLastHandler(IServiceHandler*) = 0; /** Remove a handler from the list. */ virtual void removeHandler(IServiceHandler*) = 0; }; /// IServiceManager's IID DEFINE_IID(IServiceManager, {0x22bdabd9, 0xa63a, 0x4b5e, {0xb1, 0x61, 0xb6, 0x36, 0x52, 0x27, 0xd7, 0x8e}}); #endif /* __XPLC_ISERVICEMANAGER_H__ */ wvstreams-4.6.1/include/xplc/ptr.h0000644000175000001440000000750611077372756016170 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Pierre Phaneuf * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #ifndef __XPLC_PTR_H__ #define __XPLC_PTR_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif /** \file * * Smart pointer for XPLC interfaces. */ #include #ifndef UNSTABLE #error "xplc_ptr is experimental!" #endif /** * Smart pointer class for XPLC interfaces. */ template class xplc_ptr { private: T* ptr; class ProtectedPtr: public T { private: virtual unsigned int addRef() = 0; virtual unsigned int release() = 0; #ifndef __XPLC_DELETE_H__ void operator delete(void*); #endif }; xplc_ptr& operator=(const xplc_ptr&); public: xplc_ptr(): ptr(0) { } /** * Construct an xplc_ptr from a raw pointer. This is the only way * that an xplc_ptr will take ownership of an interface from its * previous owner. */ explicit xplc_ptr(T* aObj): ptr(aObj) { } /** * Construct an xplc_ptr from another xplc_ptr. This will addRef the * interface, if the xplc_ptr is non-NULL. */ template explicit xplc_ptr(const xplc_ptr

& aObj): ptr(aObj) { if(ptr) ptr->addRef(); } ~xplc_ptr() { if(ptr) ptr->release(); } /** * Provide an operator->. This allows you to invoke methods on the * interface pointed at by the xplc_ptr. As with a raw pointer, if * the xplc_ptr is NULL, this will cause a crash. The interface is * wrapped in some basic protection, to avoid accidental addRef or * release. */ ProtectedPtr* operator->() const { return static_cast(ptr); } /** * Provide an operator*. This is so you can use "*foo" with an * xplc_ptr like you could with the raw pointer. It also applies * some basic protection. */ operator ProtectedPtr*() const { return static_cast(ptr); } /** * Assign a raw pointer to an xplc_ptr. This will addRef the * interface, and release the interface previously pointed at by the * xplc_ptr, if any. */ xplc_ptr& operator=(T* _ptr) { if(_ptr) _ptr->addRef(); if(ptr) ptr->release(); ptr = _ptr; return *this; } }; /** * Used to addRef an object before passing it to something that would * otherwise "steal" the reference. */ template T* do_addRef(T* obj) { if (obj) obj->addRef(); return obj; } #endif /* __XPLC_PTR_H__ */ wvstreams-4.6.1/include/xplc/IModule.h0000644000175000001440000000300511077372756016707 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * * 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 __XPLC_IMODULE_H__ #define __XPLC_IMODULE_H__ #if defined(__GNUC__) && __GNUC__ > 3 # pragma GCC system_header #endif #include /** \interface IModule IModule.h xplc/IModule.h * * The interface that a module should provide. */ class IModule: public IServiceHandler { UNSTABLE_INTERFACE public: /* * FIXME: There will be other methods here, for inspecting a * module. */ }; DEFINE_IID(IModule, {0x772689d4, 0x7932, 0x448a, {0x80, 0x8a, 0x6e, 0xbf, 0x1c, 0xe9, 0xf9, 0x4b}}); #endif /* __XPLC_IMODULE_H__ */ wvstreams-4.6.1/include/wvpty.h0000644000175000001440000000240311036722347015563 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * WvStreams implementation of ptys under Linux. * * For more information on programming ptys, see chapter 19 of * Stevens' "Advanced Programming in the UNIX Environment" */ #ifndef __WVPTY_H #define __WVPTY_H #include "wvfdstream.h" #include "wvtr1.h" class WvPty: public WvFDStream { private: WvString _master, _slave; pid_t _pid; int _exit_status; static bool open_pty(WvString &master, int &master_fd, WvString &slave, int &slave_fd); void monitor_child(bool wait); public: typedef wv::function Callback; Callback pre_exec_cb; Callback post_exec_cb; // This can only be called if exec() fails WvPty(const char *program, const char * const *argv, Callback _pre_exec_cb = Callback(), Callback _post_exec_cb = Callback()); void kill(int signum); bool child_exited(); bool child_killed(); int finish(); int exit_status(); const char *master() const { return _master; } const char *slave() const { return _slave; } pid_t pid() const { return _pid; } const char *wstype() const { return "WvPty"; } }; #endif // __WVPTY_H wvstreams-4.6.1/include/wvrateadjust.h0000644000175000001440000000362611036722347017125 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvRateAdjust is a WvEncoder that makes sure data comes out of it at a * given average rate. It adds duplicate samples or removes extra samples * from the input in order to achieve this. * * The current version doesn't do anything fancy like linear or spline * interpolation, since it's being built mainly for minor rate adjustments * like 8000 Hz to 8020 Hz, and interpolation probably doesn't help too * much there. It's also nicer to not have to worry explicitly about the * number format, which you would have to do if you were doing actual math. * * You can also use this as a slightly (not terribly) inefficient rate * *estimator* for the input stream. * * NOTE: Time is of the essence of this encoder. */ #ifndef __WVRATEADJUST_H #define __WVRATEADJUST_H #include "wvencoder.h" #include "wvtimeutils.h" class WvRateAdjust : public WvEncoder { public: WvRateAdjust *match_rate; int sampsize, irate_n, irate_d, orate_n, orate_d; WvTime epoch; // the time when sampling started // the token bucket holds the "remainder" of our fake integer division // operation. With this, we can make sure we always average out to // exactly the right rate. // // Basically: // bucket = ((orate*insamps) - (irate*outsamps)) * irate_d * orate_d // // ...but with some care thrown in to prevent overflows. int bucket; WvRateAdjust(int _sampsize, int _irate_base, int _orate); WvRateAdjust(int _sampsize, int _irate_base, WvRateAdjust *_match_rate); int getirate() { return irate_n / irate_d; } int getorate() { return orate_n / orate_d; } protected: void init(int _sampsize, int _irate_base); virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); }; #endif // __WVRATEADJUST_H wvstreams-4.6.1/include/uniinigen.h0000644000175000001440000000272311036722347016364 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generator for .ini files. */ #ifndef __UNICONFINI_H #define __UNICONFINI_H #include "unitempgen.h" #include "wvlog.h" #include class WvFile; /** * Loads and saves ".ini"-style files similar to those used by * Windows, but adapted to represent keys and values using Tcl * style lists. * * To mount, use the moniker prefix "ini:" followed by the * path of the .ini file. * */ class UniIniGen : public UniTempGen { public: typedef wv::function SaveCallback; private: WvString filename; int create_mode; WvLog log; struct stat old_st; SaveCallback save_cb; public: /** * Creates a generator which can load/modify/save a .ini file. * "filename" is the local path of the .ini file */ UniIniGen(WvStringParm filename, int _create_mode = 0666, SaveCallback _save_cb = SaveCallback()); virtual ~UniIniGen(); /***** Overridden members *****/ virtual void commit(); virtual bool refresh(); virtual void set(const UniConfKey &key, WvStringParm value); private: #ifndef _WIN32 // helper methods for commit bool commit_atomic(WvStringParm real_filename); #endif void save(WvStream &file, UniConfValueTree &parent); bool refreshcomparator(const UniConfValueTree *a, const UniConfValueTree *b); }; #endif // __UNICONFINI_H wvstreams-4.6.1/include/uniconftree.h0000644000175000001440000001226011036722347016715 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniConf low-level tree storage abstraction. */ #ifndef __UNICONFTREE_H #define __UNICONFTREE_H #include "uniconfkey.h" #include "unihashtree.h" #include "wvtr1.h" /** * A recursively composed dictionary for tree-structured * data indexed by UniConfKey. * * Someday this could be further abstracted into a generic WvTreeDict. * * "Sub" is the name of the concrete subclass of UniConfTree. */ template class UniConfTree : public UniHashTreeBase { public: typedef wv::function Visitor; typedef wv::function Comparator; /** Creates a node and links it to a subtree, if parent is non-NULL */ UniConfTree(Sub *parent, const UniConfKey &key) : UniHashTreeBase(parent, key) { } /** Destroy this node's contents and children. */ ~UniConfTree() { zap(); } /** Returns a pointer to the parent node, or NULL if there is none. */ Sub *parent() const { return static_cast(this->xparent); } /** Reparents this node. */ void setparent(Sub *parent) { UniHashTreeBase::_setparent(parent); } /** Returns a pointer to the root node of the tree. */ Sub *root() const { return static_cast(UniHashTreeBase::_root()); } /** * Returns full path of this node relative to an ancestor. * If ancestor is NULL, returns the root. */ UniConfKey fullkey(const Sub *ancestor = NULL) const { return UniHashTreeBase::_fullkey(ancestor); } /** * Finds the sub-node with the specified key. * If key.isempty(), returns this node. */ Sub *find(const UniConfKey &key) const { return static_cast(UniHashTreeBase::_find(key)); } /** * Finds the direct child node with the specified key. * * If key.numsegments() == 1, then performs the same task * as find(key), but a little faster. Otherwise returns NULL. */ Sub *findchild(const UniConfKey &key) const { return static_cast(UniHashTreeBase::_findchild(key)); } /** * Removes the node for the specified key from the tree * and deletes it along with any of its children. * * If the key is UniConfKey::EMPTY, deletes this object. */ void remove(const UniConfKey &key) { delete find(key); } /** Removes and deletes all children of this node. */ void zap() { if (!(this->xchildren)) return; // set xchildren to NULL first so that the zap() will happen faster // otherwise, each child will attempt to unlink itself uselessly typename UniHashTreeBase::Container *oldchildren = this->xchildren; this->xchildren = NULL; // delete all children typename UniHashTreeBase::Container::Iter i(*oldchildren); for (i.rewind(); i.next();) delete static_cast(i.ptr()); delete oldchildren; } /** * Performs a traversal on this tree using the specified * visitor function and traversal type(s). * "visitor" is the tree visitor function * "userdata" is userdata for the tree visitor function */ void visit(const Visitor &visitor, void *userdata, bool preorder = true, bool postorder = false) const { _recursive_unsorted_visit(this, reinterpret_cast< const typename UniHashTreeBase::BaseVisitor&>(visitor), userdata, preorder, postorder); } /** * Compares this tree with another using the specified comparator * function. * Comparison of a subtree ends when the comparator returns false. * "comparator" is the value compare function * "userdata" is userdata for the compare function * Returns: true if the comparison function returned true each time */ bool compare(const Sub *other, const Comparator &comparator) { return _recursivecompare(this, other, reinterpret_cast< const typename UniHashTreeBase::BaseComparator&>(comparator)); } /** * An iterator that walks over all elements on one level of a * UniConfTree. */ class Iter : public UniHashTreeBase::Iter { public: typedef typename UniHashTreeBase::Iter MyBase; /** Creates an iterator over the specified tree. */ Iter(Sub &tree) : UniHashTreeBase::Iter(tree) { } /** Returns a pointer to the current node. */ Sub *ptr() const { return static_cast(MyBase::ptr()); } WvIterStuff(Sub); }; }; /** A plain UniConfTree that holds keys and values. */ class UniConfValueTree : public UniConfTree { WvString xvalue; /*!< the value of this entry */ public: UniConfValueTree(UniConfValueTree *parent, const UniConfKey &key, WvStringParm value) : UniConfTree(parent, key), xvalue(value) { } /** Returns the value field. */ const WvString &value() const { return xvalue; } /** Sets the value field. */ void setvalue(WvStringParm value) { xvalue = value; } }; #endif // __UNICONFTREE_H wvstreams-4.6.1/include/wvxplc.h0000644000175000001440000000150311077156272015720 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * XPLC setup bits. */ #ifndef __WVXPLC_H #define __WVXPLC_H #ifndef UNSTABLE #define UNSTABLE #endif #ifdef _WIN32 #include #include #include #include "wvwin32-sanitize.h" #else #include // not strictly necessary, but EVERYBODY uses this... #include #include "wvautoconf.h" #endif #ifndef ENABLE_DELETE_DETECTOR #include #define deletev delete[] #else #include #include #endif #include #include #include #define WVRELEASE(ptr) do { if (ptr) ptr->release(); ptr = 0; } while (0) #define WVDELETE(ptr) do { delete ptr; ptr = 0; } while (0) #endif // __WVXPLC_H wvstreams-4.6.1/include/wvsubprocqueue.h0000644000175000001440000001124711036722347017477 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for running a series or set of processes, one at a time. */ #ifndef __WVSUBPROCQUEUE_H #define __WVSUBPROCQUEUE_H #include "wvsubproc.h" /** * An ordered queue of WvSubProc instances. * * You can enqueue any number of subprocesses to run sequentially, with * a specified maximum number of processes running at a time. The processes * run in the order they are added to the queue, except that (of course) * running more than one process at a time may cause processes to overlap * in an undefined way. * * You can define "sync point" subprocesses using the "cookie" parameter to * add(). A sync point is guaranteed to be started: * - alone, not in parallel with anything else * - at least once after you enqueue it * - at least once after every already-enqueued process has finished * - immediately after every already-enqueued process has finished, *unless* * an earlier sync point is still waiting. * - no more than twice after the final time it is enqueued. * * That sounds complicated, but it lets you easily implement a common * type of "delayed event" queuing: "Some time after each of these * things S, I need to run X, but I don't need to run it for *every* * element of S, but I don't want it to wait forever because I keep adding * to S." * * For example, imagine you have one type of operation, add() that * creates a new file in a directory, and another type of operation * that regenerates the directory index. You need to generate the * index after any create operation before it will really be done, * but there is no need to generate the index more than once when * doing a lot of create operations. You could do a sequence like * this: * * for (i = 0; i < 10; i++) * { add_file(i); } * * Where "add" can trivially just do q.add(NULL, whatever1) and then * q.add(&reindex_cookie, whatever2). WvSubProcQueue * will ensure that "whatever2" runs as soon as possible (to prevent * arbitrary delays because of nonstop add_file() calls) and also exactly * once at the very end, but not every single time. * * In case it wasn't obvious, if you create more than one * WvSubProcQueue, they operate totally independently of each other. That * means if you have two queues with a max of 10 processes, you might have * up to 20 processes running at a time. */ class WvSubProcQueue { public: /** * Create a WvSubProcQueue. _maxrunning is the maximum number of * processes to have running in parallel. 1 is usually a good choice. */ WvSubProcQueue(unsigned _maxrunning); virtual ~WvSubProcQueue(); /** * Enqueue a process. If cookie is NULL, the process will simply * be added at the end of the queue. If cookie is non-NULL, it will * be treated as a "sync point" as described above. * * WARNING! Do not start_again() the proc before passing it to the * WvSubProcQueue. This is done automatically in some WvSubProc * constructors. Use WvSubProc::prepare() or preparev() instead. */ void add(void *cookie, WvSubProc *proc); /** * Like add(cookie, proc) but you don't have to build the WvSubProc * yourself for simple cases. */ void add(void *cookie, const char *cmd, const char * const *argv); /** * Clean up after any running processes in the queue, and start running * additional processes if any are waiting. Never blocks. * * Returns the number of new processes which were started on this run. * * WARNING: you must call this rather often in order to keep your * queue moving. */ int go(); /** * Wait synchronously for all processes in the entire queue to finish. * This might block forever!! You should probably only call it in * test programs or if you really know what you're doing. Otherwise * just call go() occasionally. */ void finish(); /// Return the number of currently running processes. unsigned running() const; /// Return the number of unfinished (ie. running or waiting) processes. unsigned remaining() const; /// True if there are no unfinished (ie. running *or* waiting) processes. bool isempty() const; private: struct Ent { Ent(void *_cookie, WvSubProc *_proc) { cookie = _cookie; proc = _proc; redo = false; } ~Ent() { if (proc) delete proc; } void *cookie; WvSubProc *proc; bool redo; }; DeclareWvList(Ent); unsigned maxrunning; EntList runq, waitq; bool cookie_running(); }; #endif // __WVSUBPROCQUEUE_H wvstreams-4.6.1/include/wvprociter.h0000644000175000001440000000127711036722347016606 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Process iterator. Iterates through the running processes. * */ #ifndef __WVPROCITER_H #define __WVPROCITER_H #include "wvdiriter.h" #include "wvstringlist.h" struct WvProcEnt { pid_t pid; WvString exe; WvStringList cmdline; }; class WvProcIter { private: WvDirIter dir_iter; WvProcEnt proc_ent; public: WvProcIter(); ~WvProcIter(); bool isok() const; void rewind(); bool next(); const WvProcEnt *ptr() const { return &proc_ent; } WvIterStuff(const WvProcEnt); }; bool wvkillall(WvStringParm basename, int sig); #endif wvstreams-4.6.1/include/wvdbusconn.h0000644000175000001440000002117111077124114016556 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * * A WvDBusConn represents a connection to another application. Messages * can be sent and received via this connection. In most cases, the * other application is a message bus. */ #ifndef __WVDBUSCONN_H #define __WVDBUSCONN_H #include "wvstreamclone.h" #include "wvlog.h" #include "wvdbusmsg.h" #include "wvhashtable.h" #include "wvuid.h" #define WVDBUS_DEFAULT_TIMEOUT (300*1000) class WvDBusConn; /** * The data type of callbacks used by WvDBusConn::add_callback(). The * return value should be true if the callback processes the message, false * otherwise. */ typedef wv::function WvDBusCallback; class IWvDBusAuth { public: virtual ~IWvDBusAuth() { }; /** * Main action callback. Called whenever d seems to have data available. * Return false if you're not yet authorized and need to be called again * when data is available; return true if you're done. * * If authorization fails, call seterr on d with an appropriate error * message. */ virtual bool authorize(WvDBusConn &c) = 0; // Returns the unix UID negotiated during authentication. Boring on the // client side (generally just getuid()), more useful for the server. virtual wvuid_t get_uid() = 0; }; class WvDBusClientAuth : public IWvDBusAuth { bool sent_request; public: WvDBusClientAuth(); virtual bool authorize(WvDBusConn &c); virtual wvuid_t get_uid(); }; class WvDBusConn : public WvStreamClone { bool client, authorized, in_post_select; WvString _uniquename; IWvDBusAuth *auth; public: WvLog log; /** * Creates a new dbus connection using the given WvStreams moniker. * * WvDBus uses special monikers for the "standard" DBus buses: * dbus:system, dbus:session, and dbus:starter. These correspond to * DBUS_BUS_SYSTEM, DBUS_BUS_SESSION, and DBUS_BUS_STARTER, respectively. * * If a non-NULL _auth parameter is passed, the WvDBusConn object takes * ownership of it and will delete it at some point (possibly before * the WvDBusConn itself is destroyed). */ WvDBusConn(WvStringParm moniker, IWvDBusAuth *_auth = NULL, bool _client = true); /** * Creates a new dbus connection from the given stream. Takes ownership * of the stream and will WVRELEASE() it when done. */ WvDBusConn(IWvStream *_cloned, IWvDBusAuth *_auth = NULL, bool _client = true); void init(IWvDBusAuth *_auth, bool _client); /** * Release this connection. If this is the last owner of the associated * DBusConnection object, the connection itself closes. */ virtual ~WvDBusConn(); void set_uniquename(WvStringParm s); void try_auth(); void send_hello(); wvuid_t get_uid() { return auth ? auth->get_uid() : WVUID_INVALID; } void out(WvStringParm s); void out(WVSTRING_FORMAT_DECL) { return out(WvString(WVSTRING_FORMAT_CALL)); } const char *in(); /** * Request the given service name on DBus. There's no guarantee the * server will let us have the requested name, though. * * The name will be released when this connection object is destroyed. */ void request_name(WvStringParm name, const WvDBusCallback &onreply = 0, time_t msec_timeout = WVDBUS_DEFAULT_TIMEOUT); /** * Return this connection's unique name on the bus, assigned by the server * at connect time. */ WvString uniquename() const; /** * Close the underlying stream. The object becomes unusable. This is * also called whenever an error is set. */ virtual void close(); /** * Send a message on the bus, not expecting any reply. Returns the * assigned serial number in case you want to track it some other way. */ uint32_t send(WvDBusMsg msg); /** * Send a message on the bus, calling onreply() when the reply comes in * or the messages times out. */ void send(WvDBusMsg msg, const WvDBusCallback &onreply, time_t msec_timeout = WVDBUS_DEFAULT_TIMEOUT); /** * Send a message on the bus and wait for a reply to come in, returning * the message when it does. There is always a reply, even if it's * "message expired" or some other error message. * * The serial_cb parameter allows you to create a callback which is called * after 'send' but before the runonce() loop is initiated, allowing you * to perform some kind of setup based on the serial number of the message. * * It waits by doing this->runonce(). Streams on the globallist may run. * * WARNING: this function does a synchronous wait operation, and thus * does not play nicely in single-threaded WvStreams applications. Use * with extreme care. */ WvDBusMsg send_and_wait(WvDBusMsg msg, time_t msec_timeout = WVDBUS_DEFAULT_TIMEOUT, wv::function serial_cb = 0); /** * The priority level of a callback registration. This defines the order * in which callbacks are processed, from lowest to highest integer. */ enum CallbackPri { PriSystem = 0, // implemented by DBus or WvDBus. Don't use. PriSpecific = 5000, // strictly limited by interface/method PriNormal = 6000, // a reasonably selective callback PriBridge = 7000, // proxy selectively to other listeners PriBroadcast = 8000, // last-resort proxy to all listeners PriGaveUp = 9900, // run this if nothing else works }; /** * Adds a callback to the connection: all received messages will be * sent to all callbacks to look at and possibly process. This method * is simple and flexible, but it can be slow if you have too many * callbacks set. * * Your application is very unlikely to have "too many" callbacks. If * for some reason you need to register lots of separate callbacks, * make your own data structure for them and register just a single * callback here that looks things up in your own structure. * * 'pri' defines the callback sort order. When calling callbacks, we * call them in priority order until the first callback returns 'true'. * If you just want to log certain messages and let other people handle * them, use a high priority but return 'false'. * * 'cookie' is used to identify this callback for del_callback(). Your * 'this' pointer is a useful value here. */ void add_callback(CallbackPri pri, WvDBusCallback cb, void *cookie = NULL); /** * Delete all callbacks that have the given cookie. */ void del_callback(void *cookie); /** * Called by for each received message. Returns true if we handled * this message, false if not. You should not need to call or override * this; see add_callback() instead. */ virtual bool filter_func(WvDBusMsg &msg); /** * Returns true if there are no outstanding messages that have not * received (or timed out) their reply. Mostly useful in unit tests * that want to terminate once all messages have been processed. */ bool isidle(); private: time_t mintimeout_msec(); virtual bool post_select(SelectInfo &si); struct Pending { WvDBusMsg msg; // needed in case we need to generate timeout replies uint32_t serial; WvDBusCallback cb; WvTime valid_until; Pending(WvDBusMsg &_msg, const WvDBusCallback &_cb, time_t msec_timeout) : msg(_msg), cb(_cb) { serial = msg.get_serial(); if (msec_timeout < 0) msec_timeout = 5*3600*1000; // "forever" is a few hours valid_until = msecadd(wvstime(), msec_timeout); } }; DeclareWvDict(Pending, uint32_t, serial); PendingDict pending; WvDynBuf in_queue, out_queue; void expire_pending(Pending *p); void cancel_pending(uint32_t serial); void add_pending(WvDBusMsg &msg, WvDBusCallback cb, time_t msec_timeout); bool _registered(WvDBusMsg &msg); struct CallbackInfo { CallbackPri pri; WvDBusCallback cb; void *cookie; CallbackInfo(CallbackPri _pri, const WvDBusCallback &_cb, void *_cookie) : cb(_cb) { pri = _pri; cookie = _cookie; } }; static int priority_order(const CallbackInfo *a, const CallbackInfo *b); DeclareWvList(CallbackInfo); CallbackInfoList callbacks; }; #endif // __WVDBUSCONN_H wvstreams-4.6.1/include/unilistiter.h0000644000175000001440000000440111036722347016745 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002-2005 Net Integration Technologies, Inc. * * A simple implementation of a UniConfGen iterator. */ #ifndef __UNILISTITER_H #define __UNILISTITER_H #include "uniconfgen.h" #include "wvscatterhash.h" #include "wvstringcache.h" #include "wvstringlist.h" /** * An iterator that iterates through a constant list of keys. This is * handy if you know the list of keys is relatively short and you don't * want to write your own iterator, and/or you know your own object state * might change during iteration, so you would have to pre-generate the list * of keys anyway. * * The creator of the iter is responsible for filling the 'keys' and 'values' * lists by calling add(). If the 'values' list runs out of values before * 'keys', the remaining values will be retrieved from the given generator * (using get()) instead. */ class UniListIter : public UniConfGen::Iter { IUniConfGen *gen; DeclareWvScatterTable(UniConfKey); UniConfKeyTable keylook; UniConfKeyList keys; WvStringList values; UniConfKeyList::Iter ki; WvStringList::Iter vi; WvStringCache scache; public: UniListIter(IUniConfGen *_gen); /** * Add a key/value pair to the list that gets returned by this iterator. * If v is 'noval' (the default), the value of the returned item is * retrieved by calling get(k). Otherwise the value is v. * * This function should only be called by the creator of the iterator, * not the end user. */ void add(const UniConfKey &k, WvStringParm v = WvString::null); /** * Automatically fill the contents of this iterator by calling add() * for each element of the 'source' iterator. This is handy if the * source iterator might be unsafe (eg. can't handle set() type * operations on the generator without restarting the iteration). * * This function should only be called by the creator of the iterator, * not the end user. */ void autofill(IUniConfGen::Iter *source); /***** Overridden members *****/ virtual void rewind(); virtual bool next(); virtual UniConfKey key() const; virtual WvString value() const; }; #endif // __UNILISTITER_H wvstreams-4.6.1/include/uniretrygen.h0000644000175000001440000000531411036722347016751 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen that reconnects to an inner generator whenever the inner * generator is no longer OK. */ #ifndef __UNIRETRYGEN_H #define __UNIRETRYGEN_H #include "unifiltergen.h" #include "wvtimeutils.h" #include "wvlog.h" /** * A UniConfGen that reconnects to an inner generator specified by * a moniker whenever the inner generator is no longer OK. It will * try to periodically recreate the inner generator until the resulting * object returns isok() true. * * The UniRetryGen's moniker takes either of the forms retry: * or retry:{ }; in the second form the retry * timeout is specified in milliseconds. If not specified, the retry timout * is 5000ms. Specifically this means that whenever the retry generator is * does not have a good inner generator and at least 5000ms have passed * since the disconnect or last reconnect attempt, reconnection will be * attempted again. * * The connection is created through the underlying * backend's moniker and destroyed by delete. * * If UniRetryGen's constructor is used directly, a callback of type * UniRetryGen::ReconnectCallback can be specified, which will be called * whenever the UniRetryGen reconnects to the underlying moniker. This allows * for any necessary resynchronisation, such as a call to refresh(). * * UniRetryGen can be used in combination with UniReplicateGen to create * a connection to a UniConf daemon that is robust against network * failures through a moniker such as replicate:{retry:tcp:192.168.0.1 tmp:} */ class UniRetryGen : public UniFilterGen { public: typedef wv::function ReconnectCallback; private: WvLog log; WvString moniker; ReconnectCallback reconnect_callback; time_t retry_interval_ms; WvTime next_reconnect_attempt; void maybe_disconnect(); void maybe_reconnect(); public: UniRetryGen(WvStringParm _moniker, ReconnectCallback _reconect_callback = ReconnectCallback(), time_t _retry_internal_ms = 5000); /***** Overridden methods *****/ virtual void commit(); virtual bool refresh(); virtual void prefetch(const UniConfKey &key, bool recursive); virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual bool isok(); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); }; #endif //__UNIRETRYGEN_H wvstreams-4.6.1/include/uniclientgen.h0000644000175000001440000000433111036722347017060 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniClientGen is a UniConfGen for retrieving data from the * UniConfDaemon. */ #ifndef __UNICONFCLIENT_H #define __UNICONFCLIENT_H #include "uniconfgen.h" #include "wvlog.h" #include "wvstringlist.h" #include "uniclientconn.h" #include "uniconfkey.h" /** * Communicates with a UniConfDaemon to fetch and store keys and * values. * * To mount, use the moniker prefix "unix:" followed by the * path of the Unix domain socket used by the UniConfDaemon. * Alternately, use the moniker prefix "tcp:" followed by the * hostname, a colon, and the port of a machine that serves * UniConfDaemon requests over TCP. * */ class UniClientGen : public UniConfGen { UniClientConn *conn; WvLog log; WvString result_key; /*!< the key that the current result is from */ WvString result; /*!< the result from the current key */ UniListIter *result_list; /*!< result list for iterations */ bool cmdinprogress; /*!< true while a command is in progress */ bool cmdsuccess; /*!< true when a command completed successfully */ time_t timeout; // command timeout in ms int version; /*!< version number of the protocol */ public: /** * Creates a generator which can communicate with a daemon using * the specified stream. * "stream" is the raw connection */ UniClientGen(IWvStream *stream, WvStringParm dst = WvString::null); virtual ~UniClientGen(); time_t set_timeout(time_t _timeout); /***** Overridden members *****/ virtual bool isok(); virtual bool refresh(); virtual void flush_buffers(); virtual void commit(); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); protected: virtual Iter *do_iterator(const UniConfKey &key, bool recursive); void conncallback(); bool do_select(); }; #endif // __UNICONFCLIENT_H wvstreams-4.6.1/include/unitransactiongen.h0000644000175000001440000001445511036722347020137 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen that represents pending transactions to another generator. */ #ifndef __UNITRANSACTIONGEN_H #define __UNITRANSACTIONGEN_H #include "uniconfgen.h" class UniConfChangeTree; class UniConfValueTree; /** * A UniConfGen that represents pending transactions to another generator. * It's moniker is "transaction" followed by a moniker to create * the underlying generator, or alternatively an IUniConfGen object. * * A set() call on a UniTransactionGen records the fact that you wish to * perform that set() call on the underlying generator. * * When you call commit(), the underlying generator is modified to * incorporate all set() calls since the last commit() or refresh() (or * since creation if none) as if they had all been made on the underlying * generator at the moment of your call to commit(). However, commit() * does this in a way that prevents unnecessary extra callbacks from * being issued by the underlying generator. * * When you call refresh(), all set() calls since the last commit() or * refresh() (or since creation if none) are discarded. * * WARNING!!! Your calls to commit() and refresh() will propagate to * any upstream generators. To prevent this, you will want to use a * UniBachelorGen. * * When you use get(), exists(), haschildren(), iterator(), or * recursiveiterator(), the results that you get are equivalent to the results * that you would have gotten if you had called commit() and then used these * methods on the underlying generator, except that they do not * modify the underlying generator. * * Note that the UniTransactionGen's iterators might iterate over keys * in a different order than would the underlying generator's iterators * after a commit(). Also, the UniTransactionGen's iterators presently do * not support concurrent modification (regardless of whether the underlying * generator's iterators do). * * The UniTransactionGen issues callbacks due to calls to set() and refresh() * and also due to changes to the underlying generator from other sources. If * the underlying generator issues precisely the callbacks needed to indicate * a change in state, then so will the UniTransactionGen. * * The UniTransactionGen assumes that the underlying generator recursively * issues deletion callbacks whenever someone deletes a key from it that has * children, but the semantics in r4_2 and below don't require that. In those * versions, or when wrapping a generator with a broken callback system, the * UniTransactionGen won't issue callbacks properly, but everything else * should work. * * In order to work properly, the UniTransactionGen has to assume that the * underlying generator completely obeys the UniConfGen semantics. If that * is not true, then the UniTransactionGen might not obey its own class * contract or even the UniConfGen semantics either. (Note that few * generators completely obey the UniConfGen semantics.) However, provided * that the underlying generator's personal semantics are at least sane, the * UniTransactionGen's get()-like methods will probably show the underlying * generator as how your uncommitted set()s indicate you want it to be, * commit() will probably try and make it be like that (without any callbacks * made for things it couldn't commit), and refresh() will probably work as * designed. * * Using a UniTransactionGen and/or its underlying generator in multiple * threads will probably break it. * * Though similar in concept to a UniFilterGen, the UniTransactionGen * doesn't derive from it because we have basically no need for any of * its functionality. */ class UniTransactionGen : public UniConfGen { public: /** * Constructs a UniTransactionGen for the given underlying generator, * which must be non-null. */ UniTransactionGen(IUniConfGen *_base); /** * Destroys the UniTransactionGen and the underlying generator. Does * not commit uncommitted data. */ ~UniTransactionGen(); /***** Overridden methods *****/ virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual void commit(); virtual bool refresh(); virtual Iter *iterator(const UniConfKey &key); virtual bool isok(); virtual void flush_buffers(); protected: UniConfChangeTree *root; IUniConfGen *base; /** * A recursive helper function for commit(). */ void apply_changes(UniConfChangeTree *node, const UniConfKey §ion); /** * A recursive helper function for apply_changes(). */ void apply_values(UniConfValueTree *newcontents, const UniConfKey §ion); /** * A recursive helper function for refresh(). */ void cancel_changes(UniConfChangeTree *node, const UniConfKey §ion); /** * A recursive helper function for cancel_changes(). */ void cancel_values(UniConfValueTree *newcontents, const UniConfKey §ion); /** * The callback function for the underlying generator. */ void gencallback(const UniConfKey &key, WvStringParm value); /** * Four functions to implement the functionality of set() so * that it isn't two pages long. */ UniConfValueTree *create_value(UniConfValueTree *parent, const UniConfKey &key, int seg, WvStringParm value); UniConfChangeTree *create_change(UniConfChangeTree *parent, const UniConfKey &key, int seg, WvStringParm value); UniConfValueTree *set_value(UniConfValueTree *node, const UniConfKey &key, int seg, WvStringParm value); UniConfChangeTree *set_change(UniConfChangeTree *node, const UniConfKey &key, int seg, WvStringParm value); /** * A recursive helper function for create_change(). */ void deletion_simulator(const UniConfKey &key); /** * A recursive helper function for set_change(). */ void deletion_simulator2(const UniConfKey &key); /** * A UniConfTree visitor function for set_value(), cancel_values(), and * cancel_changes(). */ void deletion_visitor(const UniConfValueTree *node, void *userdata); }; #endif wvstreams-4.6.1/include/wvsystem.h0000644000175000001440000000732411036722347016302 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #ifndef __WVSYSTEM_H #define __WVSYSTEM_H #include "wvsubproc.h" /** * WvSystem is a mostly-replacement for the libc system() function call, * which people usually use because of its notational convenience, not * because it calls the Unix shell. In fact, some people don't even realize * it calls the shell, leading to security holes when people forget to * quote user-provided parameters correctly. * * WvSystem() uses WvSubProc but makes sure it can be called in a single * line of C++ code with a minimum of fluff. For example: * * WvSystem("rm", "-rf", filename, NULL); * is like * system(WvString("rm -rf %s", filename)); * except that you don't have weird security bugs if "filename" contains * special characters like newline, space, quotation mark, etc. * * See WvSubProc and WvSubProcQueue for less concise, but more flexible ways * to run subprograms. */ class WvSystem : private WvSubProc { public: /** * Construct a WvSystem from a simple list of strings. * * For example: * WvSystem("rm", "-rf", dirname); * * Note: this is unlike WvSubProc::prepare(cmd, ...) because you * don't need to provide argv[0] yourself. "cmd" is automatically * inserted as argv[0]. It also lets you pass WvString objects in * without manually calling cstr(), because it doesn't use varargs. * Unfortunately, that means it's limited to 20 arguments. */ WvSystem(const char cmd[], const char *a0 = NULL, const char *a1 = NULL, const char *a2 = NULL, const char *a3 = NULL, const char *a4 = NULL, const char *a5 = NULL, const char *a6 = NULL, const char *a7 = NULL, const char *a8 = NULL, const char *a9 = NULL, const char *a10 = NULL, const char *a11 = NULL, const char *a12 = NULL, const char *a13 = NULL, const char *a14 = NULL, const char *a15 = NULL, const char *a16 = NULL, const char *a17 = NULL, const char *a18 = NULL, const char *a19 = NULL ) { // this function is inline so it can be a little bit less wasteful... const char * const argv[] = { cmd, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, NULL }; init(argv); } /** * Construct a WvSystem from an argv array. This is exactly the same * as WvSubProc's argv[] constructor, but the command name is always * taken from argv[0] rather than provided separately. * * For example: * const char *argv[] = { "rm", "-rf", dirname, NULL }; * WvSystem(argv); */ WvSystem(const char * const *argv) { init(argv); } /** * Destroy the WvSystem object. If you haven't yet called go(), the * command is run before destruction. */ virtual ~WvSystem(); /** * Explicitly start the command running and wait for it to finish. * This will happen automatically at object destruction time, but if you * want to check the return code, you'll need to call go(). */ int go(); /** Redirect stdin from the given input file. */ WvSystem &infile(WvStringParm filename); /** Redirect stdout to the given output file, which is overwritten. */ WvSystem &outfile(WvStringParm filename); /** Redirect stderr to the given output file, which is overwritten. */ WvSystem &errfile(WvStringParm filename); private: bool started; WvString fdfiles[3]; // stdin, stdout, stderr void init(const char * const *argv); virtual int fork(int *waitfd); }; #endif // __WVSYSTEM_H wvstreams-4.6.1/include/wvipaliaser.h0000644000175000001440000000427711036722347016733 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVIPALIASER_H #define __WVIPALIASER_H #include "wvinterface.h" #include "wvaddr.h" /** * WvIPAliaser handles IP aliasing in the Linux kernel. Multiple instances * of the object can be created, and they will share aliases between them. * Aliased addresses are only removed when all WvIPAliaser objects using * that address give it up. (ie. the object is destroyed, or the Aliaser * is reconfigured without including that address) */ class WvIPAliaser { struct Alias { int index, link_count; WvIPAddr ip; Alias(const WvIPAddr &_ip); ~Alias(); }; DeclareWvList(Alias); static AliasList all_aliases; AliasList aliases; WvInterfaceDict interfaces; WvIPAliaser::Alias *ipsearch(WvIPAliaser::AliasList &l, const WvIPAddr &ip); public: WvIPAliaser(); ~WvIPAliaser(); void dump(); /** * you must call start_edit() once, then add() any number of times, then * done_edit() once, to change your aliases. The addresses add()ed * during the session become the _only_ ones that are aliases by this * WvIPAliaser instance. * * Why bother? This way, WvIPAliaser can see all the desired aliases * when they are being changed, and only delete previously-added ones * if they are no longer used. This is important, since if eg. Fast * Forward has an open connection through 1.2.3.4, and we want to add * 1.2.3.5 and delete 1.2.3.3, Fast Forward need not remember that it * was using 1.2.3.3 but 1.2.3.4 does not get deleted, even temporarily. * * If that was too confusing, just remember: call these functions in * the order they appear below, always. * * If add() returns true, then an interface was just created. If it returns * false, then that call made no changes. * * If done_edit() returns true, then one or more interfaces were just * destroyed. If it returns false, then that call made no changes. */ void start_edit(); bool add(const WvIPAddr &ip); bool done_edit(); }; #endif // __WVIPALIASER_H wvstreams-4.6.1/include/wvcrash.h0000644000175000001440000000250211036722347016047 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Routines to generate a stack backtrace automatically when a program * crashes. */ #ifndef __WVCRASH_H #define __WVCRASH_H #include void wvcrash_setup(const char *_argv0, const char *_desc = 0); void wvcrash(int sig); void wvcrash_add_signal(int sig); // Leave a last will and testament in the WvCrash, if your program dies. void wvcrash_leave_will(const char *will); // Read the will back. const char *wvcrash_read_will(); // Read the assertion back. const char *wvcrash_read_assert(); class IWvStream; struct WvCrashInfo { // This is kind of ugly and used only for the guts of WvStreams, // but it's a significant rather than a premature optimization, // unfortunately. static IWvStream *in_stream; static const char *in_stream_id; static enum InStreamState { UNUSED, PRE_SELECT, POST_SELECT, EXECUTE, } in_stream_state; }; const int wvcrash_ring_buffer_order = 12; const int wvcrash_ring_buffer_size = 1 << wvcrash_ring_buffer_order; void wvcrash_ring_buffer_put(const char *str); void wvcrash_ring_buffer_put(const char *str, size_t len); const char *wvcrash_ring_buffer_get(); #if defined(_WIN32) extern void setup_console_crash(); #endif #endif // __WVCRASH_H wvstreams-4.6.1/include/wvlog.h0000644000175000001440000001012711036722347015532 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generic data-logger class with support for multiple receivers. If * no WvLogRcv objects have been created (see wvlogrcv.h) the default is * to log to stderr. * * WvLog supports partial- and multiple-line log messages. For example, * log.print("test "); * log.print("string\nfoo"); * will print: * appname(lvl): test string * appname(lvl): foo */ #ifndef __WVLOG_H #define __WVLOG_H #include "wvstream.h" #include #ifdef _WIN32 typedef int pid_t; #endif class WvLog; // a WvLogRcv registers itself with WvLog and prints, captures, // or transmits log messages. class WvLogRcvBase { friend class WvLog; protected: const char *appname(WvStringParm log) const; virtual void log(WvStringParm source, int loglevel, const char *_buf, size_t len) = 0; private: static void cleanup_on_fork(pid_t p); static void static_init(); public: bool force_new_line; WvLogRcvBase(); virtual ~WvLogRcvBase(); }; DeclareWvList(WvLogRcvBase); typedef wv::function WvLogFilter; /** * A WvLog stream accepts log messages from applications and forwards them * to all registered WvLogRcv's. */ class WvLog : public WvStream { friend class WvLogRcvBase; public: enum LogLevel { Critical = 0, Error, Warning, Notice, Info, Debug, Debug1=Debug, Debug2, Debug3, Debug4, Debug5, NUM_LOGLEVELS }; WvString app; protected: LogLevel loglevel; static WvLogRcvBaseList *receivers; static int num_receivers, num_logs; static WvLogRcvBase *default_receiver; WvLogFilter* filter; public: WvLog(WvStringParm _app, LogLevel _loglevel = Info, WvLogFilter* filter = 0); WvLog(const WvLog &l); virtual ~WvLog(); /** fd==-1, but this stream is always ok */ virtual bool isok() const; /* always writable */ virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); /** * change the loglevel. This returns the object again, so you can * make convenient statements like log.lvl(WvLog::Warning).print(...) */ WvLog &lvl(LogLevel _loglevel) { loglevel = _loglevel; return *this; } /** change the loglevel and then print a message. */ size_t operator() (LogLevel _loglevel, WvStringParm s) { LogLevel l = loglevel; size_t x = lvl(_loglevel).write(filter ? (*filter)(s) : s); lvl(l); return x; } /** change the loglevel and then print a formatted message */ size_t operator() (LogLevel _loglevel, WVSTRING_FORMAT_DECL) { LogLevel l = loglevel; size_t x; if (filter) x = lvl(_loglevel).print((*filter)(WvString(WVSTRING_FORMAT_CALL))); else x = lvl(_loglevel).print(WVSTRING_FORMAT_CALL); lvl(l); return x; } /** * although these appear in WvStream, they need to be re-listed here * since the above operator()s caused them to be hidden */ size_t operator() (WvStringParm s) { return WvStream::operator()(filter ? (*filter)(s) : s); } size_t operator() (WVSTRING_FORMAT_DECL) { return (filter ? WvStream::operator()((*filter)(WvString(WVSTRING_FORMAT_CALL))) : WvStream::operator()(WVSTRING_FORMAT_CALL) ); } /** * split off a new WvLog object with the requested loglevel. This way * you can have log at two or more levels without having to retype * log.lvl(WvLog::blahblah) all the time. */ WvLog split(LogLevel _loglevel) const { return WvLog(app, _loglevel, filter); } /** * we override the unbuffered write function, so lines also include the * application and log level. */ virtual size_t uwrite(const void *buf, size_t len); /** a useful substitute for the normal C perror() function */ void perror(WvStringParm s) { print("%s: %s\n", s, strerror(errno)); } public: const char *wstype() const { return "WvLog"; } }; #endif // __WVLOG_H wvstreams-4.6.1/include/wvsyslog.h0000644000175000001440000000143411036722347016272 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVSYSLOG_H #define __WVSYSLOG_H #include "wvlogrcv.h" /** * WvSyslog is a descendant of WvLogRcv that sends messages to the syslogd * daemon. */ class WvSyslog : public WvLogRcv { public: WvSyslog(WvStringParm _prefix, bool _include_appname, WvLog::LogLevel _first_debug = WvLog::Debug, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvSyslog(); protected: WvLog::LogLevel first_debug; WvDynBuf current; WvString syslog_prefix; bool include_appname; virtual void _begin_line(); virtual void _mid_line(const char *str, size_t len); virtual void _end_line(); }; #endif // __WVLOGBUFFER_H wvstreams-4.6.1/include/wvloopback2.h0000644000175000001440000000161311036722347016625 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVLOOPBACK2_H #define __WVLOOPBACK2_H #include "wvfdstream.h" /** * A two-way WvLoopback. Uses a socketpair() to create two streams that * allow you to read() from one everything written to the other and vice * versa, even (especially) across a fork() call. * * s1 and s2 are changed to point at the pair of streams. There is no * condition in which this function returns without setting s1 and s2 to * valid non-NULL streams. * * You are responsible for doing WVRELEASE on each of the returned streams. * * In case of an error, nonfunctional streams are created and returned, and * they have their error codes set appropriately. * * See also WvLoopback, WvBufStream. */ void wvloopback2(IWvStream *&s1, IWvStream *&s2); #endif // __WVLOOPBACK2_H wvstreams-4.6.1/include/wvmatrix.h0000644000175000001440000000122311036722347016252 0ustar wlachusers/* -*- Mode: C++ -*- */ #ifndef __WVMATRIX_H #define __WVMATRIX_H #include "wvstring.h" class WvMatrix { public: int *data; int m; int n; WvMatrix(const int _m, const int _n, const int *_data = 0); ~WvMatrix(); WvMatrix(const WvMatrix& mx); WvMatrix& operator= (const WvMatrix& mx); int& operator() (const int row, const int col) { return data[n*row + col]; } int operator() (const int row, const int col) const { return data[n*row + col]; } WvMatrix operator+ (const WvMatrix &rhs) const; WvMatrix operator* (const WvMatrix &rhs) const; WvString printable(); }; #endif // __WVMATRIX_H wvstreams-4.6.1/include/wvtypedencoder.h0000644000175000001440000001445111036722347017442 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * An abstraction for encoders that manipulate typed buffers. */ #ifndef __WVTYPEDENCODER_H #define __WVTYPEDENCODER_H #include "wvencoder.h" #include "wvbufbase.h" /** * This template facilitates the creation and use of encoders * that manipulate typed buffers. * * A typed encoder accepts both typed and untyped buffers, but * is implementated in terms of typed buffers. Untyped buffers * are automatically wrapped into the required form before being * passed on to the implementation. * * This type is designed to function as a statically bound mixin * to make it easier to incorporate typed encoders into untyped * encoder hierarchies. This is somewhat ugly, but necessary. * * * "IT" is the input buffer datatype * "OT" is the output buffer datatype * "S" is the WvEncoder supertype * @see WvEncoder */ template class WvTypedEncoder : public S { public: typedef IT IType; typedef OT OType; typedef WvBufBase IBuffer; typedef WvBufBase OBuffer; typedef WvBufViewBase IBufferView; typedef WvBufViewBase OBufferView; /** * Typed variant of encode(). * @see encode(WvBuf&, WvBuf&, bool, bool) */ bool encode(IBuffer &inbuf, OBuffer &outbuf, bool flush = false, bool finish = false) { WvBufView inview(inbuf); WvBufView outview(outbuf); return S::encode(inview, outview, flush, finish); } /** * Typed variant of flush(). * @see flush(WvBuf, WvBuf, bool) */ bool flush(IBuffer &inbuf, OBuffer &outbuf, bool finish = false) { WvBufView inview(inbuf); WvBufView outview(outbuf); return S::flush(inview, outview, finish); } /** * Typed variant of finish(). * @see finish(WvBuf) */ bool finish(OBuffer &outbuf) { WvBufView outview(outbuf); return S::finish(outview); } bool encode(WvBuf &inbuf, WvBuf &outbuf, bool flush = false, bool finish = false) { return S::encode(inbuf, outbuf, flush, finish); } bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish = false) { return S::flush(inbuf, outbuf, finish); } bool finish(WvBuf &outbuf) { return S::finish(outbuf); } protected: /** * Typed variant of _encode(). * @see _encode(WvBuf&, WvBuf&, bool) */ virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf, bool flush) = 0; /** * Typed variant of _finish(). * @see _finish(WvBuf&) */ virtual bool _typedfinish(OBuffer &outbuf) { return true; } /** Wrapper implementation of _encode(). */ virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { IBufferView inview(inbuf); OBufferView outview(outbuf); return _typedencode(inview, outview, flush); } /** Wrapper implementation of _finish(). */ virtual bool _finish(WvBuf &outbuf) { OBufferView outview(outbuf); return _typedfinish(outview); } }; /** * Partial template specialization for unsigned char output * buffer type to avoid compilation errors. * * "IType" is the input buffer datatype */ template class WvTypedEncoder : public S { public: typedef IT IType; typedef unsigned char OType; typedef WvBufBase IBuffer; typedef WvBufBase OBuffer; typedef WvBufViewBase IBufferView; typedef WvBufViewBase OBufferView; /** * Typed variant of encode(). * @see encode(WvBuf&, WvBuf&, bool, bool) */ bool encode(IBuffer &inbuf, OBuffer &outbuf, bool flush = false, bool finish = false) { WvBufView inview(inbuf); return S::encode(inview, outbuf, flush, finish); } /** * Typed variant of flush(). * @see flush(WvBuf, WvBuf, bool) */ bool flush(IBuffer &inbuf, OBuffer &outbuf, bool finish = false) { WvBufView inview(inbuf); return S::flush(inview, outbuf, finish); } bool encode(WvBuf &inbuf, WvBuf &outbuf, bool flush = false, bool finish = false) { return S::encode(inbuf, outbuf, flush, finish); } bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish = false) { return S::flush(inbuf, outbuf, finish); } protected: /** * Typed variant of _encode(). * @see _encode(WvBuf&, WvBuf&, bool) */ virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf, bool flush) = 0; /** * Typed variant of _finish(). * @see _finish(WvBuf&) */ virtual bool _typedfinish(OBuffer &outbuf) { return true; } /** Wrapper implementation of _encode(). */ virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { IBufferView inview(inbuf); return _typedencode(inview, outbuf, flush); } /** Wrapper implementation of _finish(). */ virtual bool _finish(WvBuf &outbuf) { return _typedfinish(outbuf); } }; /** * Partial template specialization for unsigned char input * and output buffer types to avoid compilation errors. */ template class WvTypedEncoder : public S { public: typedef unsigned char IType; typedef unsigned char OType; typedef WvBufBase IBuffer; typedef WvBufBase OBuffer; typedef WvBufViewBase IBufferView; typedef WvBufViewBase OBufferView; protected: /** * Typed variant of _encode(). * @see _encode(WvBuf&, WvBuf&, bool) */ virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf, bool flush) = 0; /** * Typed variant of _finish(). * @see _finish(WvBuf&) */ virtual bool _typedfinish(OBuffer &outbuf) { return true; } /** Wrapper implementation of _encode(). */ virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { return _typedencode(inbuf, outbuf, flush); } /** Wrapper implementation of _finish(). */ virtual bool _finish(WvBuf &outbuf) { return _typedfinish(outbuf); } }; #endif // __WVTYPEDENCODER wvstreams-4.6.1/include/wvverstring.h0000644000175000001440000000420711036722347016776 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Version number and string manipulations. * * The old version number was a 32-bit hexadecimal number, split into a 16-bit * major version and a 16-bit minor version. For example, the old-style string * equivalent of 0x00012a00 would be "1.2a". * * The new-style version number is a 32-bit hexadecimal number, split into * an 8-bit major version, an 8-bit minor version, and a 16-bit revision * number. The new-style string equivalent of 0x01020150 would be "1.02.0150". */ #ifndef __WVVERSTRING_H #define __WVVERSTRING_H /** Converts a version number to a C string. * This uses is_new_ver() to determine which style to use for the resulting * string. */ const char *ver_to_string(unsigned int ver); /// Converts a version number to a C string using the old style. const char *old_ver_to_string(unsigned int ver); /// Converts a version number to a C string using the new sytle. const char *new_ver_to_string(unsigned int ver); /** Converts a C string to a version number. * This uses is_new_verstr() to determine which style to use for the resulting * version integer. */ unsigned int string_to_ver(const char *str); /// Converts a C string to a version number using the old style. unsigned int string_to_old_ver(const char *str); /// Converts a C string to a version number using the new style. unsigned int string_to_new_ver(const char *str); /** Returns true if 'ver' is in the new style. * If the first two hex digits are non-zero, it is the old style; otherwise, * it's the new style. This somewhat arbitrary distinction was made to ease * migration of some WvStreams projects. Use the specific new and old * functions if you don't like this. */ bool is_new_ver(unsigned int ver); /** Returns true if 'str' is in the new style. * If there are 2 periods ('.') in the string, it is the new style; otherwise, * it's the old style. */ bool is_new_verstr(const char *str); /** Trims zeroes off the end of a version string. * Used by old-style functions only. */ char *trim_verstr(char *verstr); #endif // __WVVERSTRING_H wvstreams-4.6.1/include/wvcrl.h0000644000175000001440000000772611077124114015535 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2007 Net Integration Technologies, Inc. and others. * * X.509v3 CRL management class. */ #ifndef __WVCRL_H #define __WVCRL_H #include "wverror.h" #include "wvlog.h" #include "wvx509.h" // Structures to make the compiler happy so we don't have to include x509v3.h ;) struct X509_crl_st; typedef struct X509_crl_st X509_CRL; struct ssl_ctx_st; typedef struct ssl_ctx_st SSL_CTX; struct asn1_string_st; typedef struct asn1_string_st ASN1_INTEGER; class WvX509Mgr; /** * CRL Class to handle certificate revocation lists and their related * functions */ class WvCRL { public: /** * Type for the @ref encode() and @ref decode() methods: * CRLPEM = PEM Encoded X.509 CRL * CRLDER = DER Encoded X.509 CRL * CRLFilePEM = PEM Encoded X.509 CRL * CRLFileDER = DER Encoded X.509 CRL */ enum DumpMode { CRLPEM = 0, CRLDER, CRLFilePEM, CRLFileDER }; /** * Initialize a blank (null) CRL object. */ WvCRL(); /** * Initialize a CRL object, signed and created by the certificate * 'ca'. */ WvCRL(const WvX509Mgr &ca); /** Destructor */ virtual ~WvCRL(); /** Accessor for CRL */ X509_CRL *getcrl() { return crl; } /** * Check the CRL in crl against the CA certificate in cert * - returns true if CRL was signed by that CA certificate. */ bool signedbyca(const WvX509 &cacert) const; /** * Check the issuer name of the CRL in crl against the CA certificate in cert * - returns true if the names match. */ bool issuedbyca(const WvX509 &cacert) const; /** * Checks to see if the CRL is expired (i.e.: the present time is past the * nextUpdate extension). * - returns true if CRL has expired. */ bool expired() const; /* * Checks to see if the CRL has any critical extensions in it. * - returns true if the CRL has any critical extensions. */ bool has_critical_extensions() const; /** * Type for @ref validate() method: * ERROR = there was an error that happened.. * VALID = the certificate is valid * NOT_THIS_CA = the certificate is not signed by this CA * NO_VALID_SIGNATURE = the certificate claims to be signed by this CA (Issuer is the same), * but the signature is invalid. */ enum Valid { CRLERROR = -1, VALID, NOT_THIS_CA, NO_VALID_SIGNATURE, EXPIRED, UNHANDLED_CRITICAL_EXTENSIONS }; /** * Checks to see that a CRL is signed and issued by a CA certificate, and * that it has not expired. * - returns a validity status. * Get the Authority key Info */ Valid validate(const WvX509 &cacert) const; /** * Get the Authority key Info */ WvString get_aki() const; /** * Get the CRL Issuer. */ WvString get_issuer() const; /** * Do we have any errors... convenience function.. */ bool isok() const; /** * Return the information requested by mode as a WvString. */ WvString encode(const DumpMode mode) const; void encode(const DumpMode mode, WvBuf &buf) const; /** * Load the information from the format requested by mode into * the class - this overwrites the CRL. */ void decode(const DumpMode mode, WvStringParm encoded); void decode(const DumpMode mode, WvBuf &encoded); /** * Is the certificate in cert revoked? */ bool isrevoked(const WvX509 &cert) const; bool isrevoked(WvStringParm serial_number) const; /** * Add the certificate specified by cert to the CRL. */ void addcert(const WvX509 &cert); /** * Counts the number of certificates in this CRL. * WARNING: this method will be very slow and will consume a lot * of memory for large CRLs. */ int numcerts() const; private: mutable WvLog debug; X509_CRL *crl; }; #endif // __WVCRL_H wvstreams-4.6.1/include/wvmoniker.h0000644000175000001440000000636311057766345016435 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Support for monikers, which are strings that you can pass to a magic * factory to get objects supporting a particular interface, without actually * knowing anything about the constructor for those objects. */ #ifndef __WVMONIKER_H #define __WVMONIKER_H #include "wvstring.h" #include "wvxplc.h" class WvMonikerRegistry; typedef void *WvMonikerCreateFunc(WvStringParm parms, IObject *obj); /** * WvMonikerBase is an auto-registration class for putting things into * a WvMonikerRegistry. When a WvMonikerBase instance is created, it * registers a moniker prefix ("test:", "ssl:", "ini:", etc) and a factory * function that can be used to create an IObject using that prefix. * * When the instance is destroyed, it auto-unregisters the moniker prefix * from the registry. * * You can't actually create one of these, because it's not typesafe. See * WvMoniker instead. */ class WvMonikerBase { protected: WvMonikerBase(const UUID &iid, WvStringParm _id, WvMonikerCreateFunc *func, const bool override = false); ~WvMonikerBase(); public: WvString id; WvMonikerRegistry *reg; }; /** * A type-safe version of WvMonikerBase that lets you provide create functions * for object types other than IObject. (The objects themselves have to * be derived from IObject, however.) * * See WvMonikerBase for details. * * Example: * static IWvStream *createfunc(WvStringParm s, IObject *obj, * void *userdata) * { * return new WvStream; * } * * static WvMoniker registration("ssl", createfunc); */ template class WvMoniker : public WvMonikerBase { public: typedef T *CreateFunc(WvStringParm parms, IObject *obj); WvMoniker(WvStringParm _id, CreateFunc *_func, const bool override = false) : WvMonikerBase(XPLC_IID::get(), _id, (WvMonikerCreateFunc *)_func, override) { // this looks pointless, but it ensures that T* can be safely, // automatically downcast to IObject*. That means T is really derived // from IObject, which is very important. The 'for' avoids a // warning. for(IObject *silly = (T *)NULL; silly; ) ; }; }; /** * Create an object registered in a WvMonikerRegistry. The iid specifies * which registry to look in, and s, obj, and userdata are the parameters to * supply to the object's factory. Most factories need only 's', which is the * moniker itself. * * Most people don't use this function. See the templated, type-safe version * of wvcreate() below. */ void *wvcreate(const UUID &iid, WvStringParm s, IObject *obj); /** * Create an object registered in a WvMonikerRegistry. Exactly which * registry is determined by the template type T. * * s, obj, and userdata are the parameters to supply to the object's * factory. Most factories need only 's', which is the moniker itself. * * Example: * IWvStream *s = wvcreate("tcp:localhost:25"); * IWvStream *s_ssl = wvcreate("ssl:", s); */ template inline T *wvcreate(WvStringParm s, IObject *obj = 0) { return (T *)(wvcreate(XPLC_IID::get(), s, obj)); } #endif // __WVMONIKER_H wvstreams-4.6.1/include/uniwvconfgen.h0000644000175000001440000000203311036722347017101 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A generator to make a UniConf object out of a WvConf. */ #ifndef __UNICONFWVGEN_H #define __UNICONFWVGEN_H #include "uniconfgen.h" class WvConf; /** * A UniConf generator for backwards compatibility with WvConf */ class UniWvConfGen : public UniConfGen { private: UniConfKey *tempkey; WvString tempvalue; void notify(void *userdata, WvStringParm section, WvStringParm entry, WvStringParm oldval, WvStringParm newval); protected: WvConf *cfg; class WvConfIter; public: UniWvConfGen(WvConf *_cfg); ~UniWvConfGen(); /***** Overridden members *****/ virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); }; #endif //__UNICONFWVGEN_H wvstreams-4.6.1/include/unihashtree.h0000644000175000001440000000463511036722347016722 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniConf low-level tree storage abstraction. */ #ifndef __UNIHASHTREE_H #define __UNIHASHTREE_H #include "uniconfkey.h" #include "wvtr1.h" #include "wvscatterhash.h" class UniHashTreeBase; // parameters: a node (won't be NULL), userdata typedef wv::function UniHashTreeBaseVisitor; // parameters: 1st node (may be NULL), 2nd node (may be NULL), userdata typedef wv::function UniHashTreeBaseComparator; class UniHashTreeBase { protected: struct Accessor { static const UniConfKey *get_key(const UniHashTreeBase *obj) { return &obj->key(); } }; typedef WvScatterHash Container; typedef UniHashTreeBaseVisitor BaseVisitor; typedef UniHashTreeBaseComparator BaseComparator; public: ~UniHashTreeBase(); /** Returns the key field. */ const UniConfKey &key() const { return xkey; } /** Returns true if the node has children. */ bool haschildren() const; protected: UniHashTreeBase(UniHashTreeBase *parent, const UniConfKey &key); UniConfKey _fullkey(const UniHashTreeBase *ancestor = NULL) const; UniHashTreeBase *_find(const UniConfKey &key) const; UniHashTreeBase *_findchild(const UniConfKey &key) const; static bool _recursivecompare( const UniHashTreeBase *a, const UniHashTreeBase *b, const UniHashTreeBaseComparator &comparator); static void _recursive_unsorted_visit( const UniHashTreeBase *a, const UniHashTreeBaseVisitor &visitor, void *userdata, bool preorder, bool postorder); UniHashTreeBase *xparent; /*!< the parent of this subtree */ Container *xchildren; /*!< the hash table of children */ private: void _setparent(UniHashTreeBase *parent); UniHashTreeBase *_root() const; /** Called by a child to link itself to this node. */ void link(UniHashTreeBase *node); /** Called by a child to unlink itself from this node. */ void unlink(UniHashTreeBase *node); UniConfKey xkey; /*!< the name of this entry */ protected: class Iter : public Container::Iter { public: Iter(UniHashTreeBase &b) : Container::Iter(*b.xchildren) { } }; friend class Iter; }; #endif //__UNIHASHTREE_H wvstreams-4.6.1/include/wvresolver.h0000644000175000001440000000303011036722347016605 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * DNS name resolver with support for background lookups. */ #ifndef __WVRESOLVER_H #define __WVRESOLVER_H #include "wvaddr.h" #include "wvstream.h" #include "wvlinklist.h" #include "wvhashtable.h" class WvResolverHost; class WvResolverAddr; DeclareWvDict(WvResolverHost, WvString, name); DeclareWvDict(WvResolverAddr, WvIPAddr, addr[0]); DeclareWvList(WvIPAddr); /** ASynchronous DNS resolver functions, so that we can do non-blocking lookups */ class WvResolver { static int numresolvers; static WvResolverHostDict *hostmap; static WvResolverAddrDict *addrmap; public: WvResolver(); ~WvResolver(); /** * Return -1 on timeout, or the number of addresses found, which may * be 0 if the address does not exist. * addrlist, if present, has to be an initialized list. * addr points to an internal WvIPAddr and will be deleted automatically. */ int findaddr(int msec_timeout, WvStringParm name, WvIPAddr const **addr, WvIPAddrList *addrlist = NULL); int findname(int msec_timeout, WvIPAddr *ipaddr, char **name); void clearhost(WvStringParm hostname); /** add all of our waiting fds to an fd_set for use with select(). */ void pre_select(WvStringParm hostname, WvStream::SelectInfo &si); /** determines whether the resolving process is complete. */ bool post_select(WvStringParm hostname, WvStream::SelectInfo &si); }; #endif // __WVRESOLVER_H wvstreams-4.6.1/include/unidefgen.h0000644000175000001440000000420411036722347016337 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniDefGen is a UniConfGen for retrieving data with defaults * * Usable with the moniker default: */ #ifndef __UNIDEFGEN_H #define __UNIDEFGEN_H #include "unifiltergen.h" /* * The defaults are stored and accessed by using a * in the keyname. The * * can represent either a segment of the path, or can can be left as a key * in a path so that any search to that path returns a result. * * (note: odd spacing is only to avoid putting * and / directly together) * * For example, you could set /twister/expression/ * /reality = * "/tmp/twister" and then a search for /twister/expression/bob/reality * would return the result. * * There is no limitation on where the * can be placed or the number of *s. * For example: /twister/ * / * / reality / * * would be an acceptable (though somewhat insane) use. This would make it * so a search to /twister/(whatever)/(whatever)/reality/(whatever) would * always return a key. * * If a more absolute path exists, then it will be returned instead of the * defaults. Precedence is given to matches existing closer to the end of * the key. * * If the key is set to '*n', it will return the n'th element from the end of * the absolute path that was passed in. For instance, if * /twister/ * / * / reality is set to *1, then a search for * /twister/expression/bob/reality will return 'bob'. If it is set to *2, the * search will return 'expression'. If it were set to *3 (or *0), the result is * undefined. */ class UniDefGen : public UniFilterGen { UniConfKey finddefault(const UniConfKey &key, char *p, char *q); WvString replacewildcard(const UniConfKey &key, const UniConfKey &defkey, WvStringParm in); public: UniDefGen(IUniConfGen *gen) : UniFilterGen(gen) { } /***** Overridden members *****/ virtual bool keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key); virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); }; #endif // __UNIDEFGEN_H wvstreams-4.6.1/include/wvtcplistener.h0000644000175000001440000000245111203076507017302 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStream-based TCP connection and server classes. */ #ifndef __WVTCPLISTENER_H #define __WVTCPLISTENER_H #include "wvlistener.h" #include "wvaddr.h" class WvIStreamList; /** Class to easily create the Server side of a WvTCPConn. */ class WvTCPListener : public WvListener { public: /** * Create a WvStream that listens on _listenport of the current machine * This is how you set up a TCP Server. */ WvTCPListener(const WvIPPortAddr &_listenport); virtual ~WvTCPListener(); /** * return a new WvTCPConn socket corresponding to a newly-accepted * connection. If no connection is ready immediately, we may end up * blocking, or we may return NULL. You should use select(read=true) * to check for a waiting connection. */ virtual IWvStream *accept(); /** src() is a bit of a misnomer, but it returns the listener port. */ virtual const WvIPPortAddr *src() const; protected: WvIPPortAddr listenport; void accept_callback(WvIStreamList *list, wv::function cb, IWvStream *_connection); public: const char *wstype() const { return "WvTCPListener"; } }; #endif // __WVTCP_H wvstreams-4.6.1/include/unifiltergen.h0000644000175000001440000000476411036722347017101 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen framework to simplify writing filtering generators. */ #ifndef __UNIFILTERGEN_H #define __UNIFILTERGEN_H #include "uniconfgen.h" /** * A UniConfGen that delegates all requests to an inner generator. If you * derive from this, you can selectively override particular behaviours * of a sub-generator. */ class UniFilterGen : public UniConfGen { IUniConfGen *xinner; protected: UniFilterGen(IUniConfGen *inner); virtual ~UniFilterGen(); /** * Rebinds the inner generator and prepares its callback. * The previous generator is NOT destroyed. */ void setinner(IUniConfGen *inner); public: /** Returns the inner generator. */ IUniConfGen *inner() const { return xinner; } /** * A mapping function for filters that remap one keyspace onto another. * * The default implementation of the various functions (get, set, * exists, etc) run their keys through this function before forwarding * the requests on to the inner generator. * * The default implementation of this function doesn't change the key. * * Returns true if the key can be mapped, else false. */ virtual bool keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key); /** * A mapping function for filters that unmap a keyspace. * * The default implementation of this function doesn't change the key. * * Returns true if the key can be reverse-mapped, else false. */ virtual bool reversekeymap(const UniConfKey &mapped_key, UniConfKey &unmapped_key); /***** Overridden methods *****/ virtual void commit(); virtual bool refresh(); virtual void flush_buffers(); virtual void prefetch(const UniConfKey &key, bool recursive); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual bool isok(); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); protected: /** * Called by inner generator when a key changes. * The default implementation calls delta(key). */ virtual void gencallback(const UniConfKey &key, WvStringParm value); }; #endif //__UNIFILTERGEN_H wvstreams-4.6.1/include/wvudp.h0000644000175000001440000000363411036722347015546 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVUDP_H #define __WVUDP_H #include "wvfdstream.h" #include "wvaddr.h" /** * WvUDPStream can send and receive packets on a connectionless UDP socket. * * In the constructor, the socket is attached using bind() to the given * _local address. If the address is 0.0.0.0, all addresses on the local * host are used; if the port is 0, an available port number is chosen * automatically. * * If the _rem address is 0.0.0.0, the port is not connect()ed. That means * it can receive packets from anywhere and send them to anywhere. The * src() and setdest() functions are useful for this. If _rem is not 0.0.0.0, * connect() is called and the socket will only accept data to/from the * specified remote UDP address. * * Buffering: all the usual WvStream-style input buffering is available, * including getline(), but because input packets may get lost it is of * limited usefulness. Buffering will cause particular confusion if the * socket is not connect()ed. */ class WvUDPStream : public WvFDStream { public: /** connect a new socket */ WvUDPStream(const WvIPPortAddr &_local, const WvIPPortAddr &_rem); virtual ~WvUDPStream(); const WvAddr *local() const; /** * return the remote address (source of incoming packets, target of * outgoing packets). This is the last host sent to or received from, * whichever was more recent. */ virtual const WvAddr *src() const; void setdest(const WvIPPortAddr &_remaddr) { remaddr = _remaddr; } void enable_broadcasts(); protected: WvIPPortAddr localaddr, remaddr; virtual size_t uread(void *buf, size_t count); virtual size_t uwrite(const void *buf, size_t count); public: const char *wstype() const { return "WvUDPStream"; } }; #endif // __WVUDP_H wvstreams-4.6.1/include/uniconfroot.h0000644000175000001440000001112711036722347016742 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines the root management class for UniConf. */ #ifndef __UNICONFROOT_H #define __UNICONFROOT_H #include "uniconf.h" #include "uniconftree.h" #include "unimountgen.h" /** * @internal * Holds information about a single watch. */ class UniWatchInfo { public: void *cookie; bool recurse; UniConfCallback cb; UniWatchInfo(void *_cookie, bool _recurse, UniConfCallback _cb) : cookie(_cookie), recurse(_recurse), cb(_cb) { } /** Returns watch recursion */ bool recursive() { return recurse; } /** Notifies that a key has changed. */ void notify(const UniConf &cfg, const UniConfKey &key) { cb(cfg, key); } /** Equality test. */ bool operator== (const UniWatchInfo &other) const { return other.cookie == cookie; } }; DeclareWvList(UniWatchInfo); /** * @internal * Data structure to track requested watches. */ class UniWatchInfoTree : public UniConfTree { public: UniWatchInfoList watches; UniWatchInfoTree(UniWatchInfoTree *parent, const UniConfKey &key = UniConfKey::EMPTY) : UniConfTree(parent, key) { } /** Returns true if the node should not be pruned. */ bool isessential() { return haschildren() || ! watches.isempty(); } }; /** * Represents the root of a hierarhical registry consisting of pairs * of UniConfKeys and associated string values. * * Any number of data containers may be mounted into the tree at any * number of mount points to provide a backing store from which * registry keys and values are fetched and into which they are * stored. Multiple data containers may be mounted at the same * location using standard unix semantics. */ class UniConfRoot : public UniConf { friend class UniConf; friend class UniConf::Iter; friend class UniConf::RecursiveIter; UniWatchInfoTree watchroot; /** undefined. */ UniConfRoot(const UniConfRoot &other); public: /** Creates an empty UniConf tree with no mounted stores. */ UniConfRoot(); /** * Creates a new UniConf tree and mounts the given moniker at the root. * Since most people only want to mount one generator, this should save * a line of code here and there. */ UniConfRoot(WvStringParm moniker, bool refresh = true); /** * Creates a new UniConf tree and mounts the given generator at the root. * Since most people only want to mount one generator, this should save * a line of code here and there. */ UniConfRoot(UniConfGen *gen, bool refresh = true); /** Destroys the UniConf tree along with all uncommitted data. */ ~UniConfRoot(); /** * Requests notification when any of the keys covered by the * recursive depth specification change by invoking a callback. */ void add_callback(void *cookie, const UniConfKey &key, const UniConfCallback &callback, bool recurse = true); /** * Cancels notification requested using add_callback(). */ void del_callback(void *cookie, const UniConfKey &key, bool recurse = true); /** * Requests notification when any of the keys covered by the * recursive depth specification change by setting a flag. */ void add_setbool(const UniConfKey &key, bool *flag, bool recurse = true); /** * Cancels notification requested using add_setbool(). */ void del_setbool(const UniConfKey &key, bool *flag, bool recurse = true); private: /** * Checks a branch of the watch tree for notification candidates. * node - the current node * key - the key that changed * segleft - the number of segments left in the key (possibly negative) */ void check(UniWatchInfoTree *node, const UniConfKey &key, int segleft); /** * Recursively checks a branch of the watch tree for notification candidates. * node - the current node * key - the key that changed */ void deletioncheck(UniWatchInfoTree *node, const UniConfKey &key); /** Prunes a branch of the watch tree. */ void prune(UniWatchInfoTree *node); /** Callback from UniMountTreeGen (FIXME: that's a lie.) */ void gen_callback(const UniConfKey &key, WvStringParm value); protected: friend class UniUnwrapGen; UniMountGen mounts; public: /** Internal callback for setbool style notifications. */ static void setbool_callback(bool *flag, const UniConf &, const UniConfKey &) { *flag = true; } }; #endif //__UNICONFROOT_H wvstreams-4.6.1/include/wvdaemon.h0000644000175000001440000001451211077124114016207 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * High-level abstraction for creating daemon processes. Handles * command-line argument processing, forking into the background, * and signal handling. */ #ifndef __WVDAEMON_H #define __WVDAEMON_H #include "wvstring.h" #include "wvargs.h" #include "wvlog.h" class WvDaemon; typedef wv::function WvDaemonCallback; /*! @brief WvDaemon - High-level abstraction for creating daemon processes. WvDaemon makes it easy to create daemon processes that support forking into the background and detaching from terminals, management of the .pid file and the log file, and handling of the SIGTERM|SIGINT|SIGQUIT and SIGHUP signals. By default, daemons implemented through WvDaemon provide the following command line options: -q|--quiet: decrease the log level by one -v|--verbose: increase the log level by one -d|--daemonize: fork into the background (implies --syslog) -s|--syslog: write log entries to the syslog() facility --no-syslog: do not write log entries to the syslog() facility -V|--version: print the program name and version number and exit immediately These default arguments can be changed or appended to through the public member WvDaemon::args of type WvArgs. By default, daemons run in the foreground for debugging purposes; you must pass the -d parameter to force them into the background. The actual functionality of WvDaemon is implemented through five protected member callbacks: WvDaemon::load_callback: Called as soon as the arguments are processed and the process has (optionally) daemonized WvDaemon::start_callback: Called after WvDaemon::load_callback and after restarting due to SIGHUP WvDaemon::run_callback: The main loop callback. - It must return if it ever expects that the daemon should exit or restart, ie. after having called WvDaemon::die() or WvDaemon::restart(); otherwise the daemon will never exit WvDaemon::stop_callback: Called when the daemon is exiting or right before restarting due to SIGHUP WvDaemon::unload_callback: Called right before the daemon exits Sample usage: @code #include void run(WvDaemon &daemon, void *) { int i = 1; while (daemon.should_run()) { wvout->print("Loop %s\n", i++); sleep(1); if (i == 17) daemon.die(); // Exit after 16 seconds } } int main(int argc, char **argv) { WvDaemon daemon("Sample Daemon", "0.1", WvDaemonCallback(), run, WvDaemonCallback()); return daemon.run(argc, argv); } @endcode !*/ class WvDaemon { static WvDaemon *singleton; public: //! The name and version of the daemon; used for -V and logging WvString name; WvString version; //! The path to the pid file to use for the daemon; defaults //! to /var/run/name.pid, where name is above WvString pid_file; //! Whether the daemon should daemonize by default (it can //! be changed by the default options); defaults to false bool daemonize; //! The arguments the daemon accepts; the defaults are described //! above. WvArgs args; //! The daemon's log mechanism WvLog log; WvLog::LogLevel log_level; bool syslog; public: //! See the class description WvDaemonCallback load_callback; WvDaemonCallback start_callback; WvDaemonCallback run_callback; WvDaemonCallback stop_callback; WvDaemonCallback unload_callback; protected: virtual void do_load(); virtual void do_start(); virtual void do_run(); virtual void do_stop(); virtual void do_unload(); private: volatile bool _want_to_die; volatile bool _want_to_restart; volatile int _exit_status; void init(WvStringParm _name, WvStringParm _version, WvDaemonCallback _start_callback, WvDaemonCallback _run_callback, WvDaemonCallback _stop_callback); int _run(const char *argv0); bool set_daemonize(void *); protected: bool dec_log_level(void *) { if ((int)log_level > (int)WvLog::Critical) log_level = (WvLog::LogLevel)((int)log_level - 1); return true; } bool inc_log_level(void *) { if ((int)log_level < (int)WvLog::Debug5) log_level = (WvLog::LogLevel)((int)log_level + 1); return true; } WvStringList _extra_args; public: //! Construct a new daemon; requires the name, version, //! and optional userdata to be passed to the callbacks WvDaemon(WvStringParm _name, WvStringParm _version, WvDaemonCallback _start_callback, WvDaemonCallback _run_callback, WvDaemonCallback _stop_callback): log(_name, WvLog::Debug) { init(_name, _version, _start_callback, _run_callback, _stop_callback); } virtual ~WvDaemon(); //! Run the daemon with no argument processing. Returns exit status. int run(const char *argv0); //! Run the daemon after doing argument processing. Returns exit status. int run(int argc, char **argv); //! Force the daemon to restart as soon as the run callback exits void restart() { _want_to_restart = true; } //! Force the daemon to exit as soon as the run callback exits void die(int status = 0) { _want_to_die = true; _exit_status = status; } //! Whether the daemon will restart when the run callback exits bool want_to_restart() const { return _want_to_restart; } //! Whether the daemon will quit when the run callback exits bool want_to_die() const { return _want_to_die; } //! Whether the daemon should continue runnning bool should_run() const { return !_want_to_die && !_want_to_restart; } //! Remaining args const WvStringList &extra_args() const { return _extra_args; } static WvDaemon *me() { return singleton; } public: const char *wstype() const { return "WvDaemon"; } }; #endif // __WVDAEMON_H wvstreams-4.6.1/include/unicallbackgen.h0000644000175000001440000000465611036722347017350 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that executes callbacks to generate the value of keys */ #ifndef __UNICALLBACKGEN_H #define __UNICALLBACKGEN_H #include #include "unitempgen.h" #include "wvstream.h" #include "wvtr1.h" typedef wv::function UniCallbackGenGetCallback; typedef wv::function UniCallbackGenSetCallback; /** * A UniConf generator that executes callbacks to generate the value of keys * * To make the callback fire and set the value of the key, * call set(key, whatever). Calling get(key) returns the most recent * generated value of the key. */ class UniCallbackGen: public UniTempGen { typedef std::map GetCallbackMap; GetCallbackMap get_callbacks; typedef std::map SetCallbackMap; SetCallbackMap set_callbacks; public: bool update_before_get; bool update_after_set; UniCallbackGen(): update_before_get(false), update_after_set(true) {} virtual ~UniCallbackGen() {} virtual void setgetcallback(const UniConfKey &key, UniCallbackGenGetCallback get_callback) { if (get_callback) get_callbacks[key] = get_callback; else get_callbacks.erase(key); } virtual void setsetcallback(const UniConfKey &key, UniCallbackGenSetCallback set_callback) { if (set_callback) set_callbacks[key] = set_callback; else set_callbacks.erase(key); } virtual void update(const UniConfKey &key, WvStringParm value = WvString::null) { GetCallbackMap::iterator it = get_callbacks.find(key); if (it != get_callbacks.end()) UniTempGen::set(key, it->second(key)); else UniTempGen::set(key, value); } /***** Overridden members *****/ virtual WvString get(const UniConfKey &key) { if (update_before_get) update(key); return UniTempGen::get(key); } virtual void set(const UniConfKey &key, WvStringParm value) { SetCallbackMap::iterator it = set_callbacks.find(key); if (it != set_callbacks.end()) it->second(key, value); if (update_after_set) update(key, value); } }; #endif // __UNICALLBACKGEN_H wvstreams-4.6.1/include/wvgzip.h0000644000175000001440000000505111036722347015722 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Gzip encoder/decoder based on zlib. */ #ifndef __WVGZIP_H #define __WVGZIP_H #include "wvencoder.h" #include "wvencoderstream.h" struct z_stream_s; /** * An encoder implementing Gzip encryption and decryption. * * When compressing: * * - On flush(), the encoded data stream is synchronized such that * all data compressed up to this point can be fully decompressed. * * - On finish(), the encoded data stream is finalized an a Gzip * end of data marker is emitted. * * * When decompressing: * * - The encoder will transition to isfinished() == true on its own * if a Gzip end of data marker is detected in the input. After * this point, no additional data can be decompressed. * * */ class WvGzipEncoder : public WvEncoder { public: enum Mode { Deflate, /*!< Compress using deflate */ Inflate /*!< Decompress using inflate */ }; /** * Creates a Gzip encoder. * * "mode" is the compression mode */ WvGzipEncoder(Mode mode, size_t _out_limit = 0); virtual ~WvGzipEncoder(); /** * Limit the amount of output produced in one call to encode(). * Defaults to 0, meaning no limit (empty the input buffer). */ size_t out_limit; /** * Continue decompression if errors are found. * If true, upon running into a decompression error, the encoder will * seek to the next unbroken block. Most useful if at least some blocks * are fully flushed (see 'full_flush' below). Defaults to false. * Note that it may be impossible to ignore really bad decompression * errors, in which case the encoder will go !isok(), as it would * if this boolean is false. */ bool ignore_decompression_errors; /** * Do full flushes. * Makes the encoder use Z_FULL_FLUSH instead of Z_SYNC_FLUSH, which * resets the compression state to improve chances of recovering * corrupted compressed data. Degrades compression, so don't use it too * often. Defaults to false. */ bool full_flush; protected: virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); virtual bool _finish(WvBuf &outbuf); virtual bool _reset(); private: struct z_stream_s *zstr; WvInPlaceBuf tmpbuf; Mode mode; size_t output; void init(); void close(); void prepare(WvBuf *inbuf); bool process(WvBuf &outbuf, bool flush, bool finish); }; #endif // __WVGZIP_H wvstreams-4.6.1/include/unicachegen.h0000644000175000001440000000254011036722347016645 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that caches keys/values in memory. */ #ifndef __UNICACHEGEN_H #define __UNICACHEGEN_H #include "unitempgen.h" #include "uniconftree.h" #include "wvlog.h" /** * A UniConf generator that adds a cache layer on top of another generator * * This cache implementation preloads the entire uniconf tree and then keeps up * to date by making changes whenever notifications are received. This means * that a read-only uniconfclient, when cached, will never actively contact * the uniconfdaemon. * * **WARNING** * The cache *will* go out of date if used with a uniconfclient/daemon without * running a select loop. */ class UniCacheGen : public UniTempGen { protected: WvLog log; IUniConfGen *inner; bool refreshed_once; //< we cache forever, so no need to re-refresh() void loadtree(const UniConfKey &key = ""); void deltacallback(const UniConfKey &key, WvStringParm value); public: UniCacheGen(IUniConfGen *_inner); virtual ~UniCacheGen(); /***** Overridden members *****/ virtual bool isok(); virtual bool refresh(); virtual void commit(); virtual void set(const UniConfKey &key, WvStringParm value); virtual WvString get(const UniConfKey &key); }; #endif // __UNICACHEGEN_H wvstreams-4.6.1/include/uniconfgen.h0000644000175000001440000002613711036722347016537 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * An abstract data container that backs a UniConf tree. */ #ifndef __UNICONFGEN_H #define __UNICONFGEN_H #include "uniconfpair.h" #include "wvcallbacklist.h" #include "wvtr1.h" class UniConfGen; class UniListIter; /** * The callback type for signalling key changes from a UniConfGen. * * Generators that wrap other generators should catch notifications * and reissue them using themselves as the "gen" parameter and their * userdata as the "userdata parameter". This can be done effectively by * invoking the delta() function on receipt of a notification from a * wrapped generator. See UniFilterGen. * * Parameters: gen, key, userdata * gen - the externally visible generator whose key has changed * key - the key that has changed */ typedef wv::function UniConfGenCallback; /** * An abstract data container that backs a UniConf tree. * * This is intended to be implemented to provide support for fetching * and storing keys and values using different access methods. */ class IUniConfGen : public IObject { public: virtual ~IUniConfGen(); /***** Notification API *****/ /** Adds a callback for change notification. */ virtual void add_callback(void *cookie, const UniConfGenCallback &callback) = 0; /** Removes a callback for change notification. */ virtual void del_callback(void *cookie) = 0; /***** Status API *****/ /** * Determines if the generator is usable and working properly. * The default implementation always returns true. */ virtual bool isok() = 0; /***** Key Persistence API *****/ /** Commits any changes. The default implementation does nothing. */ virtual void commit() = 0; /** * Refreshes information about a key recursively. * May discard uncommitted data. * * The default implementation always returns true. */ virtual bool refresh() = 0; /** * Flushes any commitment/notification buffers . * * The default implementation always returns true. * NOTE: This method should be 'protected' */ virtual void flush_buffers() = 0; /***** Key Retrieval API *****/ /** * Indicate that we will eventually be interested in doing get(), * haschildren(), or other "get-like" operations on a particular key * or tree of keys. The generator may be able to speed up these * operations by, say, caching them in advance. * * This function is not allowed to do blocking operations. It is allowed * to do nothing at all, however, and then get() might block later. */ virtual void prefetch(const UniConfKey &key, bool recursive) = 0; /** * Fetches a string value for a key from the registry. If the key doesn't * exist, the return value has .isnull() == true. */ virtual WvString get(const UniConfKey &key) = 0; /** * Without fetching its value, returns true if a key exists. * * This is provided because it is often more efficient to * test existance than to actually retrieve the value. * * The default implementation returns !get(key).isnull(). */ virtual bool exists(const UniConfKey &key) = 0; /** * Converts a string to an integer. If the string is null or not * recognized, return defvalue. * * This is here to support the common str2int(get(key)). * * The default implementation recognizes the booleans 'true', 'yes', 'on' * and 'enabled' as 1, and 'false', 'no', 'off' and 'disabled' as 0. */ virtual int str2int(WvStringParm s, int defvalue) const = 0; /***** Key Storage API *****/ /** * Stores a string value for a key into the registry. If the value is * WvString::null, the key is deleted. */ virtual void set(const UniConfKey &key, WvStringParm value) = 0; /** * Stores multiple key-value pairs into the registry. If the value is * WvString::null, the key is deleted. */ virtual void setv(const UniConfPairList &pairs) = 0; /***** Key Enumeration API *****/ /** * Returns true if a key has children. * * This is provided because it is often more efficient to * test existance than to actually retrieve the keys. * * The default implementation uses the iterator returned by iterator() * to test whether the child has any keys. * Subclasses are strongly encouraged to provide a better implementation. */ virtual bool haschildren(const UniConfKey &key) = 0; /** The abstract iterator type (see below) */ class Iter; /** A concrete null iterator type (see below) */ class NullIter; /** An iterator over a constant list of keys (see below) */ typedef ::UniListIter ListIter; /** * Returns an iterator over the children of the specified key. * May return NULL or an empty iterator if the key has no children. * * The caller takes ownership of the returned iterator and is responsible * for deleting it when finished. */ virtual Iter *iterator(const UniConfKey &key) = 0; /** * Like iterator(), but the returned iterator is recursive, that is, * it will return children of the immediate children, not just the * immediate children themselves. * * May return NULL if the key has no immediate children (since that means * there are also no indirect children). * * Note that UniConfGen::recursiveiterator() is a default * implementation that just calls iterator() recursively, so it'll work * in any derived class without you overriding this function. However, * you might want to do it anyway if it would be more efficient in your * particular case. */ virtual Iter *recursiveiterator(const UniConfKey &key) = 0; }; DEFINE_IID(IUniConfGen, {0x7ca76e98, 0xb694, 0x43ca, {0xb0, 0x56, 0x8b, 0x9d, 0xde, 0x9a, 0xbe, 0x9f}}); /** * A default implementation of IUniConfGen, providing various handy features * that save trouble when implementing typical generators. */ class UniConfGen : public IUniConfGen { IMPLEMENT_IOBJECT(UniConfGen); // These fields are deliberately hidden to encourage use of the // special notification members WvCallbackList cblist; int hold_nesting; UniConfPairList deltas; protected: /** Creates a UniConfGen object. */ UniConfGen(); public: /** Destroys the UniConfGen and may discard uncommitted data. */ virtual ~UniConfGen(); /***** Notification API *****/ /** * Adds a callback for change notification. * Must *not* be reimplemented by subclasses of UniConfGen. */ virtual void add_callback(void *cookie, const UniConfGenCallback &callback); virtual void del_callback(void *cookie); /** * Immediately sends notification that a key has possibly changed. * Takes care of the details of invoking the callback. * * Note: You probably want to be using delta() instead. */ void dispatch_delta(const UniConfKey &key, WvStringParm value); /** * Pauses notifications until matched with a call to unhold_delta(). * * While paused, notification events are placed into a pending list. * Redundant notifications may be discarded. * * Use this to safeguard non-reentrant code. */ void hold_delta(); /** * Resumes notifications when each hold_delta() has been matched. * * On resumption, dispatches all pending notifications except * those that were destined to watches that were removed. * * Use this to safeguard non-reentrant code. */ void unhold_delta(); /** * Clears the list of pending notifications without sending them. * Does not affect the hold nesting count. */ void clear_delta(); /** * Flushes the list of pending notifications by sending them. * Does not affect the hold nesting count. */ void flush_delta(); /** * Call this when a key's value or children have possibly changed. * * If the hold nesting count is 0, the notification is sent immediately. * Otherwise it is added to a pending list for later. */ void delta(const UniConfKey &key, WvStringParm value); /***** Status API *****/ virtual bool isok(); /***** Key Persistence API *****/ virtual void commit() { } virtual bool refresh() { return true; } virtual void prefetch(const UniConfKey &key, bool recursive) { } virtual WvString get(const UniConfKey &key) = 0; virtual bool exists(const UniConfKey &key); virtual int str2int(WvStringParm s, int defvalue) const; /***** Key Storage API *****/ virtual void set(const UniConfKey &key, WvStringParm value) = 0; virtual void setv(const UniConfPairList &pairs) = 0; virtual void flush_buffers() = 0; /***** Key Enumeration API *****/ virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key) = 0; // a helpful default that just calls iterator() recursively virtual Iter *recursiveiterator(const UniConfKey &key); protected: // A naive implementation of setv() that uses only set(). void setv_naive(const UniConfPairList &pairs); }; DeclareWvList(IUniConfGen); DeclareWvList2(UniConfGenList, IUniConfGen); /** * An abstract iterator over keys and values in a generator. * * Unlike other WvStreams iterators, this one declares virtual methods so * that UniConfGen implementations can supply the right behaviour * through a common interface that does not depend on static typing. * * The precise traversal sequence is defined by the iterator implementation. * * The iterator need not support concurrent modifications of the underlying * data structures. * * TODO: Consider changing this rule depending on observed usage patterns. */ class UniConfGen::Iter { public: /** Destroys the iterator. */ virtual ~Iter() { } /** * Rewinds the iterator. * Must be called prior to the first invocation of next(). */ virtual void rewind() = 0; /** * Seeks to the next element in the sequence. * Returns true if that element exists. * Must be called prior to the first invocation of key(). */ virtual bool next() = 0; /** Returns the current key. */ virtual UniConfKey key() const = 0; /** * Returns the value of the current key. You could just do a get(), * but maybe your generator has a more efficient way. */ virtual WvString value() const = 0; }; /** * An iterator that's always empty. * This is handy if you don't have anything good to iterate over. */ class UniConfGen::NullIter : public UniConfGen::Iter { public: /***** Overridden members *****/ virtual void rewind() { } virtual bool next() { return false; } virtual UniConfKey key() const { return UniConfKey::EMPTY; } virtual WvString value() const { return WvString(); } }; #endif // __UNICONFGEN_H wvstreams-4.6.1/include/wvhashtable.h0000644000175000001440000002040111036722347016700 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A hash table container. See also wvscatterhash.h, which is newer, faster, * and better. */ #ifndef __WVHASHTABLE_H #define __WVHASHTABLE_H #include "wvhash.h" #include "wvlinklist.h" #include "wvtypetraits.h" #include /** * A small, efficient, type-safe hash table (also known as dictionary) * container class. * * These are typically used to store a reasonably large number * of objects in no particular order and find them quickly when needed. * * Two semi-distinct types of hash tables are supported: tables and * dictionaries. * * TABLE EXAMPLE: * * DeclareWvTable(WvString); * int main() * { * WvString s("foo"), s2("blue"), s3("foo"); * WvStringTable t(10); // suggested size: 10 elements * t.add(&s); t.add(&s2); * printf("%s %s\n", t[s]->str, t[s3]->str); // prints "foo" "foo" * } * * * Here, the WvStrings "foo" and "blue" are stored in the table, and then * "foo" is looked up twice. Both table searches return &s. * The suggested table size of 10 elements places no upper bound on * the maximum number of elements, but optimizes the hash table for * holding roughly 10 elements. * * To match an element, the WvString operator== function is used. That * means this particular example is rather contrived since if you already * have the search string, you do not need to find it in the table. * Objects with more specific operator== might have more luck. * * DICTIONARY EXAMPLE: * * class IntStr * { * int *key; * WvString data; * } * DeclareWvDict(IntStr, int, key[0]); * IntStrDict d(100); * * * Here, we are creating a dictionary that stores strings indexed by * integers. d[5] might return the address of IntStr number 5, which * in turn contains WvString number 5. When matching elements in this case, * a comparison is only done on key[0] of the two elements; thus, it is * not the operator== of IntStr that is important, but rather the operator== * for int. (In this case, the operator== of int is predefined.) * * The only reason *key is declared as a pointer in this example is to * demonstrate how to use pointer-based keys with our syntax. In this case * it would certainly make more sense to use int key; and * DeclareWvDict(IntStr, key). Note though, that int *key; and * DeclareWvDict(IntStr, key) is almost certainly not what you want, since * it would compare the POINTERS, not their values. * * The interface of this class resembles that of WvList by design. * In particular, we support iterators in a similar way. * * @see WvList */ /** * The untyped base class of WvHashTable. * * Putting common code in here allows us to prevent it from being * replicated by each template instantiation of WvHashTable. * */ class WvHashTableBase { // Copy constructor - not defined anywhere! WvHashTableBase(const WvHashTableBase &t); protected: WvHashTableBase(unsigned _numslots); virtual ~WvHashTableBase() {}; WvHashTableBase& operator= (const WvHashTableBase &t); void setup() { /* default: do nothing */ } void shutdown() { /* default: do nothing */ } WvLink *prevlink(WvListBase *slots, const void *data, unsigned hash) const; void *genfind(WvListBase *slots, const void *data, unsigned hash) const; virtual bool compare(const void *key, const void *elem) const = 0; public: unsigned numslots; WvListBase *wvslots; /** * Returns the number of elements in the hash table. * Returns: the number of elements */ size_t count() const; /** * Returns true if the hash table is empty. * Returns: true if empty */ bool isempty() const; // base class for the auto-declared hash table iterators class IterBase { public: WvHashTableBase *tbl; unsigned tblindex; WvLink *link; IterBase(WvHashTableBase &_tbl) : tbl(& _tbl) { } IterBase(const IterBase &other) : tbl(other.tbl), tblindex(other.tblindex), link(other.link) { } void rewind() { tblindex = 0; link = &tbl->wvslots[0].head; } WvLink *next(); WvLink *cur() const { return link; } void *vptr() const { return link->data; } /** * Returns the state of autofree for the current element. */ bool get_autofree() const { return link->get_autofree(); } /** * Sets the state of autofree for the current element. */ void set_autofree(bool autofree) { link->set_autofree(autofree); } }; }; template < class T, // element type class K, // key type class Accessor, // element to key template class Comparator = OpEqComp // comparison func > class WvHashTable : public WvHashTableBase { // copy constructor: not defined anywhere! WvHashTable(const WvHashTable &h); protected: typedef Comparator MyComparator; unsigned hash(const T *data) { return WvHash(*Accessor::get_key(data)); } virtual bool compare(const void *key, const void *elem) const { return MyComparator::compare((const K *)key, Accessor::get_key((const T *)elem)); } public: /** * Creates a hash table. * * "numslots" is the suggested number of slots */ WvHashTable(unsigned _numslots) : WvHashTableBase(_numslots) { wvslots = new WvList[numslots]; setup(); } WvList *sl() { return (WvList *)wvslots; } virtual ~WvHashTable() { shutdown(); deletev sl(); } void add(T *data, bool autofree) { sl()[hash(data) % numslots].append(data, autofree); } WvLink *getlink(const K &key) { return prevlink(wvslots, &key, WvHash(key))->next; } T *operator[] (const K &key) const { return (T *)genfind(wvslots, &key, WvHash(key)); } /** * Returns the state of autofree for the element associated with key. */ bool get_autofree(const K &key) const { WvLink *l = getlink(key); if (l) return l->get_autofree(); return false; } bool get_autofree(const T *data) const { return get_autofree(hash(data)); } /** * Sets the state of autofree for the element associated with key. */ void set_autofree(const K &key, bool autofree) { WvLink *l = getlink(key); if (l) l->set_autofree(autofree); } void set_autofree(const T *data, bool autofree) { set_autofree(hash(data), autofree); } void remove(const T *data) { unsigned h = hash(data); WvLink *l = prevlink(wvslots, Accessor::get_key(data), h); if (l && l->next) sl()[h % numslots].unlink_after(l); } void zap() { deletev sl(); wvslots = new WvList[numslots]; } class Iter : public WvHashTableBase::IterBase { public: Iter(WvHashTable &_tbl) : IterBase(_tbl) { } Iter(const Iter &other) : IterBase(other) { } T *ptr() const { return (T *)link->data; } WvIterStuff(T); }; typedef class WvSorter Sorter; }; // ****************************************** // WvDict and WvTable #define DeclareWvDict2(_classname_, _type_, _ftype_, _field_) \ __WvDict_base(_classname_, _type_, _ftype_, &obj->_field_) #define DeclareWvDict(_type_, _ftype_, _field_) \ DeclareWvDict2(_type_##Dict, _type_, _ftype_, _field_) #define DeclareWvTable2(_classname_, _type_) \ __WvDict_base(_classname_, _type_, _type_, obj) #define DeclareWvTable(_type_) \ DeclareWvTable2(_type_##Table, _type_) #define __WvDict_base(_classname_, _type_, _ftype_, _field_) \ template \ struct _classname_##Accessor \ { \ static const K *get_key(const T *obj) \ { return _field_; } \ }; \ \ typedef WvHashTable<_type_, _ftype_, \ _classname_##Accessor<_type_, _ftype_> > _classname_ #endif // __WVHASHTABLE_H wvstreams-4.6.1/include/wvfork.h0000644000175000001440000000277011036722347015717 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ /** \file * Provides support for forking processes. */ #ifndef __WVFORK_H #define __WVFORK_H #ifndef _WIN32 #include #else typedef int pid_t; #endif #include "wvscatterhash.h" #include "wvtr1.h" DeclareWvScatterTable(int); typedef wv::function WvForkCallback; /** * Register a callback to be called during wvfork. * It will be called (in both parent and child process) after the fork has * happened but before wvfork returns. It is passed the return value of the * fork. * * NOTE: There is no way to undo this operation! */ extern void add_wvfork_callback(WvForkCallback cb); /** * wvfork_start is just like fork, except that it will block the * parent until the child process closes the waitfd, to avoid race * conditions. * * For example, wvfork uses it, closing the waitfd only when it is * done closing the close-on-exec file descriptors. */ extern pid_t wvfork_start(int *waitfd); /** * wvfork() just runs fork(), but it closes all file descriptors that * are flagged close-on-exec, since we don't necessarily always run * exec() after we fork()... * * This fixes the year-old mystery bug where WvTapeBackup caused * watchdog reboots because the CHILD process wasn't touching it, and * it was already open before the fork()... */ extern pid_t wvfork(int dontclose1 = -1, int dontclose2 = -1); extern pid_t wvfork(intTable &dontclose ); #endif wvstreams-4.6.1/include/wvhttppool.h0000644000175000001440000001544611036722347016633 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A fast, easy-to-use, parallelizing, pipelining HTTP/1.1 file retriever. * * Just create a WvHttpPool object, add it to your list, and use pool.addurl() * to get a WvStream* that gives you the file you requested. */ #ifndef __WVHTTPPOOL_H #define __WVHTTPPOOL_H #include "ftpparse.h" #include "wvurl.h" #include "wvistreamlist.h" #include "wvstreamclone.h" #include "wvlog.h" #include "wvhashtable.h" #include "wvbufstream.h" #include "wvbuf.h" #include "wvcont.h" #include "wvtcp.h" class WvBufUrlStream; class WvUrlStream; class WvHttpStream; static const WvString DEFAULT_ANON_PW("weasels@"); struct WvHTTPHeader { WvString name, value; WvHTTPHeader(WvStringParm _name, WvStringParm _value) : name(_name), value(_value) {} }; DeclareWvDict(WvHTTPHeader, WvString, name); class WvUrlRequest { public: WvUrl url; WvString headers; WvUrlStream *instream; WvBufUrlStream *outstream; WvStream *putstream; bool pipeline_test; bool inuse; bool is_dir; bool create_dirs; WvString method; WvUrlRequest(WvStringParm _url, WvStringParm _method, WvStringParm _headers, WvStream *content_source, bool _create_dirs, bool _pipeline_test); ~WvUrlRequest(); void done(); }; DeclareWvList(WvUrlRequest); struct WvUrlLink { WvString linkname; WvUrl url; WvUrlLink(WvStringParm _linkname, WvStringParm _url) : linkname(_linkname), url(_url) {} }; DeclareWvList(WvUrlLink); class WvBufUrlStream : public WvBufStream { public: WvString url; WvString proto; WvUrlLinkList links; // HTML links or FTP directory listing // HTTP stuff... WvString version; int status; WvHTTPHeaderDict headers; WvBufUrlStream() : status(0), headers(10) {} virtual ~WvBufUrlStream() {} public: const char *wstype() const { return "WvBufUrlStream"; } }; DeclareWvTable(WvIPPortAddr); class WvUrlStream : public WvStreamClone { public: class Target { public: WvIPPortAddr remaddr; WvString username; Target(const WvIPPortAddr &_remaddr, WvStringParm _username) : remaddr(_remaddr), username(_username) {} ~Target() {} bool operator== (const Target &n2) const { return (username == n2.username && remaddr == n2.remaddr); } }; Target target; static int max_requests; protected: WvLog log; WvUrlRequestList urls, waiting_urls; int request_count; WvUrlRequest *curl; // current url virtual void doneurl() = 0; virtual void request_next() = 0; public: WvUrlStream(const WvIPPortAddr &_remaddr, WvStringParm _username, WvStringParm logname) : WvStreamClone(new WvTCPConn(_remaddr)), target(_remaddr, _username), log(logname, WvLog::Debug) { request_count = 0; curl = NULL; } virtual ~WvUrlStream() {}; virtual void close() = 0; void addurl(WvUrlRequest *url); void delurl(WvUrlRequest *url); // only implemented in WvHttpStream virtual size_t remaining() { return 0; } virtual void execute() = 0; public: const char *wstype() const { return "WvUrlStream"; } }; unsigned WvHash(const WvUrlStream::Target &n); DeclareWvDict(WvUrlStream, WvUrlStream::Target, target); class WvHttpStream : public WvUrlStream { public: static bool global_enable_pipelining; bool enable_pipelining; private: int pipeline_test_count; bool ssl; bool sent_url_request; // Have we sent a request to the server yet? WvIPPortAddrTable &pipeline_incompatible; WvString http_response, pipeline_test_response; WvDynBuf putstream_data; enum { Unknown, Chunked, ContentLength, Infinity, PostHeadInfinity, PostHeadChunked, PostHeadStream, ChuckInfinity, ChuckChunked, ChuckStream } encoding; size_t bytes_remaining; bool in_chunk_trailer, last_was_pipeline_test, in_doneurl; virtual void doneurl(); virtual void request_next(); void start_pipeline_test(WvUrl *url); WvString request_str(WvUrlRequest *url, bool keep_alive); void send_request(WvUrlRequest *url); void pipelining_is_broken(int why); public: WvHttpStream(const WvIPPortAddr &_remaddr, WvStringParm _username, bool ssl, WvIPPortAddrTable &_pipeline_incompatible); virtual ~WvHttpStream(); virtual void close(); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void execute(); virtual size_t remaining() { return bytes_remaining; } public: const char *wstype() const { return "WvHttpStream"; } }; class WvFtpStream : public WvUrlStream { bool logged_in, pasv_acked; WvString password; WvTCPConn *data; time_t last_request_time; bool sure; virtual void doneurl(); virtual void request_next(); // Disregard all lines that are of the form "xxx-", meaning that another // line follows. Only the last line is important for us. char *get_important_line(); // Parse response to "PASV" command and returns a pointer to the address // of the data port (or NULL if it can't parse the response).. // This mucks about with line. WvIPPortAddr *parse_pasv_response(char *line); WvString parse_for_links(char *line); WvCont cont; void* real_execute(void*); public: WvFtpStream(const WvIPPortAddr &_remaddr, WvStringParm _username, WvStringParm _password); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void close(); virtual void execute(); public: const char *wstype() const { return "WvFtpStream"; } }; // FIXME: Rename this to WvUrlPool someday. class WvHttpPool : public WvIStreamList { WvLog log; WvResolver dns; WvUrlStreamDict conns; WvUrlRequestList urls; int num_streams_created; bool sure; WvIPPortAddrTable pipeline_incompatible; public: WvHttpPool(); virtual ~WvHttpPool(); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void execute(); WvBufUrlStream *addurl(WvStringParm _url, WvStringParm _method = "GET", WvStringParm _headers = "", WvStream *content_source = NULL, bool create_dirs = false); // For URL uploads. create_dirs should be true if you want all // non-existent directories in _url to be created. // WvBufUrlStream *addputurl(WvStringParm _url, WvStringParm _headers, // WvStream *s, bool create_dirs = false); private: void unconnect(WvUrlStream *s); public: bool idle() const { return !urls.count(); } public: const char *wstype() const { return "WvHttpPool"; } }; #endif // __WVHTTPPOOL_H wvstreams-4.6.1/include/unibachelorgen.h0000644000175000001440000000106011036722347017355 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * A UniConf generator that refuses to commit() or refresh(). This is * useful in blocking propogation of these messages upstream. */ #ifndef _UNIBACHELORGEN_H #define _UNIBACHELORGEN_H #include "unifiltergen.h" class UniBachelorGen : public UniFilterGen { public: UniBachelorGen(IUniConfGen *inner); UniBachelorGen(WvStringParm moniker); virtual void commit(); virtual bool refresh(); }; #endif /* _UNIBACHELORGEN_H */ wvstreams-4.6.1/include/wvocsp.h0000644000175000001440000000274011100156566015713 0ustar wlachusers/* -*- Mode: C++ -*- * * OCSP request and response abstractions. * * OCSP provides a quick way of checking whether a certificate is valid or * not. For more information, see: http://en.wikipedia.org/wiki/OCSP * * For the sake of both ease of implementation and use, these classes only * expose a simplified subset of OCSP functionality. * - A nonce (unique identifier for the request) is always sent in the * request. * - Both the request and response objects assume only one certificate is to * be validated. * */ #ifndef __WVOCSP_H #define __WVOCSP_H #include "wvx509.h" #include class WvOCSPReq { public: WvOCSPReq(const WvX509 &cert, const WvX509 &issuer); virtual ~WvOCSPReq(); void encode(WvBuf &buf); private: WvOCSPReq(WvOCSPReq &); // not implemented yet friend class WvOCSPResp; OCSP_CERTID *id; OCSP_REQUEST *req; }; class WvOCSPResp { public: WvOCSPResp(); virtual ~WvOCSPResp(); void decode(WvBuf &buf); bool isok() const; bool check_nonce(const WvOCSPReq &req) const; bool signedbycert(const WvX509 &cert) const; WvX509 get_signing_cert() const; enum Status { Error, Good, Revoked, Unknown }; Status get_status(const WvX509 &cert, const WvX509 &issuer) const; static WvString status_str(Status status); private: WvOCSPResp(WvOCSPResp &); // not implemented yet OCSP_RESPONSE *resp; OCSP_BASICRESP * bs; mutable WvLog log; }; #endif // __WVOCSP_H wvstreams-4.6.1/include/wvsubprocqueuestream.h0000644000175000001440000000133611036722347020711 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #ifndef __WVSUBPROCQUEUESTREAM_H #define __WVSUBPROCQUEUESTREAM_H #include "wvsubprocqueue.h" #include "wvlog.h" /** * A variant of WvSubProcQueue that can be added to a WvStreamList so that * WvSubProcQueue::go() gets called automatically at a reasonable interval. */ class WvSubProcQueueStream : public WvStream, public WvSubProcQueue { public: WvSubProcQueueStream(int _maxrunning); virtual ~WvSubProcQueueStream(); virtual void execute(); private: WvLog log; public: const char *wstype() const { return "WvSubProcQueueStream"; } }; #endif // __WVSUBPROCQUEUESTREAM_H wvstreams-4.6.1/include/wvipaddrtable.h0000644000175000001440000000065711036722347017233 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPAddrs are used a lot more often than WvIPAddrTables, so the Table need * not be defined most of the time. Include this file if you need it. * */ #ifndef __WVIPADDRTABLE_H #define __WVIPADDRTABLE_H #include "wvaddr.h" #include "wvhashtable.h" DeclareWvTable(WvIPAddr); #endif // __WVIPADDRTABLE_H wvstreams-4.6.1/include/wvsubproc.h0000644000175000001440000000533411036722347016432 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for reliably starting/stopping subprocesses. * * We want to avoid calling system(), since it uses the shell (and * thus has strange parsing weirdness, environment variable changes, * and so on). Plus calling the shell when we need to is just slow. * * On the other hand, we want handy features like the ability to wait * for our child process to die, and the ability to kill it if it * doesn't (without having to use "killall"). * * By using setsid(), we also deal with strange situations like * scripts which launch other programs. stop() and kill() will kill * them all. (If you don't want that, use stop_primary() and * kill_primary().) */ #ifndef __WVSUBPROC_H #define __WVSUBPROC_H #include "wvstringlist.h" #include #include #include class WvSubProc { public: DeclareWvList(pid_t); pid_tList old_pids; pid_t pid; bool running; int estatus; WvString pidfile, last_cmd, app; WvStringList last_args, env; WvSubProc() { init(); } WvSubProc(const char cmd[], const char * const *argv) { init(); startv(cmd, argv); } virtual ~WvSubProc(); private: void init(); int _startv(const char cmd[], const char * const *argv); int memlimit; public: void prepare(const char cmd[], ...); void preparev(const char cmd[], va_list ap); void preparev(const char cmd[], const char * const *argv); void preparev(const char cmd[], WvStringList &); // launch a subprocess, which will be owned by this object. int start(const char cmd[], ...); int startv(const char cmd[], const char * const *argv); virtual int start_again(); virtual int fork(int *waitfd); // stop (kill -TERM or -KILL as necessary) the subprocess and // all its children. virtual void stop(time_t msec_delay, bool kill_children = true); // wait for the subprocess (and all its children) to die. virtual void wait(time_t msec_delay, bool wait_children = true); // figure out the pid from the /var/run pidfile pid_t pidfile_pid(); /// Sets a limit on the number of megabytes of memory the subprocess will // use void setMemLimit(int megs) { memlimit = megs; } // send a signal to the subprocess and all its children. void kill(int sig); // send a signal only to the main subprocess. void kill_primary(int sig); // suspend the process temporarily, or resume it. virtual void suspend() { kill(SIGSTOP); } virtual void resume() { kill(SIGCONT); } }; DeclareWvList(WvSubProc); #endif // __WVSUBPROC_H wvstreams-4.6.1/include/wvlogbuffer.h0000644000175000001440000000360211036722347016724 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVLOGBUFFER_H #define __WVLOGBUFFER_H #include "wvlogrcv.h" #include "wvhashtable.h" /** * WvLogBuffer is a descendant of WvLogRcv that buffers log messages for * later use. It only keeps up to max_lines log entries for every * source/debug level, s.t. debug level <= max_level */ class WvLogBuffer : public WvLogRcv { public: // An actual message class Msg { public: time_t timestamp; WvLog::LogLevel level; WvString source, message; Msg(WvLog::LogLevel _level, WvStringParm _source, WvString _message); }; DeclareWvList(Msg); /* * Maps a string describing msg type of the form "source:level" * to a list of pointers to all messages of this type */ class MsgCounter { public: MsgCounter(WvString _src_lvl) : src_lvl(_src_lvl) {}; Msg* add(Msg* msg, int max); WvString src_lvl; private: MsgList list; }; DeclareWvDict(MsgCounter, WvString, src_lvl); protected: /* * "Owns" all the msges */ MsgList msgs; /* * Used for keeping track of how many messages from a given source/level * there are. Just stores the pointers. */ MsgCounterDict counters; WvDynBuf current; int max_lines; void handle_msg(Msg *lastmsg); virtual void _begin_line() {}; virtual void _mid_line(const char *str, size_t len); virtual void _end_line(); public: WvLogBuffer(int _max_lines, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvLogBuffer(); MsgList &messages() { end_line(); return msgs; } void feed_receiver(WvLogRcv& receiver); void dump(WvStream &s); }; #endif // __WVLOGBUFFER_H wvstreams-4.6.1/include/unisubtreegen.h0000644000175000001440000000144211036722347017253 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A UniConfGen for returning only a particular subtree of a given generator. */ #ifndef __UNISUBTREEGEN_H #define __UNISUBTREEGEN_H #include "unifiltergen.h" /** * A UniConfGen that returns only a particular subtree of a given generator. * * Requests going to this generator have the given prefix added to all keys. */ class UniSubtreeGen : public UniFilterGen { UniConfKey subkey; public: UniSubtreeGen(IUniConfGen *gen, const UniConfKey &_subkey); virtual bool keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key); virtual bool reversekeymap(const UniConfKey &mapped_key, UniConfKey &unmapped_key); }; #endif // __UNISUBTREEGEN_H wvstreams-4.6.1/include/wvtest.h0000644000175000001440000000516311036722347015734 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * Part of an automated testing framework. You can declare a "test function" * using WVTEST_MAIN, and call WVPASS and WVFAIL from there. These produce * formatted data on stdout that can be read by external testrunner scripts. * * More than one WVTEST_MAIN is allowed in a single program, and they all * get run. */ #ifndef __WVTEST_H #define __WVTEST_H #include class WvTest { typedef void MainFunc(); const char *descr, *idstr; MainFunc *main; int slowness; WvTest *next; static WvTest *first, *last; static int fails, runs; static time_t start_time; static bool run_twice; static void alarm_handler(int sig); static void print_result(bool start, const char *file, int line, const char *condstr, bool result); public: WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slow); static int run_all(const char * const *prefixes = NULL); static void start(const char *file, int line, const char *condstr); static void check(bool cond); static inline bool start_check(const char *file, int line, const char *condstr, bool cond) { start(file, line, condstr); check(cond); return cond; } static bool start_check_eq(const char *file, int line, const char *a, const char *b, bool expect_pass); static bool start_check_eq(const char *file, int line, int a, int b, bool expect_pass); static bool start_check_lt(const char *file, int line, const char *a, const char *b); static bool start_check_lt(const char *file, int line, int a, int b); }; #define WVPASS(cond) \ WvTest::start_check(__FILE__, __LINE__, #cond, (cond)) #define WVPASSEQ(a, b) \ WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), true) #define WVPASSLT(a, b) \ WvTest::start_check_lt(__FILE__, __LINE__, (a), (b)) #define WVFAIL(cond) \ WvTest::start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond)) #define WVFAILEQ(a, b) \ WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), false) #define WVTEST_MAIN3(descr, ff, ll, slowness) \ static void _wvtest_main_##ll(); \ static WvTest _wvtest_##ll(descr, ff, _wvtest_main_##ll, slowness); \ static void _wvtest_main_##ll() #define WVTEST_MAIN2(descr, ff, ll, slowness) \ WVTEST_MAIN3(descr, ff, ll, slowness) #define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0) #define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1) #endif // __WVTEST_H wvstreams-4.6.1/include/wvmodem.h0000644000175000001440000000532611036722347016057 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Copyright (C) 1999 Red Hat, Inc. * * Definition of the WvModemBase and WvModem classes. Inherit from WvFile, * but do various important details related to modems, like setting baud * rates and dropping DTR and the like. * */ #ifndef __WVMODEM_H #define __WVMODEM_H #include "wvlockdev.h" #include "wvfile.h" #include "wvlog.h" #include #ifndef IUCLC #define IUCLC 0 #endif #ifndef OLCUC #define OLCUC 0 #endif #ifndef XCASE #define XCASE 0 #endif /** * WvModemBase provides the methods used to control a modem, but * without real implementation for most of them, so that they can * be used in contexts where modem control is undesirable without * reimplementing calling code for such uses. */ class WvModemBase : public WvFile { protected: struct termios t; int baud; WvModemBase() { } int get_real_speed(); public: bool die_fast; WvModemBase(int _fd); virtual ~WvModemBase(); /** do-nothing method that is not needed in WvModemBase */ virtual void close(); /** do-nothing method that is not needed in WvModemBase */ virtual bool carrier(); /** do-nothing method that is not needed in WvModemBase */ virtual int speed(int _baud); /** this one really is needed */ int getspeed() { return baud; } /** may need to hangup for redial reasons */ virtual void hangup(); public: const char *wstype() const { return "WvModemBase"; } }; /** * WvModem implements a named modem that really needs to be opened, * closed, and manipulated in lots of ways */ class WvModem : public WvModemBase { private: WvLockDev lock; WvLog log; bool have_old_t; struct termios old_t; bool closing; bool no_reset; /** * Setup all of the terminal characteristics, and leave the modem in CLOCAL * mode to make sure that we can communicate easily with the modem later. */ void setup_modem(bool rtscts); /** Check the status of the modem */ int getstatus(); public: WvModem(WvStringParm filename, int _baud, bool rtscts = true, bool _no_reset = false); virtual ~WvModem(); /** Close the connection to the modem */ virtual void close(); /** Is there a carrier present? */ virtual bool carrier(); /** * _baud is the desired speed, that you wish the modem to communicate with, * and this method returns the actual speed that the modem managed to achieve. */ virtual int speed(int _baud); public: const char *wstype() const { return "WvModem"; } }; #endif wvstreams-4.6.1/include/wvpam.h0000644000175000001440000000400411036722347015523 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * A WvStream that authenticates with PAM. If WvStreams is compiled without * PAM, it just fails. Note that if you don't check isok, you can still read * and write to the stream - in particular, anything written in the * constructor will go through before authentication begins. * * For now, this only works for PAM modules that don't require any user * interaction (not even a password!), such as ssoya. */ #ifndef __WVPAM_H #define __WVPAM_H #include "wvstringlist.h" #include "wvlog.h" class WvPamData; class WvPam { private: bool init(); WvPamData *d; WvLog log; WvString appname; /** * Log the result of the last PAM step, based on the pam_status flag,and * write a failure message to the cloned stream on error. step is the * name to use in the log message. Returns true if the last step * succeeded, false if it failed. */ bool check_pam_status(WvStringParm step); public: /** * Start up PAM (presumably you will want to call authenticate() * later. */ WvPam(WvStringParm svcname); /** * Start up PAM, and authenticate user from rhost with password */ WvPam(WvStringParm svcname, WvStringParm rhost, WvStringParm user = WvString::null, WvStringParm password = WvString::null); virtual ~WvPam(); /** * Authenticate the user from rhost with password. */ bool authenticate(WvStringParm rhost = WvString::null, WvStringParm user = WvString::null, WvStringParm password = WvString::null); /** * Get the groups that the currently sessioned user is logged * in with */ void getgroups(WvStringList &groups) const; /** * Get the user's name */ WvString getuser() const; /** * Check here to see if the user is validated or not */ WvError err; }; #endif // __WVPAM_H wvstreams-4.6.1/include/wvstringlist.h0000644000175000001440000000526011036722347017155 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStrings are used a lot more often than WvStringLists, so the List need * not be defined most of the time. Include this file if you need it. * */ #ifndef __WVSTRINGLIST_H #define __WVSTRINGLIST_H #include "wvstring.h" #include "wvlinklist.h" class WvRegex; DeclareWvList2(WvStringListBase, WvString); /** * This is a WvList of WvStrings, and is a really handy way to parse * strings. If you ever find yourself using strtok(3) or strpbrk(3), * or find yourself needing to parse a line of input, WvStringList, * WvStringList::split(), and WvStringList::popstr() are probably what you * want, and avoid all sorts of nasty security bugs caused by doing it any * other way. */ class WvStringList : public WvStringListBase { // copy constructor: not defined anywhere! WvStringList(const WvStringList &l); public: /** * Instatiate a new WvStringList() */ WvStringList() {} /** * concatenates all elements of the list seperating on joinchars */ WvString join(const char *joinchars = " ") const; /** * split s and form a list ignoring splitchars (except at beginning and end) * ie. " happy birthday to you" split on " " will populate the list with * "" * "happy" * "birthday" * "to" * "you" */ void split(WvStringParm s, const char *splitchars = " \t\r\n", int limit = 0); /** * split s and form a list creating null entries when there are multiple * splitchars * ie " happy birthday to you" split on " " will populate the list with * "" * "happy" * "birthday" * "" * "to" * "" * "you" * */ void splitstrict(WvStringParm s, const char *splitchars = " \t\r\n", int limit = 0); #ifndef _WIN32 /** * split s and form a list ignoring regex (except at beginning and end) * Note that there is no splitstrict for regexes, since the differece is * taken care of through the regex (...)+ syntax */ void split(WvStringParm s, const WvRegex ®ex, int limit = 0); #endif /* * populate the list from an array of strings */ void fill(const char * const *array); void append(WvStringParm str); void append(WVSTRING_FORMAT_DECL) { append(WvString(WVSTRING_FORMAT_CALL)); } void append(WvString *strp, bool autofree, char *id = NULL); /** * get the first string in the list, or an empty string if the list is empty. * Removes the returned string from the list. */ WvString popstr(); }; #endif // __WVSTRINGLIST_H wvstreams-4.6.1/include/wvlockdev.h0000644000175000001440000000130511036722347016376 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Some handy functions to create/remove /var/lock lockfiles. */ #ifndef __WVLOCKDEV_H #define __WVLOCKDEV_H #include "wvstring.h" /** * Class to handle Lock files - useful for WvDial and other places where we * need to guarantee exclusive access to a file or device. Creates/Removes * lockfiles in /var/lock. */ class WvLockDev { WvString devicename, filename; int lock_count; public: WvLockDev(WvString _devicename); ~WvLockDev(); bool lock(); void unlock(); bool islocked() const { return lock_count != 0; } }; #endif // __WVLOCKDEV_H wvstreams-4.6.1/include/wvipfirewall.h0000644000175000001440000001072411036722347017112 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPFirewall is an extremely simple hackish class that handles the Linux * 2.4 "iptables" firewall. It's okay to create more than one instance * of this class; they'll co-operate. * * They need you to have created the appropriate firewall tables already, * however, and call them from the right places in the Input and/or Forward * firewalls. */ #ifndef __WVIPFIREWALL_H #define __WVIPFIREWALL_H #include "wvinterface.h" #include "wvstringlist.h" #include "wvaddr.h" DeclareWvList(WvIPPortAddr); class IWvIPFirewall { public: virtual ~IWvIPFirewall() { } virtual void zap() = 0; virtual void add_port(const WvIPPortAddr &addr) = 0; virtual void add_redir(const WvIPPortAddr &src, int dstport) = 0; virtual void add_redir_all(int dstport) = 0; virtual void add_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport) = 0; virtual void add_proto(WvStringParm proto) = 0; virtual void add_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat) = 0; virtual void del_port(const WvIPPortAddr &addr) = 0; virtual void del_redir(const WvIPPortAddr &src, int dstport) = 0; virtual void del_redir_all(int dstport) = 0; virtual void del_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport) = 0; virtual void del_proto(WvStringParm proto) = 0; virtual void del_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat) = 0; }; /** Class to handle Linux 2.4 IPTables */ class WvIPFirewall : public IWvIPFirewall { class FFwd { public: WvIPPortAddr src; WvIPPortAddr dst; bool snat; FFwd(const WvIPPortAddr &_src, const WvIPPortAddr &_dst, bool _snat) : src(_src), dst(_dst) { snat = _snat; } }; class Redir { public: WvIPPortAddr src; int dstport; Redir(const WvIPPortAddr &_src, int _dstport) : src(_src) { dstport = _dstport; } }; class RedirAll { public: int dstport; RedirAll(int _dstport) { dstport = _dstport; } }; class RedirPortRange { public: WvIPPortAddr src_min; WvIPPortAddr src_max; int dstport; RedirPortRange(const WvIPPortAddr &_src_min, const WvIPPortAddr &_src_max, int _dstport) : src_min(_src_min), src_max(_src_max) { dstport = _dstport; } }; DeclareWvList(FFwd); DeclareWvList(Redir); DeclareWvList(RedirAll); DeclareWvList(RedirPortRange); FFwdList ffwds; RedirList redirs; RedirAllList redir_alls; RedirPortRangeList redir_port_ranges; WvIPPortAddrList addrs; WvStringList protos; WvString port_command(const char *cmd, const char *proto, const WvIPPortAddr &addr); WvString redir_command(const char *cmd, const WvIPPortAddr &src, int dstport); WvString redir_port_range_command(const char *cmd, const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport); WvString redir_all_command(const char *cmd, int dstport); WvString proto_command(const char *cmd, const char *proto); WvString forward_command(const char *cmd, const char *proto, const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat); WvLog log; const char *shutup() const { return ignore_errors ? " >/dev/null 2>/dev/null " : ""; } public: WvIPFirewall(); virtual ~WvIPFirewall(); static bool enable, ignore_errors; virtual void zap(); virtual void add_port(const WvIPPortAddr &addr); virtual void add_redir(const WvIPPortAddr &src, int dstport); virtual void add_redir_all(int dstport); virtual void add_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport); virtual void add_proto(WvStringParm proto); virtual void add_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat); virtual void del_proto(WvStringParm proto); virtual void del_port(const WvIPPortAddr &addr); virtual void del_redir(const WvIPPortAddr &src, int dstport); virtual void del_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat); virtual void del_redir_all(int dstport); virtual void del_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport); }; #endif // __WVIPFIREWALL_H wvstreams-4.6.1/include/wvattrs.h0000644000175000001440000000060711044160724016102 0ustar wlachusers#ifndef __WVATTRS_H #define __WVATTRS_H #include "wvstring.h" class WvAttrs { char *attrlist; unsigned int attrlen; char *_get(WvStringParm name) const; public: WvAttrs(); WvAttrs(const WvAttrs ©); virtual ~WvAttrs(); void set(WvStringParm name, WvStringParm value); inline WvString get(WvStringParm name) const { return _get(name); } }; #endif wvstreams-4.6.1/include/uniconfpamconn.h0000644000175000001440000000076711036722347017422 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a UniConf daemon session which is authenticated through PAM. */ #ifndef __UNICONFPAMCONN_H #define __UNICONFPAMCONN_H #include "uniconfroot.h" #include "wvstreamclone.h" class UniPermGen; class UniConfPamConn : public WvStreamClone { public: UniConfPamConn(WvStream *s, const UniConf &root, UniPermGen *perms); protected: UniConfRoot newroot; }; #endif // __UNICONFPAMCONN_H wvstreams-4.6.1/include/wvencoder.h0000644000175000001440000005556011036722347016402 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A top-level data encoder class and a few useful encoders. */ #ifndef __WVENCODER_H #define __WVENCODER_H #include "wvbuf.h" #include "wvlinklist.h" #include "wvstring.h" /** * The base encoder class. * * Encoders read data from an input buffer, transform it in some * way, then write the results to an output buffer. The resulting * data may be of a different size or data type, and may or may * not depend on previous data. * * Encoders may or may not possess the following characteristics: * * - Statefulness: encoding of successive input elements may * depend on previous one * - Error states: encoding may enter an error state indicated * by isok() == false due to problems detected * in the input, or by the manner in which the encoder has * been user * - Minimum input block size: data will not be drawn from the * input buffer until enough is available or the encoder * is flushed * - Minimum output block size: data will not be written to the * output buffer until enough free space is available * - Synchronization boundaries: data is process or generated * in chunks which can be manipulated independently of any * others, in which case flush() may cause the encoder to * produce such a boundary in its output * - Recognition of end-of-data mark: a special sequence marks * the end of input, after which the encoder transitions to * isfinished() == true * - Generation of end-of-data mark: a special sequence marks * the end of output when the encoder transitions to * isfinished() == true, usually by an explicit * call to finish() * - Reset support: the encoder may be reset to its initial * state and thereby recycled at minimum cost * * * Helper functions are provided for encoding data from plain * memory buffers and from strings. Some have no encode(...) * equivalent because they cannot incrementally encode from * the input, hence they always use the flush option. * * The 'mem' suffix has been tacked on to these functions to * resolve ambiguities dealing with 'char *' that should be * promoted to WvString. For instance, consider the signatures * of strflushmem(const void*, size_t) and strflushstr(WvStringParm, * bool). * * Another reason for these suffixes is to simplify overloading * the basic methods in subclasses since C++ would require the * subclass to redeclare all of the other signatures for * an overloaded method. * */ class WvEncoder { protected: bool okay; /*!< false iff setnotok() was called */ bool finished; /*!< true iff setfinished()/finish() was called */ WvString errstr; /*!< the error message */ public: /** Creates a new WvEncoder. */ WvEncoder(); /** Destroys the encoder. Unflushed data is lost. */ virtual ~WvEncoder(); /** * Returns true if the encoder has not encountered an error. * * This should only be used to record permanent failures. * Transient errors (eg. bad block, but recoverable) should be * detected in a different fashion. * * Returns: true if the encoder is ok */ bool isok() const { return okay && _isok(); } /** * Returns true if the encoder can no longer encode data. * * This will be set when the encoder detects and end-of-data * mark in its input, or when finish() is called. * * Returns: true if the encoder is finished */ bool isfinished() const { return finished || _isfinished(); } /** * Returns an error message if any is available. * * Returns: the error message, or the null string is isok() == true */ WvString geterror() const; /** * Reads data from the input buffer, encodes it, and writes the result * to the output buffer. * * If flush == true, the input buffer will be drained and the output * buffer will contain all of the encoded data including any that * might have been buffered internally from previous calls. Thus it * is possible that new data will be written to the output buffer even * though the input buffer was empty when encode() was called. If the * buffer could not be fully drained because there was insufficient * data, this function returns false and leaves the remaining unflushed * data in the buffer. * * If flush == false, the encoder will read and encode as much data * as possible (or as is convenient) from the input buffer and store * the results in the output buffer. Partial results may be buffered * internally by the encoder to be written to the output buffer later * when the encoder is flushed. * * If finish = true, the encode() will be followed up by a call to * finish(). The return values will be ANDed together to yield the * final result. Most useful when flush is also true. * * If a permanent error occurs, then isok() will return false, this * function will return false and the input buffer will be left in an * undefined state. * * If a recoverable error occurs, the encoder should discard the * problematic data from the input buffer and return false from this * function, but isok() will remain true. * * A stream might become isfinished() == true if an encoder- * specific end-of-data marker was detected in the input. * * "inbuf" is the input buffer * "outbuf" is the output buffer * "flush" is if true, flushes the encoder * "finish" is if true, calls finish() on success * Returns: true on success * @see _encode for the actual implementation */ bool encode(WvBuf &inbuf, WvBuf &outbuf, bool flush = false, bool finish = false); /** * Flushes the encoder and optionally finishes it. * * "inbuf" is the input buffer * "outbuf" is the output buffer * "finish" is if true, calls finish() on success * Returns: true on success */ bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish = false) { return encode(inbuf, outbuf, true, finish); } /** * Tells the encoder that NO MORE DATA will ever be encoded. * * The encoder will flush out any internally buffered data * and write out whatever end-of-data marking it needs to the * supplied output buffer before returning. * * Clients should invoke flush() on the input buffer before * finish() if the input buffer was not yet empty. * * It is safe to call this function multiple times. * The implementation will simply return isok() and do nothing else. * * "outbuf" is the output buffer * Returns: true on success * @see _finish for the actual implementation */ bool finish(WvBuf &outbuf); /** * Asks an encoder to reset itself to its initial state at * creation time, if supported. * * This function may be called at any time, even if * isok() == false, or isfinished() == true. * * If the behaviour is not supported or an error occurs, * then false is returned and afterwards isok() == false. * * Returns: true on success * @see _reset for the actual implementation */ bool reset(); /** * Flushes data through the encoder from a string to a buffer. * * "instr" is the input string * "outbuf" is the output buffer * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushstrbuf(WvStringParm instr, WvBuf &outbuf, bool finish = false); /** * Flushes data through the encoder from a string to a string. * * The output data is appended to the target string. * * "instr" is the input string * "outstr" is the output string * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushstrstr(WvStringParm instr, WvString &outstr, bool finish = false); /** * Encodes data from a buffer to a string. * * The output data is appended to the target string. * * "inbuf" is the input buffer * "outstr" is the output string * "flush" is if true, flushes the encoder * "finish" is if true, calls finish() on success * Returns: true on success */ bool encodebufstr(WvBuf &inbuf, WvString &outstr, bool flush = false, bool finish = false); /** * Flushes data through the encoder from a buffer to a string. * * The output data is appended to the target string. * * "inbuf" is the input buffer * "outstr" is the output string * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushbufstr(WvBuf &inbuf, WvString &outstr, bool finish = false) { return encodebufstr(inbuf, outstr, true, finish); } /** * Flushes data through the encoder from a string to a string. * * "inbuf" is the input buffer * "finish" is if true, calls finish() on success * Returns: the resulting encoded string, does not signal errors */ WvString strflushstr(WvStringParm instr, bool finish = false); /** * Flushes data through the encoder from a buffer to a string. * * "inbuf" is the input buffer * "finish" is if true, calls finish() on success * Returns: the resulting encoded string, does not signal errors */ WvString strflushbuf(WvBuf &inbuf, bool finish = false); /** * Flushes data through the encoder from memory to a buffer. * * "inmem" is the input data pointer * "inlen" is the input data length * "outbuf" is the output buffer * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushmembuf(const void *inmem, size_t inlen, WvBuf &outbuf, bool finish = false); /** * Flushes data through the encoder from memory to memory. * * The outlen parameter specifies by reference * the length of the output buffer. It is updated in place to * reflect the number of bytes copied to the output buffer. * If the buffer was too small to hold the data, the overflow * bytes will be discarded and false will be returned. * * "inmem" is the input data pointer * "inlen" is the input data length * "outmem" is the output data pointer * "outlen" is the output data length, by reference * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushmemmem(const void *inmem, size_t inlen, void *outmem, size_t *outlen, bool finish = false); /** * Encodes data from a buffer to memory. * * The outlen parameter specifies by reference * the length of the output buffer. It is updated in place to * reflect the number of bytes copied to the output buffer. * If the buffer was too small to hold the data, the overflow * bytes will be discarded and false will be returned. * * "inmem" is the input data pointer * "inlen" is the input data length * "outmem" is the output data pointer * "outlen" is the output data length, by reference * "flush" is if true, flushes the encoder * "finish" is if true, calls finish() on success * Returns: true on success */ bool encodebufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool flush = false, bool finish = false); /** * Flushes data through the encoder from a buffer to memory. * * The outlen parameter specifies by reference * the length of the output buffer. It is updated in place to * reflect the number of bytes copied to the output buffer. * If the buffer was too small to hold the data, the overflow * bytes will be discarded and false will be returned. * * "inbuf" is the input buffer * "outmem" is the output data pointer * "outlen" is the output data length, by reference * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushbufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool finish = false) { return encodebufmem(inbuf, outmem, outlen, true, finish); } /** * Flushes data through the encoder from a string to memory. * * The outlen parameter specifies by reference * the length of the output buffer. It is updated in place to * reflect the number of bytes copied to the output buffer. * If the buffer was too small to hold the data, the overflow * bytes will be discarded and false will be returned. * * "instr" is the input string * "outmem" is the output data pointer * "outlen" is the output data length, by reference * "finish" is if true, calls finish() on success * Returns: true on success */ bool flushstrmem(WvStringParm instr, void *outmem, size_t *outlen, bool finish = false); /** * Flushes data through the encoder from memory to a string. * * "inmem" is the input data pointer * "inlen" is the input data length * "finish" is if true, calls finish() on success * Returns: the resulting encoded string, does not signal errors */ WvString strflushmem(const void *inmem, size_t inlen, bool finish = false); protected: /** Sets 'okay' to false explicitly. */ void setnotok() { okay = false; } /** Sets an error condition, then setnotok(). */ void seterror(WvStringParm message) { errstr = message; setnotok(); } /** Sets an error condition, then setnotok(). */ void seterror(WVSTRING_FORMAT_DECL) { seterror(WvString(WVSTRING_FORMAT_CALL)); } /** Sets 'finished' to true explicitly. */ void setfinished() { finished = true; } protected: /** * Template method implementation of isok(). * * Not called if any of the following cases are true: * * - okay == false * * * Most implementations do not need to override this. * * Returns: true if the encoder is ok * @see setnotok */ virtual bool _isok() const { return true; } /** * Template method implementation of isfinished(). * * Not called if any of the following cases are true: * * - finished == true * * * Most implementations do not need to override this. * * Returns: true if the encoder is finished * @see setfinished */ virtual bool _isfinished() const { return false; } /** * Template method implementation of geterror(). * * Not called if any of the following cases are true: * * - isok() == true * - errstr is not null * * * Most implementations do not need to override this. * * Returns: the error message, or the null string if _isok() == true * @see seterror */ virtual WvString _geterror() const { return WvString::null; } /** * Template method implementation of encode(). * * Not called if any of the following cases are true: * * - okay == false * - finished == true * - in.used() == 0 && flush == false * * * All implementations MUST define this. * * If you also override _isok() or _isfinished(), note that they * will NOT be consulted when determining whether or not to * invoke this function. This allows finer control over the * semantics of isok() and isfinished() with respect to encode(). * * "inbuf" is the input buffer * "outbuf" is the output buffer * "flush" is if true, flushes the encoder * Returns: true on success * @see encode */ virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) = 0; /** * Template method implementation of finish(). * * Not called if any of the following cases are true: * * - okay == false * - finished == true * * * The encoder is marked finished AFTER this function exits. * * Many implementations do not need to override this. * * If you also override _isok() or _isfinished(), note that they * will NOT be consulted when determining whether or not to * invoke this function. This allows finer control over the * semantics of isok() and isfinished() with respect to finish(). * * "outbuf" is the output buffer * Returns: true on success * @see finish */ virtual bool _finish(WvBuf &outbuf) { return true; } /** * Template method implementation of reset(). * * When this method is invoked, the current local state will * be okay == true and finished == false. If false is returned, * then okay will be set to false. * * May set a detailed error message if an error occurs. * * Returns: true on success, false on error or if not supported * @see reset */ virtual bool _reset() { return false; } }; /** An encoder that discards all of its input. */ class WvNullEncoder : public WvEncoder { protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported: does nothing }; /** * A very efficient passthrough encoder that just merges the * input buffer into the output buffer. * * Counts the number of bytes it has processed. * * Supports reset(). * */ class WvPassthroughEncoder : public WvEncoder { size_t total; public: WvPassthroughEncoder(); virtual ~WvPassthroughEncoder() { } /** * Returns the number of bytes processed so far. * Returns: the number of bytes */ size_t bytes_processed() { return total; } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported: resets the count to zero }; /** * An encoder chain owns a list of encoders that are used in sequence * to transform data from a source buffer to a target buffer. * * Supports reset() if all the encoders it contains also support * reset(). * */ class WvEncoderChain : public WvEncoder { class ChainElem { public: WvEncoder *enc; WvDynBuf out; bool autofree; ChainElem(WvEncoder *enc, bool autofree) : enc(enc), autofree(autofree) { } ~ChainElem() { if (autofree) delete enc; } }; DeclareWvList(ChainElem); ChainElemList encoders; ChainElem *last_run; public: /** Creates an initially empty chain of encoders. */ WvEncoderChain(); /** Destroys the encoder chain. Calls zap(). */ virtual ~WvEncoderChain(); /** * Appends an encoder to the tail of the chain. * if "autofree" is true, takes ownership of the encoder */ void append(WvEncoder *enc, bool autofree); /** * Prepends an encoder to the head of the chain. * if "autofree" is true, takes ownership of the encoder */ void prepend(WvEncoder *enc, bool autofree); /** * Gets the autofree state of a particular encoder in the chain. * * If an encoder is in the chain multiple times, this will return * true if at least one instance is set to autofree. */ bool get_autofree(WvEncoder *enc) const; /** * Sets the autofree state of a particular encoder in the chain. * * if "autofree" is true, takes ownership of the encoder, by ensuring * only one of the encoders has autofree set. If it is false, then * all encoders have their autofree cleared. */ void set_autofree(WvEncoder *enc, bool autofree); /** * Unlinks the encoder from the chain. * Deletes the encoder if it was added with autofree == true. */ void unlink(WvEncoder *enc); /** * Clears the encoder chain. * Deletes any encoders that were added with autofree == true. */ void zap(); /** * "Continues" encoding a buffer. Runs all data in the buffer through * any encoders that have been added to the chain since the last encode. * * This is only useful once, immediately after you add one or more new * encoders to the chain. However, you can call it whenever you want, * and if no new encoders have been added, the given data will simply * be (perhaps) copied unchanged into outbuf. Note that this call * never does flush() or finish(), so outbuf may or may not be used. * * The supplied inbuf is guaranteed to be empty when this function * returns. */ bool continue_encode(WvBuf &inbuf, WvBuf &outbuf); /** * Returns true if there is data in an internal buffer. */ size_t buffered(); protected: /** * Returns true if the encoder has not encountered an error. * * WvEncoderChain is special in that it may transition from * isok() == false to isok() == true if the offending encoders * are removed from the list. * * Returns: true iff all encoders return isok() == true * @see WvEncoder::_isok */ virtual bool _isok() const; /** * Returns true if the encoder can no longer encode data. * * WvEncoderChain is special in that it may transition from * isfinished() == true to isfinished() == false if the offending * encoders are removed from the list, but not if finish() is * called. * * Returns: false iff all encoders return isfinished() == false */ virtual bool _isfinished() const; /** * Returns the error message, if any. * * WvEncoderChain is special in that it may transition from * !geterror() = false to !geterror() = true if the offending * encoders are removed from the list. * * Returns: the first non-null error message in the chain */ virtual WvString _geterror() const; /** * Passes the data through the entire chain of encoders. * Returns true iff all encoders return true. */ virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); /** * Finishes the chain of encoders. * * Invokes finish() on the first encoder in the chain, then * flush() on the second encoder if new data was generated, * then finish() on the second encoder, and so on until all * encoders have been flushed and finished (assuming the first * encoder had already been flushed). * * Returns true iff all encoders return true. */ virtual bool _finish(WvBuf & out); /** * Resets the chain of encoders. * * Resets all of the encoders in the chain and discards any * pending buffered input. Preserves the list of encoders. * * Returns: true iff all encoders return true. */ virtual bool _reset(); private: /** Used by _encode() and _finish() */ bool do_encode(WvBuf &in, WvBuf &out, ChainElem *start_after, bool flush, bool finish); }; #endif // __WVENCODER_H wvstreams-4.6.1/include/wvx509mgr.h0000644000175000001440000001411011100162141016136 0ustar wlachusers/* -*- Mode: C++ -*- * * X.509 certificate management class: This class builds upon the * functionality provided by the WvX509 class, adding operations that are * made possible with the addition of a private key (e.g. signing certificates * and CRLs). */ #ifndef __WVX509MGR_H #define __WVX509MGR_H #include "wvx509.h" #include "wvcrl.h" class WvX509Mgr : public WvX509 { public: /** * Constructor to create a blank certificate + keypair (useful if, for * example, you were going to load the appropriate values in later). */ WvX509Mgr(); /** * Constructor to create a self-signed certificate for the given dn and * RSA key. If you don't already have a WvRSAKey, try the other * constructor, below, which creates one automatically. If 'ca' is true, * the certificate will be created as a certificate authority. * * For SSL Servers, the dname must contain a "cn=" section in order to * validate correctly with some clients, particularly web browsers. * For example, if your domain name is nit.ca, you can try this for * _dname: "cn=nit.ca,o=Net Integration,c=CA", or maybe this instead: * "cn=nit.ca,dc=nit,dc=ca" * * We don't check automatically that your _dname complies with these * restrictions, since non-SSL certificates may be perfectly valid * without this. If you want to generate invalid certs, that's up to * you. */ WvX509Mgr(WvStringParm _dname, WvRSAKey *_rsa, bool ca = false); /** * Constructor to create a new self-signed certificate for the given dn * and number of bits. See the previous constructor for details on how * to choose _dname. 'bits' is the number of bits in the auto-generated * RSA key; 1024 or 2048 are good values for this. If 'ca' is true, the * certificate will be created as a certificate authority. */ WvX509Mgr(WvStringParm _dname, int bits, bool ca=false); /** * Copy Constructor. */ WvX509Mgr(const WvX509Mgr &mgr); protected: /** * Given the Distinguished Name dname and an already generated keypair in * rsa, return a Self Signed Certificate in cert. * If is_ca, it will generate a self-issued certificate with the * appropriate values for a certificate authority (or at least the most * common ones). Note that a certificate created in this way will not be * signed: */ void create_selfissued(WvStringParm dname, bool is_ca = false); public: /** Destructor */ virtual ~WvX509Mgr(); /** * Says if this certificate+key pair is good for use. Checks to make sure * that both are present and that they match. */ virtual bool isok() const; /** * Says what the error is, if isok() is not true. */ virtual WvString errstr() const; /** * The not operator returns true if !isok() */ bool operator! () const; /** * Allow us access to the RSA member. */ WvRSAKey *get_rsa() { return rsa; } void set_rsa(WvRSAKey *_rsa) { WVDELETE(rsa); rsa = new WvRSAKey(*_rsa); } /** * Avoid a lot of ugliness by having it so that we are binding to the SSL * context, and not the other way around, since that would make ownership * of the cert and rsa keys ambiguous. */ bool bind_ssl(SSL_CTX *ctx); /** * Take the PKCS#10 request in the string pkcs10req, sign it with the * private key in rsa, and then spit back a new X509 Certificate in * PEM format. */ WvString signreq(WvStringParm pkcs10req) const; /** * Sign the certificate with the rsa key associated with this class. */ bool signcert(WvX509 &unsignedcert) const; /** * Sign the CRL with the rsa key associated with this class. This method * will also update the lastUpdate time, and set the CRL's validity period * to 30 days. */ bool signcrl(WvCRL &unsignedcrl) const; /** * Test to make sure that a certificate and a keypair go together. * You can call it if you want to test a certificate yourself. * (Such as after a decode) */ bool test() const; /** * Sign the contents of data and return the signature as a BASE64 * string. */ WvString sign(WvBuf &data) const; WvString sign(WvStringParm data) const; /** * Encodes the information requested by mode into a buffer. */ virtual WvString encode(const WvX509::DumpMode mode) const; virtual WvString encode(const WvRSAKey::DumpMode mode) const; virtual void encode(const WvX509::DumpMode mode, WvBuf &buf) const; virtual void encode(const WvRSAKey::DumpMode mode, WvBuf &buf) const; /** * Load the information from the format requested by mode into * the class - this overwrites the certificate, and possibly the * key - and to enable two stage loading (the certificate first, then the * key), it DOES NOT call test() - that will be up to the programmer */ virtual void decode(const WvX509::DumpMode mode, WvStringParm encoded); virtual void decode(const WvRSAKey::DumpMode mode, WvStringParm encoded); virtual void decode(const WvX509::DumpMode mode, WvBuf &encoded); virtual void decode(const WvRSAKey::DumpMode mode, WvBuf &encoded); /** * This writes the certificate and RSA keys in PKCS12 format to the file * specified by filename, setting the password to "_pkcs12pass". Returns * true if the operation was successful, false otherwise. */ bool write_p12(WvStringParm _fname, WvStringParm _pkcs12pass) const; /** * And this reads from the file specified in filename using the password * "_pkcs12pass", and fills the RSA and cert members with the decoded * information. */ void read_p12(WvStringParm _fname, WvStringParm _pkcs12pass); private: /** * The Public and Private RSA keypair associated with the certificate * Make sure that you save this somewhere!!! If you don't, then you won't * really be able to use the certificate for anything... */ mutable WvRSAKey *rsa; mutable WvLog debug; }; #endif wvstreams-4.6.1/include/wvlink.h0000644000175000001440000000310611036722347015705 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvLink is one element of a linked list. * Used by wvlinklist.h. */ #ifndef __WVLINK_H #define __WVLINK_H #include // for 'NULL' /** * WvLink is one element of a WvList. * * Note that WvLink itself is untyped to minimize the amount of * generated code. This means that WvLink cannot handle the * autofree behaviour itself which would require static type * information. Instead, it defers this behaviour to the * template instantiation of WvList that uses it. * */ class WvLink { public: void *data; WvLink *next; const char *id; private: bool autofree : 1; public: WvLink(void *_data, bool _autofree, const char *_id = NULL): data(_data), next(NULL), id(_id), autofree(_autofree) {} WvLink(void *_data, WvLink *prev, WvLink *&tail, bool _autofree, const char *_id = NULL); bool get_autofree() { return autofree; } void set_autofree(bool _autofree) { autofree = _autofree; } void unlink(WvLink *prev) { prev->next = next; delete this; } }; #define WvIterStuff(_type_) \ /*! @brief Returns a reference to the current element. */ \ _type_ &operator () () const \ { return *ptr(); } \ /*! @brief Returns a pointer to the current element. */ \ _type_ *operator -> () const \ { return ptr(); } \ /*! @brief Returns a reference to the current element. */ \ _type_ &operator* () const \ { return *ptr(); } #endif // __WVLINK_H wvstreams-4.6.1/include/wvcont.h0000644000175000001440000001166011036722347015717 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * FIXME: I was too lazy to templatize this properly, so we only support * WvCallback. It should be possible to work with any kind * of return value and parameter, although it makes sense to limit things * to just one parameter (since it currently has to be returned by yield() * somehow). */ #ifndef __WVCONT_H #define __WVCONT_H #include "wvlinklist.h" #include "wvstreamsdebugger.h" #include "wvtr1.h" typedef wv::function WvContCallback; /** * WvCont provides "continuations", which are apparently also known as * semi-coroutines. You can wrap any WvCallback in a WvCont * and make it a "continuable" callback - that is, you can yield() from it * and return a value. Next time someone calls your callback, it will be * as if yield() has returned (and the parameter to your function is returned * from yield()). */ class WvCont { struct Data; friend struct Data; typedef WvList DataList; private: /** * When we copy a WvCont, we increase the reference count of the 'data' * member rather than copying it. That makes it so every copy of a given * callback object still refers to the same WvTask. */ Data *data; static DataList *data_list; static Data *curdata; static int taskdepth; static void bouncer(void *userdata); /** * Actually call the callback inside its task, and enforce a call stack. * Doesn't do anything with arguments. Returns the return value. */ void *call() { return _call(data); } /** * Call the callback inside its task, but don't assume this WvCont will * still be around when we come back. */ static void *_call(Data *data); /** * Construct a WvCont given a pre-existing Data structure. This is * basically equivalent to using the copy constructor. */ WvCont(Data *data); public: /** * Construct a WvCont using an existing WvCallback. The WvCont object * can be used in place of that callback, and stored in a callback of * the same data type. */ WvCont(const WvContCallback &cb, unsigned long stacksize = 64*1024); /** Copy constructor. */ WvCont(const WvCont &cb); /** Destructor. */ ~WvCont(); /** * call the callback, making p1 the return value of yield() or the * parameter to the function, and returning Ret, the argument of yield() * or the return value of the function. */ void *operator() (void *p1 = 0); // the following are static because a function doesn't really know // which WvCont it belongs to, and only one WvCont can be the "current" // one globally in an application anyway. // // Unfortunately this prevents us from assert()ing that you're in the // context you think you are. /** * Get a copy of the current WvCont. */ static WvCont current(); /** * "return" from the current callback, giving value 'ret' to the person * who called us. Next time this callback is called, it's as if yield() * had returned, and the parameter to the callback is the value of * yield(). */ static void *yield(void *ret = 0); /** * Tell us if the current context is "okay", that is, not trying to * die. If !isok(), you shouldn't yield(), because the caller is just * going to keep calling you until you die. Return as soon as you can. */ static bool isok(); /** * A templated function that allows you to pass a WvCont wherever a * C-style function pointer of the form * R func(T, void *userdata) * is taken. It's your job to make sure the 'userdata' provided is * a pointer to the right WvCont. * * Example: * typedef bool MyFunc(Obj *obj, void *userdata); * WvCont cont; * MyFunc *func = &WvCont::c_bouncer; * bool b = func(new Obj, &cont); */ template static R c_bouncer(T t, void *_cont) { WvCont &cont = *(WvCont *)_cont; return (R)cont((T)t); } /** * A templated function that allows you to pass a WvCont wherever a * C-style function pointer of the form * R func(void *userdata) * is taken. It's your job to make sure the 'userdata' provided is * a pointer to the right WvCont. * * Example: * typedef bool MyFunc(void *userdata); * WvCont cont; * MyFunc *func = &WvCont::c_bouncer; * bool b = func(&cont); */ template static R c_bouncer(void *_cont) { WvCont &cont = *(WvCont *)_cont; return (R)cont(0); } private: static WvString debugger_conts_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *); }; #endif // __WVCONT_H wvstreams-4.6.1/include/wvlogstream.h0000644000175000001440000000102511036722347016743 0ustar wlachusers#ifndef __WVLOGSTREAM_H #define __WVLOGSTREAM_H #include "wvlogrcv.h" /** * A WvLogRcv that sends its log messages to any supplied WvStream. * * Takes ownership of the given stream, so it will be release()d when * this object goes away. */ class WvLogStream: public WvLogRcv { public: WvLogStream(IWvStream *s, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvLogStream(); protected: IWvStream *cloned; virtual void _mid_line(const char *str, size_t len); }; #endif // __WVLOGSTREAM_H wvstreams-4.6.1/include/wvtripledes.h0000644000175000001440000000526711036722347016755 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * TripleDES cryptography abstractions. */ #ifndef __WVTRIPLEDES_H #define __WVTRIPLEDES_H #include "wvencoder.h" #include "wvencoderstream.h" #include "wvcrypto.h" #include /** * An encoder implementing the TripleDES encryption method. * * Supports reset(). * */ class WvTripleDESEncoder : public WvCryptoEncoder { public: enum Mode { ECBEncrypt, /*!< Encrypt using ECB mode (avoid) */ ECBDecrypt, /*!< Decrypt using ECB mode (avoid) */ CFBEncrypt, /*!< Encrypt using CFB mode (simulates a stream) */ CFBDecrypt, /*!< Decrypt using CFB mode (simulates a stream) */ CBCEncrypt, /*!< Encrypt using CBC mode */ CBCDecrypt /*!< Decrypt using CBC mode */ }; /* * Creates a new TripleDES cipher encoder. * * "mode" is the encryption mode * "key[1-3]" are the initial keys */ WvTripleDESEncoder(Mode mode, const void *key1, const void *key2, const void *key3); /* virtual ~WvTripleDESEncoder(); */ /* * Sets the current TripleDES keys and resets the initialization * vector to all nulls. * * "key[1-3]" are the new keys */ virtual void setkey(const void *key) { setkey(key, (unsigned char*)key+DES_KEY_SZ, (unsigned char *)key+(DES_KEY_SZ*2)); return; } virtual void setkey(const void *_key1, const void *_key2, const void *_key3); /* * Sets the current TripleDES initialization vector. * * "iv" is the new IV must be 8 bytes */ virtual void setiv(const void *iv); protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported: restores most recently set // key and initialization vector private: Mode mode; des_cblock key; des_key_schedule deskey1; des_key_schedule deskey2; des_key_schedule deskey3; des_cblock ivec; // initialization vector int ivecoff; // current offset into initvec }; /** * A crypto stream implementing TripleDES encryption. * * By default, written data is encrypted using * WvTripleDESEncoder::CFBEncrypt, read data is decrypted using * WvTripleDESEncoder::CFBDecrypt. * * @see WvTripleDESEncoder */ class WvTripleDESStream : public WvEncoderStream { public: WvTripleDESStream(WvStream *_cloned, const void *_key1, const void *_key2, const void *_key3, WvTripleDESEncoder::Mode readmode = WvTripleDESEncoder::CFBDecrypt, WvTripleDESEncoder::Mode writemode = WvTripleDESEncoder::CFBEncrypt); virtual ~WvTripleDESStream() { } }; #endif // __WVTRIPLEDES_H wvstreams-4.6.1/include/uniwatch.h0000644000175000001440000000230011036722347016210 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class that does add_callback when created and del_callback when * destroyed, thus making it harder to do one or the other incorrectly. * * Because it's an object itself, it uses its own 'this' pointer as the * 'cookie', so you don't have to come up with one. */ #ifndef __UNIWATCH_H #define __UNIWATCH_H #include "uniconf.h" class UniWatch { UniConf cfg; UniConfCallback cb; bool recurse; public: // standard "add_callback" version UniWatch(const UniConf &_cfg, const UniConfCallback &_cb, bool _recurse = true); // special "add_setbool" version UniWatch(const UniConf &_cfg, bool *b, bool _recurse = true); ~UniWatch(); }; DeclareWvList2(UniWatchListBase, UniWatch); class UniWatchList : public UniWatchListBase { public: void add(const UniConf &_cfg, const UniConfCallback &_cb, bool _recurse = true) { append(new UniWatch(_cfg, _cb, _recurse), true); } void add(const UniConf &_cfg, bool *b, bool _recurse = true) { append(new UniWatch(_cfg, b, _recurse), true); } }; #endif // __UNIWATCH_H wvstreams-4.6.1/include/uniconfpair.h0000644000175000001440000000167111036722347016715 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniConf key-value pair storage abstraction. */ #ifndef __UNICONFPAIR_H #define __UNICONFPAIR_H #include "uniconfkey.h" #include "wvstring.h" #include "wvhashtable.h" /** Represents a simple key-value pair. */ class UniConfPair { UniConfKey xkey; /*!< the name of this entry */ WvString xvalue; /*!< the value of this entry */ public: /** * Creates a UniConfPair. * "key" is the key * "value" is the value */ UniConfPair(const UniConfKey &key, WvStringParm value) : xkey(key), xvalue(value) { } const UniConfKey &key() const { return xkey; } const WvString &value() { return xvalue; } void setvalue(WvStringParm value) { xvalue = value; } void setkey(UniConfKey &key) { xkey = key; } }; DeclareWvList(UniConfPair); #endif //__UNICONFPAIR_H wvstreams-4.6.1/include/unisecuregen.h0000644000175000001440000000504711036722347017075 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __UNISECUREGEN_H #define __UNISECUREGEN_H #include "unifiltergen.h" #include "unipermgen.h" #include "wvstring.h" #include "wvstringlist.h" /** * UniSecureGen wraps a given generator and checks permissions (using a * Unix-style scheme) before responding to requests. The permissions for * generator gen are stored in a parallel tree, perms. * * It is up to the caller to ensure that the UniPermGen is itself secure. * (The easiest way is probably to back it with an ini file in a secure * directory.) Note that there is a race condition here: there is no locking * to be sure that the UniPermGen is not altered while a key is being looked * up. This could come into play, for instance, if the exec permission is * removed from a subtree while the UniSecureGen is in the middle of * drilldown(). * * UniSecureGen can be created with a moniker, but only if the particular * implementation of file permissions you want is UniPermGen. Otherwise, * create a different kind of UniPermGen yourself, pass it to the * constructor of this class, and mount it in your UniConf by hand. */ class UniSecureGen : public UniFilterGen { UniPermGen *perms; UniPermGen::Credentials cred; public: UniSecureGen(IUniConfGen *_gen, UniPermGen *_perms); UniSecureGen(WvStringParm moniker, UniPermGen *_perms = NULL); void setcredentials(const UniPermGen::Credentials &_cred); void setcredentials(WvStringParm user, const WvStringList &groups); /** Overridden methods */ virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual bool exists(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); virtual bool refresh(); virtual void commit(); private: /** Check the perms tree for the given permission */ bool findperm(const UniConfKey &key, UniPermGen::Type type); /** * Search the fullpath of key to be sure we are able to view each * element. If we ever find a missing exec permission, return false * immediately. */ bool drilldown(const UniConfKey &key); /** Override gencallback to check for permissions before sending a delta */ virtual void gencallback(const UniConfKey &key, WvStringParm value); }; #endif // __UNISECUREGEN_H wvstreams-4.6.1/include/wvstreamsdebugger.h0000644000175000001440000000514311036722347020136 0ustar wlachusers/* -*- Mode: C++ -*- */ #ifndef WVSTREAMSDEBUGGER_H #define WVSTREAMSDEBUGGER_H #include #include "wverror.h" #include "wvstringlist.h" #include "wvtclstring.h" #include "wvtr1.h" class WvStreamsDebugger { public: // The callback type used to pass the results back to the application // that calls WvStreamsDebugger::run. The application is allowed // to consume the WvStringList of results. typedef wv::function ResultCallback; // Debugging commands are implemented through the following three // callbacks: // - InitCallback is optional and is used to allocate state // for an instance of WvStreamsDebugger for the given command // - RunCallback is required and is used to actually execute // the command as a result of a call to WvStreamsDebugger::run // - CleanupCallback is optional and is used to free state // for an instance of WvStreamsDebugger for the given command typedef wv::function InitCallback; typedef wv::function RunCallback; typedef wv::function CleanupCallback; // The WvStreamsDebugger::foreach function can be used to update // state in every instance of WvStreamsDebugger for a given command. typedef wv::function ForeachCallback; private: struct Command { InitCallback init_cb; RunCallback run_cb; CleanupCallback cleanup_cb; Command(InitCallback _init_cb, RunCallback _run_cb, CleanupCallback _cleanup_cb) { init_cb = _init_cb; run_cb = _run_cb; cleanup_cb = _cleanup_cb; } }; typedef std::map CommandMap; static CommandMap *commands; typedef std::map CommandDataMap; CommandDataMap command_data; void *get_command_data(WvStringParm cmd, Command *command); friend class WvStreamsDebuggerStaticInitCleanup; public: WvStreamsDebugger(); ~WvStreamsDebugger(); WvString run(WvStringParm cmd, WvStringList &args, ResultCallback result_cb); static bool add_command(WvStringParm cmd, InitCallback init_cb, RunCallback run_cb, CleanupCallback cleanup_cb); static bool foreach(WvStringParm cmd, ForeachCallback foreach_cb); private: static WvString help_run_cb(WvStringParm cmd, WvStringList &args, ResultCallback result_cb, void *); }; #endif wvstreams-4.6.1/include/unipstoregen.h0000644000175000001440000000445211036722347017122 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A generator that exposes Windows protected storage. * * When linking statically, use the following #pragma to ensure this * generator gets registered: * #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VUniConfGen@@@@A") */ #ifndef __UNICONFPSTORE_H #define __UNICONFPSTORE_H #include "uniconfgen.h" #include "wvlog.h" #include "windows.h" #include "pstorec.tlh" #define PST_KEY_CURRENT_USER 0x00000000 // Specifies that the storage is maintained in the current user section of the registry. #define PST_KEY_LOCAL_MACHINE 0x00000001 // Specifies that the storage is maintained in the local machine section of the registry. #define PST_E_OK 0x00000000L // The operation was successful. #define PST_E_TYPE_EXISTS 0x800C0004L // The data item already exists in the protected storage. #define PST_E_UNKNOWN_TYPE 0x800C0005L #define PST_E_NOT_FOUND 0x800C0010L #define PST_PF_ALWAYS_SHOW 0x00000001 // Requests that the provider show the prompt dialog to the user even if not required for this access. #define PST_PF_NEVER_SHOW 0x00000002 // Do not show the prompt dialog to the user. #define PST_CF_DEFAULT 0x00000000 // Allows user to choose confirmation style. #define PST_CF_NONE 0x00000001 // Forces silent item creation. /** * A generator that exposes Windows protected storage. * * To mount, use the moniker * "pstore:PST_KEY_CURRENT_USER:TYPENAME:TYPEGUID:SUBTYPE:SUBTYPEGUID" * */ class UniPStoreGen : public UniConfGen { private: WvLog m_log; HMODULE m_hPstoreDLL; PSTORECLib::IPStorePtr m_spPStore; GUID m_type, m_subtype; DWORD m_key; HRESULT create_types(WvString type_name, WvString subtype_name); protected: virtual void flush_buffers() { } public: UniPStoreGen(WvString _base); virtual ~UniPStoreGen(); /***** Overridden methods *****/ virtual bool isok(); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); }; #endif // __UNICONFPSTORE_H wvstreams-4.6.1/include/wvbufstore.h0000644000175000001440000003542711036722347016614 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines basic buffer storage classes. * These are not intended for use directly by clients. * See "wvbufbase.h" for the public API. */ #ifndef __WVBUFFERSTORE_H #define __WVBUFFERSTORE_H #include "wvlinklist.h" #include #include #include /** * This value is used internally to signal unlimited free space. * It is merely meant to be as large as possible yet leave enough * room to accomodate simple arithmetic operations without overflow. * Clients should NOT check for the presence of this value explicitly. */ #define UNLIMITED_FREE_SPACE (INT_MAX/2) /** The abstract buffer storage base class. */ class WvBufStore { // discourage copying explicit WvBufStore(const WvBufStore &other) { } protected: // the suggested granularity int granularity; /** * Creates a new buffer. * "_granularity" is the suggested granularity for data allocation * and alignment purposes */ explicit WvBufStore(int _granularity); public: virtual ~WvBufStore() { } /*** Buffer Reading ***/ virtual bool isreadable() const { return true; } virtual size_t used() const = 0; virtual size_t optgettable() const { return used(); } virtual const void *get(size_t count) = 0; virtual void skip(size_t count) { get(count); } virtual void unget(size_t count) = 0; virtual size_t ungettable() const = 0; virtual size_t peekable(int offset) const; virtual size_t optpeekable(int offset) const { return peekable(offset); } virtual const void *peek(int offset, size_t count) { return mutablepeek(offset, count); } virtual void zap() = 0; // helpers void move(void *buf, size_t count); void copy(void *buf, int offset, size_t count); /*** Buffer Writing ***/ virtual bool iswritable() const { return true; } virtual size_t free() const = 0; virtual size_t optallocable() const { return free(); } virtual void *alloc(size_t count) = 0; virtual void unalloc(size_t count) = 0; virtual size_t unallocable() const = 0; virtual void *mutablepeek(int offset, size_t count) = 0; // helpers void put(const void *data, size_t count); void fastput(const void *data, size_t count); void poke(const void *data, int offset, size_t count); /*** Buffer to Buffer Transfers ***/ virtual void merge(WvBufStore &instore, size_t count); // default implementation void basicmerge(WvBufStore &instore, size_t count); protected: /*** Support for buffers with subbuffers ***/ /** Returns true if the buffer uses subbuffers for storage. */ virtual bool usessubbuffers() const { return false; } /** Returns the number of subbuffers in the buffer. */ virtual size_t numsubbuffers() const { return 0; } /** * Returns the first subbuffer. * Returns: the buffer or NULL if none or not supported */ virtual WvBufStore *firstsubbuffer() const { return NULL; } /** Appends a subbuffer to the buffer. */ virtual void appendsubbuffer(WvBufStore *buffer, bool autofree) { /*assert(! "not supported");*/ } /** Prepends a subbuffer to the buffer. */ virtual void prependsubbuffer(WvBufStore *buffer, bool autofree) { /*assert(! "not supported");*/ } /** * Unlinks the specified subbuffer. * Only autofrees the buffer if allowautofree == true. * Returns: the autofree flag for the buffer */ virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree) { /*assert(! "not supported");*/ return true; } }; // lists of buffer stores are sometimes useful DeclareWvList(WvBufStore); /** * A statically bound mixin template for buffer implementations that are * read-only. It is an error to attempt to write to a read-only buffer. * Note that read-only in this context does not mean the same as "const". */ template class WvReadOnlyBufferStoreMixin : public Super { public: explicit WvReadOnlyBufferStoreMixin(int _granularity) : Super(_granularity) { } virtual bool iswritable() const { return false; } virtual size_t free() const { return 0; } virtual size_t optallocable() const { return 0; } virtual void *alloc(size_t count) { assert(count == 0 || ! "non-zero alloc() called on non-writable buffer"); return NULL; } virtual void unalloc(size_t count) { assert(count == 0 || ! "non-zero unalloc() called on non-writable buffer"); } virtual size_t unallocable() const { return 0; } virtual void *mutablepeek(int offset, size_t count) { assert(count == 0 || ! "mutablepeek() called on non-writable buffer"); return NULL; } virtual void merge(WvBufStore &instore, size_t count) { assert(count == 0 || ! "non-zero merge() called on non-writable buffer"); } }; /** * A statically bound mixin template for buffer implementations that are * write-only. It is an error to attempt to read from a write-only buffer. */ template class WvWriteOnlyBufferStoreMixin : public Super { public: explicit WvWriteOnlyBufferStoreMixin(int _granularity) : Super(_granularity) { } virtual bool isreadable() const { return false; } virtual size_t used() const { return 0; } virtual size_t optgettable() const { return 0; } virtual size_t peekable(int offset) const { return 0; } virtual size_t optpeekable(int offset) const { return 0; } virtual const void *get(size_t count) { assert(count == 0 || ! "non-zero get() called on non-readable buffer"); return NULL; } virtual void skip(size_t count) { assert(count == 0 || ! "non-zero skip() called on non-readable buffer"); } virtual void unget(size_t count) { assert(count == 0 || ! "non-zero unget() called on non-readable buffer"); } virtual size_t ungettable() const { return 0; } virtual const void *peek(int offset, size_t count) { assert(count == 0 || ! "peek() called on non-readable buffer"); return NULL; } virtual void zap() { // nothing to zap } }; /** The WvInPlaceBuf storage class. */ class WvInPlaceBufStore : public WvBufStore { protected: void *data; size_t xsize; size_t readidx; size_t writeidx; bool xautofree; public: WvInPlaceBufStore(int _granularity, void *_data, size_t _avail, size_t _size, bool _autofree); WvInPlaceBufStore(int _granularity, size_t _size); virtual ~WvInPlaceBufStore(); void *ptr() const { return data; } size_t size() const { return xsize; } bool get_autofree() const { return xautofree; } void set_autofree(bool _autofree) { xautofree = _autofree; } void reset(void *_data, size_t _avail, size_t _size, bool _autofree); void setavail(size_t _avail); /*** Overridden Members ***/ virtual size_t used() const; virtual const void *get(size_t count); virtual void unget(size_t count); virtual size_t ungettable() const; virtual void zap(); virtual size_t free() const; virtual void *alloc(size_t count); virtual void unalloc(size_t count); virtual size_t unallocable() const; virtual void *mutablepeek(int offset, size_t count); }; /** The WvConstInPlaceBuf storage class. */ class WvConstInPlaceBufStore : public WvReadOnlyBufferStoreMixin { protected: const void *data; size_t avail; size_t readidx; public: WvConstInPlaceBufStore(int _granularity, const void *_data, size_t _avail); const void *ptr() const { return data; } void reset(const void *_data, size_t _avail); void setavail(size_t _avail); /*** Overridden Members ***/ virtual size_t used() const; virtual const void *get(size_t count); virtual void unget(size_t count); virtual size_t ungettable() const; virtual const void *peek(int offset, size_t count); virtual void zap(); }; /** The WvCircularBuf storage class. */ class WvCircularBufStore : public WvBufStore { protected: void *data; size_t xsize; size_t head; size_t totalused; size_t totalinit; bool xautofree; public: WvCircularBufStore(int _granularity, void *_data, size_t _avail, size_t _size, bool _autofree); WvCircularBufStore(int _granularity, size_t _size); virtual ~WvCircularBufStore(); void *ptr() const { return data; } size_t size() const { return xsize; } bool get_autofree() const { return xautofree; } void set_autofree(bool _autofree) { xautofree = _autofree; } void reset(void *_data, size_t _avail, size_t _size, bool _autofree); void setavail(size_t _avail); void normalize(); /*** Overridden Members ***/ virtual size_t used() const; virtual size_t optgettable() const; virtual const void *get(size_t count); virtual void unget(size_t count); virtual size_t ungettable() const; virtual void zap(); virtual size_t free() const; virtual size_t optallocable() const; virtual void *alloc(size_t count); virtual void unalloc(size_t count); virtual size_t unallocable() const; virtual void *mutablepeek(int offset, size_t count); protected: /** * Ensures that count new bytes can be read from or written * to the buffer beginning at the specified offset as one * large contiguous block. * * "offset" is the offset * "count" is the number of bytes * "keephistory" is if true, does not purge unget history * Returns: the offset of the first available byte */ size_t ensurecontiguous(int offset, size_t count, bool keephistory); /** * Compacts an array arranged as a circular buffer such that * the specified region is moved to the beginning of the array. * * "data" is the array base * "size" is the size of the array * "head" is the beginning of the region to keep * "count" is the number of bytes in the region to keep */ static void compact(void *data, size_t size, size_t head, size_t count); }; /** * The WvLinkedBuffer storage class. * * A buffer store built out of a list of other buffers linked together. * Buffers may be appended or prepended to the list at any time, at * which point they act as slaves for the master buffer. Slaves may * be expunged from the list at any time when the master buffer * determines that they are of no further use. * * This is mostly useful for building other buffer storage classes. * */ class WvLinkedBufferStore : public WvBufStore { protected: WvBufStoreList list; size_t totalused; size_t maxungettable; public: explicit WvLinkedBufferStore(int _granularity); /*** Overridden Members ***/ virtual size_t used() const; virtual size_t optgettable() const; virtual const void *get(size_t count); virtual void unget(size_t count); virtual size_t ungettable() const; virtual void zap(); virtual size_t free() const; virtual size_t optallocable() const; virtual void *alloc(size_t count); virtual void unalloc(size_t count); virtual size_t unallocable() const; virtual size_t optpeekable(int offset) const; virtual void *mutablepeek(int offset, size_t count); protected: virtual bool usessubbuffers() const; virtual size_t numsubbuffers() const; virtual WvBufStore *firstsubbuffer() const; virtual void appendsubbuffer(WvBufStore *buffer, bool autofree); virtual void prependsubbuffer(WvBufStore *buffer, bool autofree); virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree); protected: /** * Called when a new buffer must be allocated to coalesce chunks. * * "minsize" is the minimum size for the new buffer * Returns: the new buffer */ virtual WvBufStore *newbuffer(size_t minsize); /** * Called when a buffer with autofree is removed from the list. * This function is not called during object destruction. * * "buffer" is the buffer to be destroyed */ virtual void recyclebuffer(WvBufStore *buffer); /** * Searches for the buffer containing the offset. * * "it" is the iterator updated to point to buffer found, * or to an invalid region if the offset is invalid * "offset" is the offset for which to search * Returns: the corrected offset within the buffer at it.ptr() */ int search(WvBufStoreList::Iter &it, int offset) const; /** * Coalesces a sequence of buffers. * * "it" is the iterator pointing to the first buffer * "count" is the required number of contiguous used bytes * Returns: the composite buffer */ WvBufStore *coalesce(WvBufStoreList::Iter &it, size_t count); private: // unlinks and recycles the buffer pointed at by the iterator void do_xunlink(WvBufStoreList::Iter &it); }; /** The WvDynBuf storage class. */ class WvDynBufStore : public WvLinkedBufferStore { size_t minalloc; size_t maxalloc; public: WvDynBufStore(size_t _granularity, size_t _minalloc, size_t _maxalloc); /*** Overridden Members ***/ virtual size_t free() const; virtual size_t optallocable() const; virtual void *alloc(size_t count); protected: virtual WvBufStore *newbuffer(size_t minsize); }; /** The WvNullBuf storage class. */ class WvNullBufStore : public WvWriteOnlyBufferStoreMixin< WvReadOnlyBufferStoreMixin > { public: explicit WvNullBufStore(size_t _granularity); }; /** The WvBufCursor storage class. */ class WvBufCursorStore : public WvReadOnlyBufferStoreMixin { protected: WvBufStore *buf; int start; size_t length; size_t shift; public: WvBufCursorStore(size_t _granularity, WvBufStore *_buf, int _start, size_t _length); /*** Overridden Members ***/ virtual bool isreadable() const; virtual size_t used() const; virtual size_t optgettable() const; virtual const void *get(size_t count); virtual void skip(size_t count); virtual void unget(size_t count); virtual size_t ungettable() const; virtual size_t peekable(int offset) const; virtual size_t optpeekable(int offset) const; virtual const void *peek(int offset, size_t count); virtual void zap(); virtual bool iswritable() const; virtual void *mutablepeek(int offset, size_t count); }; #endif // __WVBUFFERSTORE_H wvstreams-4.6.1/include/wvcountermode.h0000644000175000001440000000326111036722347017276 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A 'counter mode' cryptography engine abstraction. */ #ifndef __WVCOUNTERMODE_H #define __WVCOUNTERMODE_H #include "wvencoder.h" /** A counter mode encryption encoder. */ class WvCounterModeEncoder : public WvEncoder { public: WvEncoder *keycrypt; /** * Create a new counter mode encoder / decoder. * _keycrypt : the underlying encoder for generating the keystream * (note: takes ownership of this encoder) * _counter : the initial counter value * _countersize : the counter size, must equal crypto block size */ WvCounterModeEncoder(WvEncoder *_keycrypt, const void *_counter, size_t _countersize); virtual ~WvCounterModeEncoder(); /** * Sets the Counter mode auto-incrementing counter. * counter : the counter * countersize : the new counter size, must equal crypto block size */ void setcounter(const void *counter, size_t countersize); /** * Stores the current counter in the supplied buffer. * counter : the array that receives the counter */ void getcounter(void *counter) const; /** Returns the counter size. */ size_t getcountersize() const { return countersize; } /** Increments the counter. */ virtual void incrcounter(); private: WvConstInPlaceBuf counterbuf; protected: unsigned char *counter; // auto-incrementing counter size_t countersize; // counter size in bytes virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); }; #endif // __WVCOUNTERMODE_H wvstreams-4.6.1/include/uninullgen.h0000644000175000001440000000162611036722347016560 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generator that is always empty and rejects changes. */ #ifndef __UNICONFNULL_H #define __UNICONFNULL_H #include "uniconfgen.h" /** * A generator that is always empty and rejects changes. * * To mount, use the moniker "null:". * */ class UniNullGen : public UniConfGen { public: UniNullGen() { }; virtual ~UniNullGen() { }; /***** Overridden methods *****/ virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key) { return WvString::null; } virtual void set(const UniConfKey &key, WvStringParm value) { } virtual void setv(const UniConfPairList &pairs) { } virtual bool haschildren(const UniConfKey &key) { return false; } virtual Iter *iterator(const UniConfKey &key) { return new NullIter(); } }; #endif // __UNICONFNULL_H wvstreams-4.6.1/include/wviproute.h0000644000175000001440000000246311036722347016444 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * The WvIPRoute and WvIPRouteList classes, which can manipulate the kernel * routing table in useful ways. */ #ifndef __WVIPROUTE_H #define __WVIPROUTE_H #include "wvaddr.h" #include "wvlinklist.h" #include "wvlog.h" /** Manipulate the kernel routing table in strange and interesting ways ;) */ class WvIPRoute { public: WvIPRoute(WvStringParm _ifc, const WvIPNet &_net, const WvIPAddr &_gate, int _metric, WvStringParm _table); operator WvString() const; bool operator== (const WvIPRoute &r2) const; WvString ifc; WvIPNet ip; WvIPAddr gateway; int metric; WvString table; // "advanced ip routing" table name WvIPAddr src; }; DeclareWvList2(WvIPRouteListBase, WvIPRoute); /** List of IP Routes currently in effect */ class WvIPRouteList : public WvIPRouteListBase { public: WvLog log; WvIPRouteList(); /** automatically fill the list with appropriate data from the kernel */ void get_kernel(); /** automatically set the kernel to the values in the RouteList */ void set_kernel(); /** find the routing entry that matches 'addr' */ WvIPRoute *find(const WvIPAddr &addr); }; #endif // __WVIPROUTE_H wvstreams-4.6.1/include/wvcrypto.h0000644000175000001440000000174311036722347016275 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Miscellaneous cryptography primitives. */ #ifndef __WVCRYPTO_H #define __WVCRYPTO_H #include "wvencoder.h" #include "wvfile.h" /** A very simple stream that returns randomness from /dev/urandom */ class WvRandomStream : public WvFile { public: WvRandomStream(); }; class WvCryptoEncoder : public WvEncoder { public: /* * Sets the current TripleDES keys and resets the initialization * vector to all nulls. * * "key[1-3]" are the new keys */ virtual void setkey(const void *_key) { return; } virtual void setkey(const void *_key1, const void *_key2, const void *_key3) { return; } /* * Sets the current TripleDES initialization vector. * * "iv" is the new IV must be 8 bytes */ virtual void setiv(const void *iv) { return; } }; #endif // __WVCRYPTO_H wvstreams-4.6.1/include/wvunixdgsocket.h0000644000175000001440000000362511036722347017465 0ustar wlachusers#ifndef __WVUNIXDGSOCKET_H #define __WVUNIXDGSOCKET_H #include #include #include #include #include "wvlog.h" #include "wvstring.h" #include "wvlinklist.h" #include "wvfdstream.h" #include "wvaddr.h" class WvUnixDGListener; class WvUnixDGConn; /** * WvStream-based Unix datagram domain socket base class. * * You probably want to use WvUnixDGConn and WvUnixDGListener as this will * probably be deprecated one day. */ class WvUnixDGSocket : public WvFDStream { bool server; int backoff; DeclareWvList(WvBuf); WvBufList bufs; public: WvUnixDGSocket(WvStringParm filename, bool _server, int perms = 0222); virtual ~WvUnixDGSocket(); virtual size_t uwrite(const void *buf, size_t count); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); protected: WvString socketfile; public: const char *wstype() const { return "WvUnixDGSocket"; } size_t bufsize; }; /** * WvStream-based Unix datagram domain socket connection class that listens on * filename. * * The specified file should already exist before using this. */ class WvUnixDGConn : public WvUnixDGSocket { public: WvUnixDGConn(WvStringParm filename) : WvUnixDGSocket(filename, false) {} public: const char *wstype() const { return "WvUnixDGConn"; } }; /** * Server end of a Unix datagram socket stream. * * Makes a datagram socket at filename with its permissions set to perms and * then listens to it like a good little WvStream. * * FIXME: Make this suck less. Do we want this to look like a wvunixsocket? */ class WvUnixDGListener : public WvUnixDGSocket { public: WvUnixDGListener(WvStringParm filename, int perms = 0222) : WvUnixDGSocket(filename, true, perms) {} public: const char *wstype() const { return "WvUnixDGListener"; } }; #endif wvstreams-4.6.1/include/strutils.h0000644000175000001440000000011611036722347016262 0ustar wlachusers// this file exists only for backwards compatibility! #include "wvstrutils.h" wvstreams-4.6.1/include/uniregistrygen.h0000644000175000001440000000421411036722347017452 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A generator that exposes the windows registry. * * When linking statically, use the following #pragma to ensure this * generator gets registered: * #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VUniConfGen@@@@A") */ #ifndef __UNICONFREGISTRY_H #define __UNICONFREGISTRY_H #include "uniconfgen.h" #include "wvlog.h" #include "windows.h" /** * A generator that exposes the windows registry. * * To mount, use the moniker "registry:". * */ class UniRegistryGen : public UniConfGen { WvLog m_log; HKEY m_hRoot; protected: virtual void flush_buffers() { } public: UniRegistryGen(WvString _base); virtual ~UniRegistryGen(); /***** Overridden methods *****/ virtual bool isok(); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); }; class UniRegistryGenIter : public UniConfGen::Iter { public: UniRegistryGenIter(UniRegistryGen &gen, const UniConfKey &key, HKEY base); /** Destroys the iterator. */ virtual ~UniRegistryGenIter(); /** * Rewinds the iterator. * Must be called prior to the first invocation of next(). */ virtual void rewind(); /** * Seeks to the next element in the sequence. * Returns true if that element exists. * Must be called prior to the first invocation of key(). */ virtual bool next(); /** Returns the current key. */ virtual UniConfKey key() const; /** Returns the value of the current key. */ virtual WvString value() const; private: LONG next_key(); LONG next_value(); HKEY m_hKey; enum Enumerating { KEYS, VALUES } m_enumerating; unsigned m_index; UniRegistryGen &gen; const UniConfKey parent; UniConfKey current_key; const HKEY m_dontClose; }; #endif // __UNICONFREGISTRY_H wvstreams-4.6.1/include/wvbackslash.h0000644000175000001440000000444211036722347016707 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * C-style backslash escaping and unescaping of strings. */ #ifndef __WVBACKSLASH_H #define __WVBACKSLASH_H #include "wvencoder.h" /** * An encoder that performs C-style backslash escaping of strings. * * Use this to escape control characters, unprintable characters, * and optionally quotes or any other special printable characters * into sequences of the form \\n, \\xFF, \\", etc... * * Supports reset(). * */ class WvBackslashEncoder : public WvEncoder { WvString nasties; public: /** * Creates a C-style backslash encoder. * nasties - the set of printable characters to escape * in addition to the non-printable ones * (should always contain at least backslash) */ WvBackslashEncoder(WvStringParm _nasties = "\\\""); virtual ~WvBackslashEncoder() { } protected: virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); virtual bool _reset(); }; /** * An encoder that performs C-style backslash unescaping of strings. * * Recognizes the following sequences preceeded by backslash: * * - a: substitutes alarm bell (ascii 7) * - b: substitutes backspace (ascii 8) * - f: substitutes formfeed (ascii 12) * - n: substitutes newline (ascii 10) * - r: substitutes carriage return (ascii 13) * - t: substitutes tab (ascii 9) * - v: substitutes vertical tab (ascii 11) * - 0: substitutes null (ascii 0) * - 0xyz: substitutes character with octal encoding xyz * - xxy: substitutes character with hex encoding xy * - newline: substitutes space (line continuation sequence) * - \\: substitutes backslash * - otherwise substitutes the next character (strips the backslash) * * * Supports reset(). * */ class WvBackslashDecoder : public WvEncoder { enum State { Initial, Escape, Hex1, Hex2, Octal1, Octal2, Octal3 }; State state; WvInPlaceBuf tmpbuf; int value; public: /** Creates a C-style backslash decoder. */ WvBackslashDecoder(); virtual ~WvBackslashDecoder() { } protected: virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); virtual bool _reset(); private: bool flushtmpbuf(WvBuf &outbuf); }; #endif // __WVBACKSLASH_H wvstreams-4.6.1/include/wvserialize.h0000644000175000001440000002550211122205460016727 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Code to serialize objects into WvBufs, and more code to read WvBufs and * construct objects from them. */ #ifndef __WVSERIALIZE_H #define __WVSERIALIZE_H #include "wvbuf.h" #include "wvstringlist.h" #ifndef _WIN32 # if HAVE_INTTYPES_H # include # else # if HAVE_STDINT_H # include # endif # endif #include #else #if _MSC_VER typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #endif #include #endif /** * Encode an object as an array of bytes and put it into a WvBuf. This * function just calls an overloaded _wv_serialize() function. There was * really no need for a template here at all, except for symmetry with * wv_deserialize() which does need one. */ template inline void wv_serialize(WvBuf &buf, const T &t) { _wv_serialize(buf, t); } /** * This function shouldn't be necessary at all, but using it makes totally * insane assembler errors go away (gcc 2.95.4, glibc 2.3.1). */ inline int32_t _wv_htonl(int32_t i) { return htonl(i); } inline int16_t _wv_htons(int16_t i) { return htons(i); } /** * Helper functions to convert 64 bit ints to and from host byteorder */ inline uint64_t ntohll(uint64_t n) { #ifdef WORDS_BIGENDIAN return n; #else return (((uint64_t)ntohl(n)) << 32) | ntohl(n >> 32); #endif } inline uint64_t htonll(uint64_t n) { #ifdef WORDS_BIGENDIAN return n; #else return (((uint64_t)htonl(n)) << 32) | htonl(n >> 32); #endif } /** * A helper function that serializes different types of integers. Since * it's inlined, the "if" is actually executed at compile time, so don't * worry. * * The clever part: it doesn't really matter what size an 'int' or a 'long' * is, as long as it's one of the sizes supported by this function. If an * int is 32 bits, we'll use the 32-bit serializer... and so on. */ template void wv_serialize_scalar(WvBuf &buf, const T t) { if (sizeof(T) == 8) { int64_t i = htonll(t); buf.put(&i, 8); } else if (sizeof(T) == 4) { int32_t i = _wv_htonl(t); buf.put(&i, 4); } else if (sizeof(T) == 2) { int32_t i = _wv_htons(t); buf.put(&i, 2); } else if (sizeof(T) == 1) buf.put(&t, 1); else assert(0); } inline void _wv_serialize(WvBuf &buf, long long i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, unsigned long long i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, long i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, unsigned long i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, int i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, unsigned int i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, short i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, unsigned short i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, bool i) { wv_serialize_scalar(buf, i); } /** Note: char != signed char for purposes of function overloading! */ inline void _wv_serialize(WvBuf &buf, char i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, signed char i) { wv_serialize_scalar(buf, i); } inline void _wv_serialize(WvBuf &buf, unsigned char i) { wv_serialize_scalar(buf, i); } /** * Serialize a WvString. The string serializer is guaranteed to not insert * any nuls (character 0) into the output stream except for the * string-terminating one, which is always present. This makes * deserialization easy. */ inline void _wv_serialize(WvBuf &buf, WvStringParm s) { if (!s.isnull()) buf.putstr(s); buf.put("", 1); // terminating nul } /** The template wv_serialize doesn't work for const char arrays. */ inline void wv_serialize(WvBuf &buf, const char *t) { _wv_serialize(buf, t); } /** * Serialize a WvBuf. This is handier than it sounds, because then * WvGdbmHash's value can be a WvBuf. */ inline void _wv_serialize(WvBuf &buf, const WvBuf &inbuf) { wv_serialize(buf, inbuf.used()); buf.put(const_cast(&inbuf)->peek(0, inbuf.used()), inbuf.used()); } /** * Serialize a list of serializable things. * * Oh boy - I think I'm having a bit too much fun. */ template void _wv_serialize(WvBuf &buf, const WvList &list) { // save the number of elements _wv_serialize(buf, (size_t)list.count()); // save the elements typename WvList::Iter i(list); for (i.rewind(); i.next(); ) _wv_serialize(buf, *i); } /** Deserialize an object. See wv_deserialize(). */ template T _wv_deserialize(WvBuf &buf); /** * Deserialize a complex templated object. See wv_deserialize(). * * This class is needed because partial template specialization only works * on classes, not on functions. So in order to define a generic deserializer * for, say, WvList, we have to have a class with a member function. Sigh. */ template class WvDeserialize { public: static T go(WvBuf &buf) { return _wv_deserialize(buf); } }; /** * If there's a deserializer for type "T", this will make a default * deserializer for type "T *"; that is, it'll allocate the new object * dynamically and you'll have to free it after. * * This helps when you want to assume *all* deserializers return pointers * that you need to delete later. * * FIXME: this class takes precedence over *specialized* _wv_deserialize() * functions for pointers! Pointer-based deserializers need to be classes * too until this is resolved. */ // note: this has to be a class because we use partial template // specialization, which doesn't work on functions. template class WvDeserialize { public: static T *go(WvBuf &buf) { return new T(_wv_deserialize(buf)); } }; /** * Deserialize an object: read bytes from a buffer, and return an object * constructed from that. * * Note that there is no default deserializer. You have to specialize this * template for every data type you might want to deserialize. We do define * some for a few standard C types. * * Implementation note: * If you define a deserializer for your own type, name it _wv_deserialize() * (with the underscore). If you're unlucky, you may need to define a * WvDeserialize class instead. * * Note that if you have a data structure, you probably want to * wv_deserialize(buf) instead of wv_deserialize(buf) to * avoid extra copies. You'll have to define _wv_deserialize() appropriately, * of course. Pointer-based _wv_deserialize() functions allocate memory, * so you'll have to 'delete' the returned object yourself. */ template inline T wv_deserialize(WvBuf &buf) { return WvDeserialize::go(buf); } /** * These functions shouldn't be necessary at all, but using it makes totally * insane assembler errors go away (gcc 2.95.4, glibc 2.3.1). */ inline int32_t _wv_ntohl(int32_t i) { return ntohl(i); } inline int16_t _wv_ntohs(int16_t i) { return ntohs(i); } /** * A helper function that deserializes different types of integers. Since * it's inlined, the "if" is actually executed at compile time, so don't * worry. */ template inline T wv_deserialize_scalar(WvBuf &buf) { if (buf.used() < sizeof(T)) return 0; if (sizeof(T) == 8) return (T) ntohll(*(int64_t *)buf.get(8)); else if (sizeof(T) == 4) return (T) _wv_ntohl(*(int32_t *)buf.get(4)); else if (sizeof(T) == 2) return (T) _wv_ntohs(*(int16_t *)buf.get(2)); else if (sizeof(T) == 1) return (T) *(int8_t *)buf.get(1); else assert(0); } template inline T xwv_deserialize_scalar(WvBuf &buf) { return 0; } template <> inline long long _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline unsigned long long _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline long _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline unsigned long _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline int _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline unsigned int _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline short _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline unsigned short _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline bool _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline char _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline signed char _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } template <> inline unsigned char _wv_deserialize(WvBuf &buf) { return wv_deserialize_scalar(buf); } /** * Deserialize a WvString. Stops at (and includes) the terminating nul * (zero) character. Serialized WvStrings are guaranteed not to contain nul * except as the last character. */ template <> WvString _wv_deserialize(WvBuf &buf); /** Deserialize a WvBuf. */ // FIXME: it should be possible to do this without using a class! template <> class WvDeserialize { public: static WvBuf *go(WvBuf &buf) { size_t len = wv_deserialize(buf); WvBuf *outbuf = new WvInPlaceBuf(new char[len], 0, len, true); outbuf->merge(buf, len); return outbuf; } }; /** Deserialize a list of serializable things. */ template class WvDeserialize *> { public: static WvList *go(WvBuf &buf) { WvList *list = new WvList; size_t nelems = wv_deserialize(buf); for (size_t count = 0; count < nelems; count++) { T t = wv_deserialize(buf); list->append(new T(t), true); } return list; } }; template <> class WvDeserialize { public: static WvStringList *go(WvBuf &buf) { WvStringList *list = new WvStringList(); size_t nelems = wv_deserialize(buf); for (size_t count = 0; count < nelems; count++) { WvString str = wv_deserialize(buf); list->append(str); } return list; } }; #endif // __WVSERIALIZE_H wvstreams-4.6.1/include/unireplicategen.h0000644000175000001440000000437011036722347017555 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that caches keys/values in memory. */ #ifndef __UNIREPLICATEGEN_H #define __UNIREPLICATEGEN_H #include "uniconftree.h" #include "wvlog.h" /** * A UniConf generator that replicates generators between an ordered list * of inner generators, with the priority given by the list. * * Replication of the data occurs when the generator is contructed, whenever * prepend() or append() is called, or whenever any of the generators in the * list goes from !isok() to isok(). If two inner generators contain different * values for the same before replication, then they will both have the value * of the earlier generator (as ordered in the moniker) after replication. * * If an asynchronous change occurs in any of the inner generators, the * new value will be set in all generators irrespective of priority. */ class UniReplicateGen : public UniConfGen { private: struct Gen { IUniConfGen *gen; bool was_ok; bool auto_free; Gen(IUniConfGen *_gen, bool _auto_free) : gen(_gen), was_ok(gen->isok()), auto_free(_auto_free) {} ~Gen() { if (auto_free) WVRELEASE(gen); } bool isok() { return was_ok = gen->isok(); } }; DeclareWvList(Gen); GenList gens; bool processing_callback; Gen *first_ok() const; void replicate_if_any_have_become_ok(); protected: void replicate(const UniConfKey &key = "/"); void deltacallback(Gen *src_gen, const UniConfKey &key, WvStringParm value); public: UniReplicateGen(); UniReplicateGen(const IUniConfGenList &_gens, bool autofree = true); virtual ~UniReplicateGen(); void prepend(IUniConfGen *gen, bool autofree = true); void append(IUniConfGen *gen, bool autofree = true); /***** Overridden members *****/ virtual bool isok(); virtual void commit(); virtual bool refresh(); virtual void flush_buffers() { } virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual WvString get(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); }; #endif // __UNIREPLICATEGEN_H wvstreams-4.6.1/include/wvtypetraits.h0000644000175000001440000000224411036722347017162 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Contains code you'd rather not think about. */ #ifndef __WVTYPETRAITS_H #define __WVTYPETRAITS_H #include "wvxplc.h" template struct WvTraits_Helper { static inline void maybe_addref(T* obj) { } static inline void release(T* obj) { delete obj; } }; template struct WvTraits_Helper { static inline void maybe_addref(T* obj) { obj->addRef(); } static inline void release(T* obj) { if (obj) obj->release(); } }; template class WvTraits { typedef char Yes; struct No { char dummy[2]; }; static From* from; static Yes test(IObject*); static No test(...); public: static inline void maybe_addref(From* obj) { const bool is_iobject = (sizeof(test(from)) == sizeof(Yes)); WvTraits_Helper::maybe_addref(obj); } static inline void release(From* obj) { const bool is_iobject = (sizeof(test(from)) == sizeof(Yes)); WvTraits_Helper::release(obj); } }; #endif /* __WVTYPETRAITS_H */ wvstreams-4.6.1/include/wvqthook.h0000644000175000001440000000221311036722347016253 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A Qt object that invokes its callback whenever it receives * an event. This is useful for deferring processing to the * Qt event loop. Use it to avoid problems resulting from the * non-reentrant nature of WvStream::execute(). */ #ifndef __WVQTHOOK_H #define __WVQTHOOK_H #include #include #include "wvtr1.h" class WvQtHook; // parameters are: WvQtHook &, int type, void *data typedef wv::function WvQtHookCallback; class WvQtHook : public QObject { Q_OBJECT WvQtHookCallback callback; public: WvQtHook(WvQtHookCallback _callback = NULL); // sets the callback function to be invoked void setcallback(WvQtHookCallback _callback); // posts an event to the Qt event loop to be sent to the // attached callback later void post(int type = 0, void *data = NULL); // sends an event to the attached callback now void send(int type = 0, void *data = NULL); // internal virtual bool event(QEvent *event); }; #endif // __WVQTHOOK_H wvstreams-4.6.1/include/wvbase64.h0000644000175000001440000000257311036722347016043 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Base64 encoder and decoder implementations. */ #ifndef __WVBASE64_H #define __WVBASE64_H #include "wvencoder.h" /** * A base 64 encoder. * * On finish(), outputs any needed pad characters. * * Supports reset(). * */ class WvBase64Encoder : public WvEncoder { enum State { ATBIT0, ATBIT2, ATBIT4 }; State state; unsigned int bits; // remaining bits shifted left 8 bits public: /** Creates a base 64 encoder. */ WvBase64Encoder(); virtual ~WvBase64Encoder() { } protected: // on flush, outputs any needed pad characters virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _finish(WvBuf &out); virtual bool _reset(); // supported }; /** * A base 64 decoder. * * Becomes isfinished() == true on detection of padding. * * Supports reset(). * */ class WvBase64Decoder : public WvEncoder { enum State { ATBIT0, ATBIT2, ATBIT4, ATBIT6, PAD }; State state; unsigned int bits; // remaining bits shifted left 6 bits public: /** Creates a base 64 decoder. */ WvBase64Decoder(); virtual ~WvBase64Decoder() { } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported }; #endif // __WVBASE64_H wvstreams-4.6.1/include/iwvstream.h0000644000175000001440000001416711044160724016417 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * The basic streaming I/O interface. */ #ifndef __IWVSTREAM_H #define __IWVSTREAM_H #include "wvbuf.h" #include "wverror.h" #include "wvtr1.h" #include "wvxplc.h" class WvAddr; class WvStream; /* The stream gets passed back as a parameter. */ typedef wv::function IWvStreamCallback; typedef unsigned int WSID; class IWvStream : public WvErrorBase, public IObject { public: static IWvStream *create(WvStringParm moniker, IObject *obj = NULL); /** * A SelectRequest is a convenient way to remember what we want to do * to a particular stream: read from it, write to it, or check for * exceptions. */ struct SelectRequest { bool readable, writable, isexception; SelectRequest() { } SelectRequest(bool r, bool w, bool x = false) { readable = r; writable = w; isexception = x; } SelectRequest &operator |= (const SelectRequest &r) { readable |= r.readable; writable |= r.writable; isexception |= r.isexception; return *this; } }; /** * the data structure used by pre_select()/post_select() and internally * by select(). */ struct SelectInfo { fd_set read, write, except; // set by pre_select, read by post_select SelectRequest wants; // what is the user looking for? int max_fd; // largest fd in read, write, or except time_t msec_timeout; // max time to wait, or -1 for forever bool inherit_request; // 'wants' values passed to child streams bool global_sure; // should we run the globalstream callback }; IWvStream(); virtual ~IWvStream(); virtual void close() = 0; virtual bool isok() const = 0; virtual void callback() = 0; // FIXME: these really have no place in the interface... virtual int getrfd() const = 0; virtual int getwfd() const = 0; // FIXME: evil, should go away (or be changed to localaddr/remoteaddr) virtual const WvAddr *src() const = 0; // needed for select(). // Some say that pre_select() should go away. virtual void pre_select(SelectInfo &si) = 0; virtual bool post_select(SelectInfo &si) = 0; // these are now the official way to get/put data to your stream. // The old uread() and uwrite() are just implementation details! virtual size_t read(void *buf, size_t count) = 0; virtual size_t write(const void *buf, size_t count) = 0; // FIXME: these are the new fancy versions, but WvBuf needs to have // a safely abstracted interface class (IWvBuf) before IWvStream will // really be safe, if we include these. virtual size_t read(WvBuf &outbuf, size_t count) = 0; virtual size_t write(WvBuf &inbuf, size_t count = INT_MAX) = 0; /** * Shuts down the reading side of the stream. This is the opposite * of nowrite(), but the name is actually slightly misleading; subsequent * calls to read() *might not* fail; rather, if the other end of the * connection tries to write to us, they should fail. * * After noread(), if the read buffer (if any) is empty once, we promise * that it will never refill. * * If you call both noread() and nowrite(), then the stream does close() * automatically once all buffers are empty. */ virtual void noread() = 0; /** * Shuts down the writing side of the stream. * Subsequent calls to write() will fail. But if there's data in the * output buffer, it will still be flushed. * * If you call both noread() and nowrite(), then the stream does close() * automatically once all buffers are empty. */ virtual void nowrite() = 0; /** * Auto-close the stream if the time is right. If noread() and nowrite() * and all buffers are empty, then we can probably close. */ virtual void maybe_autoclose() = 0; /** Returns true if the stream is readable. */ virtual bool isreadable() = 0; /** Returns true if the stream is writable (without using the outbuf). */ virtual bool iswritable() = 0; /** * flush the output buffer, if we can do it without delaying more than * msec_timeout milliseconds at a time. (-1 means wait forever) * * Returns true if it finished flushing (ie. the outbuf is empty). * * FIXME: Something like this probably belongs in IWvStream, but * probably not exactly this. */ virtual bool flush(time_t msec_timeout) = 0; /** * Returns true if we want to flush the output buffer right now. This * allows us to implement delayed_flush(), flush_then_close(), etc, but * it's still super-ugly and probably needs to go away. (In fact, all * our buffer flushing is super-ugly right now.) */ virtual bool should_flush() = 0; /* * WARNING: these don't work as expected! */ /** Sets a callback to be invoked when the stream is readable. */ virtual IWvStreamCallback setreadcallback(IWvStreamCallback _callfunc) = 0; /** Sets a callback to be invoked when the stream is writable. */ virtual IWvStreamCallback setwritecallback(IWvStreamCallback _callfunc) = 0; /** Sets a callback to be invoked when the stream is in exception * state. */ virtual IWvStreamCallback setexceptcallback(IWvStreamCallback _callfunc) = 0; /* * END WARNING */ /** Sets a callback to be invoked on close(). */ virtual IWvStreamCallback setclosecallback(IWvStreamCallback _callfunc) = 0; /* Stream identification/debugging */ virtual const char *wsname() const = 0; virtual void set_wsname(WvStringParm name) = 0; virtual const char *wstype() const = 0; // This is not static due to, eg, WvStreamClone virtual WSID wsid() const = 0; /** ** set the maximum size of outbuf, beyond which a call to write() will ** return 0. **/ virtual void outbuf_limit(size_t size) = 0; virtual WvString getattr(WvStringParm name) const = 0; }; DEFINE_IID(IWvStream, {0x7ca76e98, 0xb653, 0x43d7, {0xb0, 0x56, 0x8b, 0x9d, 0xde, 0x9a, 0xbe, 0x9d}}); #endif /* __IWVSTREAM_H */ wvstreams-4.6.1/include/unislowgen.h0000644000175000001440000000317511036722347016573 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen that makes everything slow. */ #ifndef __UNISLOWGEN_H #define __UNISLOWGEN_H #include "unifiltergen.h" /** * A UniConfGen that counts all "potentially synchronous" (ie. slow) * operations, so you'll know for sure if you're calling UniConf synchronous * operations when you shouldn't be. Hint: wrapping this one in a * UniCacheGen is supposed to cut slow operations to a bare minimum, so a * good test is to try a moniker like this: * * cache:slow:tcp:localhost * * ...and see if everything still works but there are no slow operations. * * (A previous version of this used to actually make things slow by doing * a deliberate sleep() on synchronous operations, but that wasn't really * needed. Now it just logs them instead.) */ class UniSlowGen : public UniFilterGen { public: UniSlowGen(IUniConfGen *inner); virtual ~UniSlowGen(); virtual void commit(); virtual bool refresh(); virtual void flush_buffers() { } virtual WvString get(const UniConfKey &key); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); int how_slow() const { return slowcount; } void reset_slow() { slowcount = 0; } private: int slowcount; void be_slow(WvStringParm what); void be_slow(WVSTRING_FORMAT_DECL) { be_slow(WvString(WVSTRING_FORMAT_CALL)); } }; #endif //__UNISLOWGEN_H wvstreams-4.6.1/include/wvlinklist.h0000644000175000001440000002757511057766345016632 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A linked list container. */ #ifndef __WVLINKLIST_H #define __WVLINKLIST_H #include "wvtypetraits.h" #include "wvsorter.h" /** * @internal * The untyped base class of WvList. * * Putting common code in here allows us to prevent it from being * replicated by each template instantiation of WvList. * */ class WvListBase { WvListBase(const WvListBase &l); // copy constructor - not actually defined anywhere! private: //This is private to force people to pass by reference, not by value WvListBase& operator= (const WvListBase &l); public: WvLink head, *tail; /** Creates an empty linked list. */ WvListBase() : head(NULL, false) { tail = &head; } /** * Returns the number of elements in the list. * * This function causes a full traversal of the list which may be * overly inefficient depending on how and when it is used. * * Returns: the number of elements */ size_t count() const; /** * Reverses the order of elements in the list. * * This function traverses the list and rearranges the pointers * and updates the pointers to head & tail appropriately. * * It does nothing for lists of count<2 */ void reverse(); /** * Quickly determines if the list is empty. * * This is much faster than checking count() == 0. * * Returns: true if empty */ bool isempty() const { return head.next == NULL; } /** * @internal * The untyped base class of WvList::Iter. * * Putting common code in here allows us to prevent it from being * replicated by each template instantiation of WvList. * */ class IterBase { public: const WvListBase *list; WvLink *link, *prev; /** * Binds the iterator to the specified list. * "l" is the list */ IterBase(const WvListBase &l) { list = &l; link = NULL; } /** * Rewinds the iterator to make it point to an imaginary element * preceeding the first element of the list. */ void rewind() // dropping a const pointer here! Danger! { prev = NULL; link = &((WvListBase *)list)->head; } /** * Moves the iterator along the list to point to the next element. * * If the iterator had just been rewound, it now points to the * first element of the list. * * Returns: the current WvLink pointer, or null if there were no * more elements remaining in the traversal sequence */ WvLink *next() { prev = link; return link = link->next; } /** * Returns a pointer to the WvLink at the iterator's current location. * Returns: the current WvLink pointer, or null if there were no * more elements remaining in the traversal sequence */ WvLink *cur() const { return link; } /** * Returns a void pointer to the object at the iterator's current * location. You should almost never need this. Use ptr() instead. */ void *vptr() const { return link->data; } /** * Rewinds the iterator and repositions it over the element that * matches the specified value. * * Uses pointer equality (object identity) as the criteria for * finding the matching element. * * In order to locate multiple matching elements, first call find() * and then use find_next(). * * Returns: the current WvLink pointer, or null if no such element * was found */ WvLink *find(const void *data); /** * Repositions the iterator over the element that matches the * specified value. * * Uses pointer equality (object identity) as the criteria for * finding the matching element. * * Returns: the current WvLink pointer, or null if no such element * was found */ WvLink *find_next(const void*data); }; }; /** * A linked list container class. * * Some rather horrible macros are used to declare actual concrete * list types. * * Example: * * DeclareWvList(WvString); * * int main() * { * WvStringList l; * WvStringList::Iter i(l); * * ... fill the list ... * * i.rewind(); * while (i.next()) * printf("%s\\n", i.str); * } * * * Deallocating list will free all of the WvLinks in the list, but * will only free the user objects that were added with autofree * set to true. * * We need to malloc memory for each WvLink as well as the data it * stores; this is unnecessarily slow. I would rather have made a * base "Link" class for object types that could be stored as links * in a list, and then used object->next instead of all the * List Iterator stuff, but the end result was pure ugliness, so I * gave up. At least this way, the same object can be in multiple * lists. * * List type construction is facilitated by the following macros: * * - DeclareWvList(Type): creates a subclass named TypeList * that contains pointers to Type. * - DeclareWvList2(name, Type): as the above, but calls the * resulting class by the specified name. * * * "T" is the object type */ template class WvList : public WvListBase { // copy constructor: not defined anywhere! WvList(const WvList &list); public: /** Creates an empty linked list. */ WvList() { } /** * Destroys the linked list. * * Destroys any elements that were added with autofree == true. * */ ~WvList() { zap(); } /** Invoked by subclasses after the linked list is first created. */ void setup() {} /** Invoked by subclasses before the linked list is destroyed. */ void shutdown() {} /** * Clears the linked list. * * If destroy is true, destroys any elements that were added with autofree == true. * */ void zap(bool destroy = true) { while (head.next) unlink_after(& head, destroy); } /** * Returns a pointer to the first element in the linked list. * * The list must be non-empty. * * Returns: the element pointer, possibly null */ T *first() const { return (T*)head.next->data; } /** * Returns a pointer to the last element in the linked list. * * The list must be non-empty. * * Returns: the element pointer, possibly null */ T *last() const { return (T*)tail->data; } /** * Adds the element after the specified link in the list. * * "link" is the link preceeding the desired location of the element * to be inserted, non-null * "data" is the element pointer, may be null * "autofree" is if true, takes ownership of the element * "id" is an optional string to associate with the element, or null */ void add_after(WvLink *after, T *data, bool autofree, const char *id = NULL ) { (void)new WvLink((void *)data, after, tail, autofree, id); } /** * Appends the element to the end of the list. * * "data" is the element pointer, may be null * "autofree" is if true, takes ownership of the element * "id" is an optional string to associate with the element, or null */ void append(T *data, bool autofree, const char *id = NULL) { add_after(tail, data, autofree, id); } /** * Synonym for append(T*, bool, char*). * @see append(T*, bool, char*) */ void add(T *data, bool autofree, const char *id = NULL) { append(data, autofree, id); } /** * Prepends the element to the beginning of the list. * * "data" is the element pointer, may be null * "autofree" is if true, takes ownership of the element * "id" is an optional string to associate with the element, or null */ void prepend(T *data, bool autofree, const char *id = NULL) { add_after(&head, data, autofree, id); } /** * Unlinks the specified element from the list. * * Destroys the element if it was added with autofree == true. * * "data" is the element pointer, may be null */ void unlink(T *data) { Iter i(*this); while (i.find(data)) i.unlink(); } /** * Unlinks the first element from the list. * * Destroys the element if it was added with autofree == true. * */ void unlink_first() { if(head.next != NULL) { Iter i(*this); i.rewind(); i.next(); i.unlink(); } } /** * Unlinks the element that follows the specified link in the list. * * Destroys the element if it was added with autofree == true and * destroy == true. * * "after" is the link preceeding the element to be removed, non-null */ void unlink_after(WvLink *after, bool destroy = true) { WvLink *next = after->next; if(next != NULL) { T *obj = (destroy && next->get_autofree()) ? static_cast(next->data) : NULL; if (next == tail) tail = after; next->unlink(after); if (obj) WvTraits::release(obj); } } /** * The iterator type for linked lists. * * An iterator instance does not initially point to any valid * elements in a list. Before using, it must be reset using rewind() * which causes it to point to an imaginary element located before * the first elements in the list. Then next() must be invoked * to incrementally move the iterator along the list to first element, * and then later to the second, third, and subsequent elements. * */ class Iter : public WvListBase::IterBase { public: /** * Binds the iterator to the specified list. * "l" is the list */ Iter(const WvList &l) : IterBase(l) { } /** * Returns a pointer to the current element. * Returns: the element pointer, possibly null */ T *ptr() const { return (T *)link->data; } WvIterStuff(T); /** * Returns the state of autofree for the current element. */ bool get_autofree() const { return link->get_autofree(); } /** * Sets the state of autofree for the current element. */ void set_autofree(bool autofree) { link->set_autofree(autofree); } /** * Unlinks the current element from the list and automatically * increments the iterator to point to the next element as if * next() had been called. */ void unlink(bool destroy = true) { if (prev) ((WvList *)list)->unlink_after(prev, destroy); link = prev->next; } /** * Unlinks the current element from the list but unlike unlink() * automatically returns the iterator to the previous link in * the list such that next() must be called to obtain the * next element. * * This version allows for writing neater loop structures since * an element can be unlinked in mid-traversal while still allowing * the iterator to be incremented at the top of the loop as usual. * * Calling xunlink() twice in a row is currently unsupported. * */ void xunlink(bool destroy = true) { if (prev) ((WvList *)list)->unlink_after(prev, destroy); link = prev; } }; /** The sorted iterator type for linked lists. */ typedef class WvSorter Sorter; }; #define DeclareWvList2(_classname_, _type_) \ typedef class WvList<_type_> _classname_ #define DeclareWvList(_type_) DeclareWvList2(_type_##List, _type_) #endif // __WVLINKLIST_H wvstreams-4.6.1/include/wvlogrcv.h0000644000175000001440000000640411036722347016250 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Enhanced "Log Receiver" classes for WvLog. * * WvLogRcv-derived classes support automatic formatting of log lines with * a prefix, removing control characters, and so on. * * WvLogRcv supports partial- and multiple-line log messages. For example, * log.print("test "); * log.print("string\nfoo"); * will print: * appname(lvl): test string * appname(lvl): foo */ #ifndef __WVLOGRCV_H #define __WVLOGRCV_H #include "wvlog.h" #include "wvfdstream.h" #include "wvscatterhash.h" /** * WvLogRcv adds some intelligence to WvLogRcvBase, to keep * track of line-prefix-printing and other formatting information. */ class WvLogRcv : public WvLogRcvBase { protected: WvString last_source; WvLog::LogLevel max_level, last_level; time_t last_time; bool at_newline; WvString prefix; size_t prelen; class Src_Lvl { public: WvString src; WvLog::LogLevel lvl; Src_Lvl(WvString _src, int _lvl) : src(_src), lvl((WvLog::LogLevel)_lvl) {}; }; DeclareWvScatterDict(Src_Lvl, WvString, src); Src_LvlDict custom_levels; /** Set the Prefix and Prefix Length (size_t prelen) */ virtual void _make_prefix(time_t now); /** Start a new log line (print prefix) */ virtual void _begin_line(); /** End this (Guaranteed NonEmpty) log line */ virtual void _end_line(); /** * add text to the current log line. 'str' may contain only * one '\n' optional character at str[len-1] (the end); if it does, * end_line will be called immediately after this function. */ virtual void _mid_line(const char *str, size_t len) = 0; private: void begin_line() { if (!at_newline) return; _begin_line(); at_newline = false; } void mid_line(const char *str, size_t len) { _mid_line(str, len); if (len>0 && str[len-1] == '\n') at_newline = true; } public: virtual void log(WvStringParm source, int loglevel, const char *_buf, size_t len); static const char *loglevels[WvLog::NUM_LOGLEVELS]; WvLogRcv(WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvLogRcv(); void end_line() { if (at_newline) return; _mid_line("\n", 1); _end_line(); at_newline = true; }; WvLog::LogLevel level() const { return max_level; } void level(WvLog::LogLevel lvl) { max_level = lvl; } /* * Allows you to override debug levels for specific sources * example: mysql=9,Service Manager=9 * will get all the debug output from all the sources that * contain (case insensitively) "mysql" or "Service Manager" * in the source name regardless of the current debug level. */ bool set_custom_levels(WvString descr); }; /** * Captures formatted log messages and outputs them to the * specified file descriptor. */ class WvLogConsole : public WvFDStream, public WvLogRcv { public: WvLogConsole(int _fd, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvLogConsole(); protected: virtual void _mid_line(const char *str, size_t len); }; #endif // __WVLOGRCV_H wvstreams-4.6.1/include/wvdbusmsg.h0000644000175000001440000002117111202637403016407 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * * WvDBusMsg is intended to be an easy-to-use abstraction over the low-level * D-Bus DBusMessage structure. It represents a message being passed around on * the bus. */ #ifndef __WVDBUSMSG_H #define __WVDBUSMSG_H #include "wvstringlist.h" #include "wvbuf.h" #include struct DBusMessageIter; struct DBusMessage; class WvDBusMsg; class WvDBusConn; class WvDBusMsg { public: /** * Constructs a new WvDBus message. If destination is blank, no * destination is set; this is appropriate when using D-BUS in a * peer-to-peer context (no message bus). */ WvDBusMsg(WvStringParm busname, WvStringParm objectname, WvStringParm ifc, WvStringParm method); /** * Constructs a new WvDBus message, copying it out of an old one. */ WvDBusMsg(WvDBusMsg &_msg); /** * Constructs a new WvDBus message from an existing low-level D-Bus * message. */ WvDBusMsg(DBusMessage *_msg); virtual ~WvDBusMsg(); operator DBusMessage* () const; /** * Demarshals a new WvDBusMsg from a buffer containing its binary DBus * protocol representation. You're responsible for freeing the object * when done. Returns NULL if the object can't be extracted from the * buffer. * (Implementation in wvdbusmarshal.cc) */ static WvDBusMsg *demarshal(WvBuf &buf); /** * Given a buffer containing what might be the header of a DBus message, * checks how many bytes need to be in the buffer in order for it to * contain a whole message. If the return value is <= the number of * bytes already in the buffer, then demarshal() will succeed (or the * incoming message is corrupt). * (Implementation in wvdbusmarshal.cc) */ static size_t demarshal_bytes_needed(WvBuf &buf); /** * Locks this message, encodes it in DBus binary protocol format, and * adds it to the given buffer. This message becomes locked and can * no longer be append()ed to. You can marshal it more than once, * however (but it will always have the same serial number!!) * (Implementation in wvdbusmarshal.cc) */ void marshal(WvBuf &buf); WvString get_sender() const; WvString get_dest() const; WvString get_path() const; WvString get_interface() const; WvString get_member() const; WvString get_error() const; uint32_t get_serial() const; uint32_t get_replyserial() const; bool is_reply() const; operator WvString() const; void get_arglist(WvStringList &list) const; WvString get_argstr() const; /** * The following methods are designed to allow appending various * arguments to the message. */ WvDBusMsg &append(const char *s); WvDBusMsg &append(bool b); WvDBusMsg &append(signed char c); WvDBusMsg &append(unsigned char c); WvDBusMsg &append(int16_t i); WvDBusMsg &append(uint16_t i); WvDBusMsg &append(int32_t i); WvDBusMsg &append(uint32_t i); WvDBusMsg &append(int64_t i); WvDBusMsg &append(uint64_t i); WvDBusMsg &append(double d); /** * Start a variant. */ WvDBusMsg &variant_start(WvStringParm element_type); /** * End a variant. */ WvDBusMsg &variant_end(); /** * Start a struct. Elements append()ed after this will be inside the * struct, and you should be careful that you append the right types in * the right order. Finish using struct_end(). */ WvDBusMsg &struct_start(WvStringParm element_type); /** * End a struct started with struct_start(). */ WvDBusMsg &struct_end(); /** * Start an array. Elements append()ed after this will be inside the * array. Finish using array_end(). */ WvDBusMsg &array_start(WvStringParm element_type); /** * End an array started with array_start(). */ WvDBusMsg &array_end(); /** * Start a variant-array. Elements append()ed after this will be inside * the array. Finish using varray_end(). * * A variant-array is like an array, but is enclosed automatically inside * a variant object. This is useful for arrays of arrays, where each * inner array is of a different type. */ WvDBusMsg &varray_start(WvStringParm element_type); /** * End an array started with array_start(). */ WvDBusMsg &varray_end(); /** * Generate a message that will be a reply to this one. */ WvDBusMsg reply(); /** * Return true if this message is an error response. */ bool iserror() const; /** * A shortcut for sending this message on the given connection. * Equivalent to conn.send(*this). */ void send(WvDBusConn &conn); class Iter { public: DBusMessageIter *const first, *const it; mutable WvString s; bool rewound; Iter(const WvDBusMsg &_msg); Iter(const WvDBusMsg::Iter &_it); Iter(const DBusMessageIter &_first); ~Iter(); /** * Rewinds the iterator to make it point to an imaginary element * preceeding the first element of the list. */ void rewind(); /** * Returns the data type of the current element. Not usually needed, * as the iterator converts elements automatically between most types. */ int type() const; /** * Returns a sub-iterator for walking through recursive types, such * as arrays, structs, and variants. * * You don't strictly need to call this for variants; get_str() and * friends will do the right thing. */ Iter open() const; /** * Moves the iterator along the list to point to the next element. * * If the iterator had just been rewound, it now points to the * first element of the list. */ bool next(); /** * Same as next(), but returns *this instead so you can convert the * new item to the right value type. Note: this doesn't do error * checking to see if the parameter exists. */ Iter &getnext() { next(); return *this; } /** * Returns: true if the current link is valid */ bool cur() const; /** * Fill a WvStringList with a string for each element of the iter. */ void get_all(WvStringList &list); /** * Return a WvString representation of all elements in a single * string. */ WvString get_all(); /** * Get the current element as a string (possible for all types). */ WvString get_str() const; /** * Get the current element as an int64_t * (possible for all integer types) */ int64_t get_int() const; operator int64_t() const { return get_int(); } operator int32_t() const { return get_int(); } operator int16_t() const { return get_int(); } operator int8_t() const { return get_int(); } operator bool() const { return get_int() != 0; } /** * Get the current element as a uint64_t * (possible for all integer types) */ uint64_t get_uint() const; operator uint64_t() const { return get_uint(); } operator uint32_t() const { return get_uint(); } operator uint16_t() const { return get_uint(); } operator uint8_t() const { return get_uint(); } /** * Get the current element as a double * (possible for all integer and floating point types) */ double get_double() const; operator double() const { return get_double(); } operator float() const { return get_double(); } /** * Returns a pointer to the WvString at the iterator's current * location. Needed so that WvIterStuff() will work. */ WvString *ptr() const; operator WvString() const { return *ptr(); } WvIterStuff(WvString); }; protected: mutable DBusMessage *msg; WvList itlist; }; class WvDBusSignal : public WvDBusMsg { public: WvDBusSignal(WvStringParm objectname, WvStringParm ifc, WvStringParm name); }; class WvDBusError : public WvDBusMsg { DBusMessage *setup1(WvDBusMsg &in_reply_to, WvStringParm errname, WvStringParm message); void setup2(); public: WvDBusError(WvDBusMsg &in_reply_to, WvStringParm errname, WvStringParm message) : WvDBusMsg(setup1(in_reply_to, errname, message)) { setup2(); } WvDBusError(WvDBusMsg &in_reply_to, WvStringParm errname, WVSTRING_FORMAT_DECL) : WvDBusMsg(setup1(in_reply_to, errname, WvString(WVSTRING_FORMAT_CALL))) { setup2(); } }; #endif // __WVDBUSMSG_H wvstreams-4.6.1/include/wvencoderstream.h0000644000175000001440000001273011036722347017606 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * An stream wrapper for encoders. */ #ifndef __WVENCODERSTREAM_H #define __WVENCODERSTREAM_H #include "wvstream.h" #include "wvstreamclone.h" #include "wvencoder.h" /** * WvEncoderStream chains a series of encoders on the input and * output ports of the underlying stream to effect on-the-fly data * transformations. * * Notice that the value of WvEncoderStream's auto_flush flag becomes * important when working with encoders that treat explicit buffer * flushing in a special manner. For instance, on flush() the Gzip * encoder synchronizes its output. Were auto_flush to remain true, * each incremental write to the stream would cause the Gzip encoder * to flush its dictionary thereby resulting in poor compression. * * See WvStream::auto_flush(bool). * * WARNING: it is possible to add to the readchain and/or writechain in the * middle of a session, for example to add gzip compression after first * negotiating it with the remote end. If you plan to do this, be very * careful with buffering. Never read() or getline() more bytes than * you're sure will exist with the old encoding. Even then, only ever * append things to the readchain, not prepend. (Therefore only prepend * things to the writechain.) Always flush() or flush_write() before * adding to the writechain. See also min_readsize. */ class WvEncoderStream : public WvStreamClone { bool is_closing; WvDynBuf readinbuf; WvDynBuf readoutbuf; WvDynBuf writeinbuf; //WvDynBuf writeoutbuf; public: /** Encoder chain through which input data is passed. */ WvEncoderChain readchain; /** Encoder chain through which output data is passed. */ WvEncoderChain writechain; /** * Controls the minimum number of unencoded bytes the encoder * should try to read at once from the underlying stream, * to optimize performance of block-oriented protocols. * This is not the same as queuemin() which guarantees how much * encoded input must be generated before select() returns true. * if 0, the encoder will only read whatever is specified in uread(). * * NOTE: if you plan to append a new encoder to the readchain after * doing read(), you should always use read() with only 1 byte at a * time, or some extra data will end up in inbuf and not pass through * the newly- added encoder. Remember that getline() also calls * read(). The purpose of min_readsize is to make these one-byte * read() calls more efficient, because the *underlying* stream can * still read lots of bytes, as long as we only pass single bytes down * to the WvEncoderStream. * * If you don't plan to add new encoders to readchain from now on, you * can give larger sizes to read() or getline(), and thus min_readsize * is unnecessary. */ size_t min_readsize; /** * Creates an encoder stream. * * "cloned" is the stream to wrap */ WvEncoderStream(WvStream *cloned); virtual ~WvEncoderStream(); /** * Safely shuts down the stream. * * Does the following in sequence: * * - Flushes and finishes the read chain * - Flushes and finishes the write chain * - Flushes the stream output buffers * - Closes the underlying stream */ virtual void close(); /** * Flushes the read chain through to the stream's input buffer. * * The regular stream flush() only operates on the write chain. * * Returns: true if the encoder chain returned true */ bool flush_read(); /** * Flushes the write chain through to the stream's output buffer. * * The regular stream flush() invokes this, then attempts to * synchronously push the buffered data to the stream, which * may not always be desirable since it can be quite costly. * * To simply cause the write chain to be flushed but allow * WvStreams to drain the encoded output buffer at its leisure, * use this function. * * Returns: true if the encoder chain returned true */ bool flush_write(); /** * Calls flush() then finish() on the read chain of encoders. * * Returns: true if the encoder chain returned true */ bool finish_read(); /** * Calls flush() then finish() on the write chain of encoders. * * Does not flush() the stream. * * Returns: true if the encoder chain returned true. */ bool finish_write(); /** * Defines isok() semantics for encoders. * * Returns false on error or after all data has been read from * the internal buffers and readchain.isfinished() or * ! writechain.isok(). * * Returns: true if it is still possible to read and write data */ virtual bool isok() const; virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); protected: void pre_select(SelectInfo &si); bool post_select(SelectInfo &si); virtual bool flush_internal(time_t msec_timeout); private: void checkreadisok(); void checkwriteisok(); // pulls a chunk of specified size from the underlying stream void pull(size_t size); // pushes a chunk to the underlying stream bool push(bool flush, bool finish); public: const char *wstype() const { return "WvEncoderStream"; } }; #endif // __WVENCODERSTREAM_H wvstreams-4.6.1/include/unimountgen.h0000644000175000001440000001007311036722347016744 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines a UniConfGen that manages a tree of UniConfGen instances. */ #ifndef __UNIMOUNTGEN_H #define __UNIMOUNTGEN_H #include "uniconfgen.h" #include "wvmoniker.h" #include "wvstringlist.h" #include "wvtr1.h" /** The UniMountTree implementation realized as a UniConfGen. */ class UniMountGen : public UniConfGen { protected: // Class to hold the generator with its mountpoint class UniGenMount { public: UniGenMount(IUniConfGen *gen, const UniConfKey &key) : gen(gen), key(key) { } xplc_ptr gen; UniConfKey key; }; typedef class WvList MountList; MountList mounts; /** undefined. */ UniMountGen(const UniMountGen &other); public: /** Creates an empty UniConf tree with no mounted stores. */ UniMountGen(); /** Destroys the UniConf tree along with all uncommitted data. */ virtual ~UniMountGen(); void zap(); /** * Mounts a generator at a key using a moniker. * Returns the generator instance pointer, or NULL on failure. */ virtual IUniConfGen *mount(const UniConfKey &key, WvStringParm moniker, bool refresh); /** * Mounts a generator at a key. * Takes ownership of the supplied generator instance. * * "key" is the key * "gen" is the generator instance * "refresh" is if true, refreshes the generator after mount * Returns: the generator instance pointer, or NULL on failure */ virtual IUniConfGen *mountgen(const UniConfKey &key, IUniConfGen *gen, bool refresh); /** * Unmounts the generator at a key and releases it. * * "gen" is the generator instance * "commit" is if true, commits the generator before unmount */ virtual void unmount(IUniConfGen *gen, bool commit); /** * Finds the generator that owns a key. * * If the key exists, returns the generator that provides its * contents. Otherwise returns the generator that would be * updated if a value were set. * * "key" is the key * "mountpoint" is if not NULL, replaced with the mountpoint * path on success * Returns: the handle, or a null handle if none */ virtual IUniConfGen *whichmount(const UniConfKey &key, UniConfKey *mountpoint); /** Determines if a key is a mountpoint. */ virtual bool ismountpoint(const UniConfKey &key); /***** Overridden members *****/ virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual void commit(); virtual bool refresh(); virtual void flush_buffers() { } virtual Iter *iterator(const UniConfKey &key); virtual Iter *recursiveiterator(const UniConfKey &key); private: /** Find the active generator for a given key. */ UniGenMount *findmount(const UniConfKey &key); /** Find a unique active generator a given key, will return NULL if * there are other generators beneath that key. */ UniGenMount *findmountunder(const UniConfKey &key); // Trim the key so it matches the generator starting point UniConfKey trimkey(const UniConfKey &foundkey, const UniConfKey &key) { return key.removefirst(foundkey.numsegments()); } /** Called by generators when a key changes. */ void gencallback(const UniConfKey &base, const UniConfKey &key, WvStringParm value); void makemount(const UniConfKey &key); /** Return true if the given key has a subkey * if you used findmount first, give the result as a parameter to * improve efficiency*/ bool has_subkey(const UniConfKey &key, UniGenMount *found = NULL); struct UniGenMountPairs; DeclareWvDict(UniGenMountPairs, WvFastString, key); }; #endif //__UNIMOUNTGEN_H wvstreams-4.6.1/include/wvdailyevent.h0000644000175000001440000000602011036722347017112 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A period event stream. */ #ifndef __WVDAILYEVENT_H #define __WVDAILYEVENT_H #include "wvstream.h" /** * A simple class that can trigger an event on a timed basis. * * The period may be specified the following ways: * * - Given an hour, triggers once per day, on that hour. * - Given a number of times per day, triggers that many times * per day, evenly, starting at the specified hour. * - WvDailyEvents can happen up to 1440 times a day, that is once per * minute, no more. * * * Presently has a one-hour granularity in the first case, but that * can be fixed someday when someone cares. * */ class WvDailyEvent : public WvStream /**********************************/ { public: /** * Constructs WvDailyEvent. * \param _first_hour the first hour of the day in which the event should * occur. * \param _num_per_day the number of times in a day that the event should * occur. * \param _skip_first indicates whether the first event should be skipped * or not, starting on the second is default. * If _num_per_day is not specified, it defaults to 0 (which is equivalent * to running the event once a day). */ WvDailyEvent( int _first_hour, int _num_per_day=0, bool _skip_first=true ); /** Munges SelectInfo such that the stream will select when the * time is right for the event to occur. * "The time is right" means that it is the first hour in some arbitrary * day that the event should occur or it is the first hour + * (number-of-minutes-in-a-day mod number of occurrences in a day) minutes * in some arbitrary day that the event should occur. */ virtual void pre_select( SelectInfo& si ); virtual bool post_select( SelectInfo& si ); /** * Modifies the first hour in which the event should occur and the number of * times the event should occur in a day. * \param _first_hour the first hour of the day in which the event should * occur. * \param _num_per_day the number of times in a day that the event should * occur. * If _num_per_day is not specified, it defaults to 0 (which is equivalent * to running the event once a day). */ void configure( int _first_hour, int _num_per_day=0, bool _skip_first=true ); /// Set number of times per day the event should occur - ONLY FOR TESTING! void set_num_per_day(int _num_per_day); /** * Modifies the first hour in which the event should occur and leaves the * number of times per day unmodified. */ void set_hour( int h ) { configure( h, num_per_day ); } /// return the time when the next event will occur time_t next_event() const; private: int first_hour; int num_per_day; bool need_reset; bool skip_first; time_t prev; time_t not_until; public: const char *wstype() const { return "WvDailyEvent"; } }; #endif wvstreams-4.6.1/include/wvcolorlogconsole.h0000644000175000001440000000212311036722347020151 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A version of WvLogConsole that colorizes output on terminals * which support ANSI color sequences */ #ifndef __WVCOLORLOGCONSOLE_H #define __WVCOLORLOGCONSOLE_H #include "wvlogrcv.h" /** * WvLogRcv adds some intelligence to WvLogRcvBase, to keep * track of line-prefix-printing and other formatting information. */ class WvColorLogConsole: public WvLogConsole { bool colorize; public: WvColorLogConsole(int _fd, WvLog::LogLevel _max_level = WvLog::NUM_LOGLEVELS); virtual ~WvColorLogConsole(); static bool is_tty(int fd); static bool can_colorize(int fd, const char *TERM); static const char *color_start_seq(WvLog::LogLevel log_level); static const char *clear_to_eol_seq(WvLog::LogLevel log_level); static const char *color_end_seq(WvLog::LogLevel log_level); protected: virtual void _begin_line(); virtual void _mid_line(const char *str, size_t len); virtual void _end_line(); }; #endif // __WVCOLORLOGCONSOLE_H wvstreams-4.6.1/include/iwvlistener.h0000644000175000001440000000307411036722347016752 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * An interface for "listeners", streams that spawn other streams from * (presumably) incoming connections. */ #ifndef __IWVLISTENER_H #define __IWVLISTENER_H #include "iwvstream.h" typedef wv::function IWvListenerCallback; typedef wv::function IWvListenerWrapper; class IWvListener : public IWvStream { public: static IWvListener *create(WvString moniker, IObject *obj = NULL); /** * Accept a connection from this stream. If none are available right now, * might return NULL or block. (NULL is preferable.) */ virtual IWvStream *accept() = 0; /** * Set a user-defined function to be called when a new connection is * available. The new connection IWvStream is given, and it's the * callback's responsibility to make sure it gets freed properly. */ virtual IWvListenerCallback onaccept(IWvListenerCallback _cb) = 0; /** * Add a wrapper function for this stream: something that accept() will * call to possibly wrap the stream from accept() before returning it. * You can use this more than once; the wrappers will be called in * order (so the "innermost" stream is the original, the first wrapper * is next, and so on). */ virtual void addwrap(IWvListenerWrapper _wrapper) = 0; }; DEFINE_IID(IWvListener, {0xe7c2433a, 0x6d5c, 0x4345, {0x83, 0xee, 0xc0, 0x0f, 0xa7, 0xe3, 0x08, 0xeb}}); #endif // __IWVLISTENER_H wvstreams-4.6.1/include/wvtundev.h0000644000175000001440000000167011036722347016261 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A tun device wrapper. */ #ifndef __WV_TUNDEV_H #define __WV_TUNDEV_H #include "wvfile.h" #include "wvinterface.h" #include "wvaddr.h" /** * WvTunDev provides a convenient way of using Linux tunnel devices. * * If you don't have the /dev/net/tun device, try doing: * mknod /dev/net/tun c 10 200. * */ class WvTunDev : public WvFile { public: /** * Creates a tunnel device and its associated interface. * * "addr" is the initial ip address for the interface * "mtu" is the max transfer unit, default 1400 */ WvTunDev(const WvIPNet &addr, int mtu = 1400); /** Contains the name of the interface associated with the device. */ WvString ifcname; private: void init(const WvIPNet &addr, int mtu); public: const char *wstype() const { return "WvTunDev"; } }; #endif wvstreams-4.6.1/include/pwvstream.h0000644000175000001440000000463311036722347016431 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #ifndef __PWVSTREAM_H #define __PWVSTREAM_H #include "iwvstream.h" #include "wvstream.h" // FIXME: don't include this! #include "wvstreamclone.h" // FIXME: don't include this! #include "wvmoniker.h" #include "wvtr1.h" /** * PWvStream is a smart pointer to an IWvStream object. It is designed for * maximum ABI-stability. Even though individual WvStream-derived classes * might change their size and object layout, if you create, destroy, and * access them using PWvStream and IWvStream, you should be safe. * * Note that this class is entirely inlined. PWvStream's object layout may * change at any time, so you shouldn't pass it around between modules; pass * around IWvStream objects instead (perhaps from PWvStream::addRef()). That * way people using two different versions of PWvStream will still be able * to interoperate. * * FIXME: * PWvStream is incomplete, so it does not yet give the required level of ABI * stability. Things to do: * * - Remove all references to classes, using only interfaces. That means * no WvStream or WvStreamClone, only IWvStream. IWvStream might have * to change (or introduce a new IWvBufStream) to make this work. * * - Definitely don't rely on C++ RTTI here. */ class PWvStream : public wv::shared_ptr { static WvStream *clean_stream(IWvStream *s) { WvStream *ss = dynamic_cast(s); if (ss) return ss; else return new WvStreamClone(s); } static WvStream *make_stream(WvStringParm moniker, IObject *obj) { IWvStream *s = IWvStream::create(moniker, obj); if (!s) s = wvcreate("null:"); assert(s != NULL); return clean_stream(s); } public: PWvStream() { // Pointer points to NULL right now, but it could be reassigned // later using operator=(). } PWvStream(IWvStream *s) : wv::shared_ptr(clean_stream(s), wv::bind(&IWvStream::release, _1)) { } PWvStream(WvStringParm moniker, IObject *obj = 0) : wv::shared_ptr(make_stream(moniker, obj), wv::bind(&IWvStream::release, _1)) { // Note: pointer is definitely not NULL here, because make_stream is // careful. } WvStream *addRef() const { if (get()) get()->addRef(); return get(); } }; #endif // __PWVSTREAM_H wvstreams-4.6.1/include/wvstringcache.h0000644000175000001440000000305511036722347017245 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Definition for the WvStringCache class. */ #ifndef __WVSTRINGCACHE_H #define __WVSTRINGCACHE_H #include "wvstringtable.h" /** * A cache table of WvString objects. If you think you might be reusing * the same string objects over and over (for example, because the user * provides the same string value a million times in a config file you're * reading), you might be able to save a lot of memory by sharing the * strings via a WvStringCache. * * To potentially share a string, call get(string), throw away the input * string, and use the output string (which is guaranteed to have the same * content) in its place. The string will be saved in the cache table for * next time. * * Every once and a while, you should call clean() to remove any strings from * the table that are no longer referenced elsewhere. This is especially * important after deleting a large data structure, because you won't actually * free up the memory used by those strings until clean() is called. * * All WvStringCaches in the app are shared, to optimize the benefits of * the cache. */ class WvStringCache { static WvStringTable *t; static int refcount; static size_t clean_threshold; public: WvStringCache(); ~WvStringCache(); /** Get a shared string corresponding to 's'. */ WvString get(WvStringParm s); /** Remove any now-unused strings from the cache. */ void clean(); }; #endif // __WVSTRINGCACHE_H wvstreams-4.6.1/include/wvstring.h0000644000175000001440000003555211036722347016270 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of a simple and efficient printable-string class. * * It leaves out many of the notational conveniences provided by other * string classes, because they waste too much CPU time and space. * It does the one thing really missing from char* strings, that is, * dynamic buffer management. * * The 'str' member is the actual (char*) string. You should never * need to access it directly. */ #ifndef __WVSTRING_H #define __WVSTRING_H #include #include #include #include // no code is actually used from here /* 1 byte for terminating NUL */ #define WVSTRING_EXTRA 1 #define __WVS_F(n) WvStringParm __wvs_##n #define __WVS_FORM(n) WvStringParm __wvs_##n = WvFastString::null #define WVSTRING_FORMAT_DECL WvStringParm __wvs_format, \ WvStringParm __wvs_a0, \ __WVS_FORM( a1), __WVS_FORM( a2), __WVS_FORM( a3), \ __WVS_FORM( a4), __WVS_FORM( a5), __WVS_FORM( a6), \ __WVS_FORM( a7), __WVS_FORM( a8), __WVS_FORM( a9), \ __WVS_FORM(a10), __WVS_FORM(a11), __WVS_FORM(a12), \ __WVS_FORM(a13), __WVS_FORM(a14), __WVS_FORM(a15), \ __WVS_FORM(a16), __WVS_FORM(a17), __WVS_FORM(a18), \ __WVS_FORM(a19) #define WVSTRING_FORMAT_DEFN WvStringParm __wvs_format, \ WvStringParm __wvs_a0, \ __WVS_F( a1), __WVS_F( a2), __WVS_F( a3), \ __WVS_F( a4), __WVS_F( a5), __WVS_F( a6), \ __WVS_F( a7), __WVS_F( a8), __WVS_F( a9), \ __WVS_F(a10), __WVS_F(a11), __WVS_F(a12), \ __WVS_F(a13), __WVS_F(a14), __WVS_F(a15), \ __WVS_F(a16), __WVS_F(a17), __WVS_F(a18), \ __WVS_F(a19) #define WVSTRING_FORMAT_CALL __wvs_format, __wvs_a0, \ __wvs_a1, __wvs_a2, __wvs_a3, __wvs_a4, __wvs_a5, \ __wvs_a6, __wvs_a7, __wvs_a8, __wvs_a9, __wvs_a10, \ __wvs_a11, __wvs_a12, __wvs_a13, __wvs_a14, __wvs_a15, \ __wvs_a16, __wvs_a17, __wvs_a18, __wvs_a19 struct WvStringBuf; class WvFastString; class WvString; class QString; // for operator QString() class QCString; // all WvFastString objects are const - they should _only_ be created // automatically by automatic typecasting in parameter passing. So let's // create a handy alias. typedef const WvFastString & WvStringParm; struct WvStringBuf { size_t size; // string length - if zero, use strlen!! unsigned links; // number of WvStrings using this buf. char data[1]; // optional room for extra string data }; // the _actual_ space taken by a WvStringBuf, without the data[] array // (which is variable-sized, not really 1 byte) #define WVSTRINGBUF_SIZE(s) (s->data - (char *)s) /** * A WvFastString acts exactly like a WvString, but can take (const char *) * strings without needing to allocate any memory, thus making it faster. * * When we copy to a normal WvString object, _then_ we allocate the memory. * If that never happens, we never need to allocate. * * DON'T CREATE INSTANCES OF THIS! It's mostly useful for parameter passing, * and for that you should use WvStringParm. You can get yourself into _big_ * trouble if you have an instance of a WvFastString created from a (char *) * object and then you modify the original (char *). * * For almost all purposes, use WvString instead. At worst, it's a bit slower. */ class WvFastString { friend class WvString; // so WvString can access members of _other_ objects protected: WvStringBuf *buf; char *str; // WvStringBuf used for char* strings that have not been cloned. static WvStringBuf nullbuf; public: // a null string, converted to char* as "(nil)" static const WvFastString null; /** * Create an empty, NULL string. In the past, these were dangerous * and could only be filled with operator= or setsize(); nowadays, NULL * strings are explicitly allowed, since it's useful to express the * difference between a zero-length string and a NULL result. */ WvFastString(); void setsize(size_t i); /** * Returns a copy of string pointed i bytes into this. Will not make it point * past the trailing null byte. */ WvFastString offset(size_t i) const; /** * Copy constructor. We can safely copy from a normal WvString like this * too, since no special behaviour is required in this direction. (Note * that copying from a WvFastString to a WvString _does_ require special * care!) */ WvFastString(const WvFastString &s); WvFastString(const WvString &s); /** * Create a string out of a (char *)-style string _without_ copying any * memory. It's fast, but we have to trust that the _str won't change * for the lifetime of our WvFastString. That's usually safe, if you * didn't use WvFastString where you should have used a WvString. */ WvFastString(const char *_str); /** * Create a string out of a Qt library QString. If you use this, * you need to link with libwvqt.so. */ WvFastString(const QString &s); WvFastString(const QCString &s); /** * Create a string out of a stdc++ string. To use this, #include * wvstdstring.h. */ inline WvFastString(const std::string &s); /** * NOTE: make sure that 32 bytes is big enough for your longest * int. This is true up to at least 64 bits. */ WvFastString(short i); WvFastString(unsigned short i); WvFastString(int i); WvFastString(unsigned int i); WvFastString(long i); WvFastString(unsigned long i); WvFastString(long long i); WvFastString(unsigned long long i); WvFastString(double i); /** when this is called, we assume output.str == NULL; it will be filled. */ static void do_format(WvFastString &output, const char *format, const WvFastString * const *a); /** * Now, you're probably thinking to yourself: Boy, does this ever * look ridiculous. And indeed it does. However, it is * completely type-safe and when functions are enabled, it * reduces automatically to its minimum possible implementation. * (ie. all extra comparisons with wv_null go away if the * parameter really _is_ wv_null, and that is the default!) * * I failed to find a way to optimize out the comparisons for * parameters that _are_ provided, however. * * There is a small problem, which is that only up to 20 (numbers * 0 to 19) additional arguments are allowed. Luckily, no one has * ever used that many on one "printf"-type line in the history of * the world. */ WvFastString(WVSTRING_FORMAT_DECL) { const WvFastString *x[20]; x[ 0] = (&__wvs_a0 != &null)? &__wvs_a0 : 0; x[ 1] = (&__wvs_a1 != &null)? &__wvs_a1 : 0; x[ 2] = (&__wvs_a2 != &null)? &__wvs_a2 : 0; x[ 3] = (&__wvs_a3 != &null)? &__wvs_a3 : 0; x[ 4] = (&__wvs_a4 != &null)? &__wvs_a4 : 0; x[ 5] = (&__wvs_a5 != &null)? &__wvs_a5 : 0; x[ 6] = (&__wvs_a6 != &null)? &__wvs_a6 : 0; x[ 7] = (&__wvs_a7 != &null)? &__wvs_a7 : 0; x[ 8] = (&__wvs_a8 != &null)? &__wvs_a8 : 0; x[ 9] = (&__wvs_a9 != &null)? &__wvs_a9 : 0; x[10] = (&__wvs_a10 != &null)? &__wvs_a10 : 0; x[11] = (&__wvs_a11 != &null)? &__wvs_a11 : 0; x[12] = (&__wvs_a12 != &null)? &__wvs_a12 : 0; x[13] = (&__wvs_a13 != &null)? &__wvs_a13 : 0; x[14] = (&__wvs_a14 != &null)? &__wvs_a14 : 0; x[15] = (&__wvs_a15 != &null)? &__wvs_a15 : 0; x[16] = (&__wvs_a16 != &null)? &__wvs_a16 : 0; x[17] = (&__wvs_a17 != &null)? &__wvs_a17 : 0; x[18] = (&__wvs_a18 != &null)? &__wvs_a18 : 0; x[19] = (&__wvs_a19 != &null)? &__wvs_a19 : 0; link(&nullbuf, NULL); do_format(*this, __wvs_format.str, x); } ~WvFastString(); /* * Figure out the length of this string. ==0 if NULL or empty. */ size_t len() const; protected: void construct(const char *_str); // this doesn't exist - it's just here to keep it from being auto-created // by stupid C++. WvFastString &operator= (const WvFastString &s2); // connect/disconnect ourselves from a WvStringBuf. void link(WvStringBuf *_buf, const char *_str); void unlink(); // allocate new space for buffers - needed only by the (int i) constructor, // for now. WvStringBuf *alloc(size_t size); void newbuf(size_t size); public: // string comparison bool operator== (WvStringParm s2) const; bool operator!= (WvStringParm s2) const; bool operator< (WvStringParm s2) const; bool operator== (const char *s2) const; bool operator!= (const char *s2) const; bool operator< (const char *s2) const; /** the not operator is 'true' if string is empty */ bool operator! () const; // pointer arithmetic const char *operator+ (int i) const { return str + i; } const char *operator- (int i) const { return str - i; } /** auto-convert WvString to (const char *), when needed. */ operator const char*() const { return str; } /** * return a (const char *) for this string. The typecast operator does * this automatically when needed, but sometimes (especially with varargs * like in printf()) that isn't convenient enough. */ const char *cstr() const { return str; } /** * return a Qt library QString containing the contents of this string. * You need to link to libwvqt.so if you use this. */ operator QString() const; /** * Return a stdc++ string with the contents of this string. To use * this, #include wvstdstring.h. */ //inline operator std::string() const; /** * used to convert WvString to int, when needed. * we no longer provide a typecast, because it causes annoyance. */ int num() const { return str ? atoi(str) : 0; } /** returns true if this string is null */ bool isnull() const { return str == NULL; } /** returns either this string, or, if isnull(), the given string. */ const WvFastString &ifnull(WvStringParm defval) const { return isnull() ? defval : *this; } }; /** * WvString is an implementation of a simple and efficient * printable-string class. It leaves out many of the notational * conveniences provided by other string classes, because they waste * too much CPU time and space. * * It does the one thing really missing from char* strings, that is, * dynamic buffer management. * * When you copy one WvString to another, it does _not_ duplicate the * buffer; it just creates another pointer to it. To really duplicate * the buffer, call the unique() member function. * * To change the contents of a WvString, you need to run its edit() * member function, which executes unique() and then returns a char* * pointer to the WvString contents. * * The most annoying side-effect of this implementation is that if you * construct a WvString from a char* buffer or static string, WvString * won't duplicate it. Usually this is okay and much faster (for * example, if you just want to print a static string). However, if * you construct a WvString from a dynamic variable, changing the * dynamic variable will change the WvString unless you run unique() * or edit(). Worse still, deleting the dynamic variable will make * WvString act unpredictably. * * But it does cut out extra dynamic memory allocation for the most * common cases, and it almost always avoids manual 'new' and 'delete' * of string objects. */ class WvString : public WvFastString { public: // an empty string, converted to char* as "" static const WvString empty; WvString() {} // nothing special needed WvString(short i) : WvFastString(i) { } // nothing special WvString(unsigned short i) : WvFastString(i) { } // nothing special WvString(int i) : WvFastString(i) { } // nothing special WvString(unsigned int i) : WvFastString(i) { } // nothing special WvString(long i) : WvFastString(i) { } // nothing special WvString(unsigned long i) : WvFastString(i) { } // nothing special WvString(long long i) : WvFastString(i) { } // nothing special WvString(unsigned long long i) : WvFastString(i) { } // nothing special WvString(double i) : WvFastString(i) { } // nothing special /** * Magic copy constructor for "fast" char* strings. When we copy from * a "fast" string to a real WvString, we might need to allocate memory * (equivalent to unique()) so the original char* can be safely changed * or destroyed. */ WvString(const WvString &s) { copy_constructor(s); } WvString(const WvFastString &s) { copy_constructor(s); } /** * Create a WvString out of a char* string. We always allocate memory * and make a copy here. To avoid memory copies, you can (carefully) * use a WvFastString. To just have quick parameter passing, use a * WvStringParm instead. */ WvString(const char *_str); /** * Create a WvString out of a Qt library QString. You have to link with * libwvqt.so if you want to use this. */ WvString(const QString &); WvString(const QCString &); /** * Create a string out of a stdc++ string. To use this, #include * wvstdstring.h. */ inline WvString(const std::string &s); WvString(WVSTRING_FORMAT_DECL) : WvFastString(WVSTRING_FORMAT_CALL) { } WvString &append(WvStringParm s); WvString &append(WVSTRING_FORMAT_DECL) { return append(WvString(WVSTRING_FORMAT_CALL)); } WvString &operator= (int i); WvString &operator= (const WvFastString &s2); WvString &operator= (const char *s2) { return *this = WvFastString(s2); } /** make the buf and str pointers owned only by this WvString. */ WvString &unique(); /** returns true if this string is already unique() */ bool is_unique() const; /** make the string editable, and return a non-const (char*) */ char *edit() { return unique().str; } protected: void copy_constructor(const WvFastString &s); inline void construct(const char *_str) { link(&nullbuf, _str); // apenwarr (2002/04/24): from now on, all WvString objects are created // with unique(), so you should _never_ have to call it explicitly. We // still can (and should!) use fast parameter passing via WvFastString. unique(); } }; /** * A ridiculous class needed because UniConf::operator->() needs to return * a pointer, even though that pointer is going to be dereferenced * immediately anyway. We can instantiate a temporary WvStringStar, which * can then return its 'this' pointer. */ class WvStringStar : public WvFastString { public: WvStringStar(WvStringParm s) : WvFastString(s) { } WvFastString *operator -> () { return this; } }; inline bool operator== (const char *s1, WvStringParm s2) { return s2 == s1; } inline bool operator!= (const char *s1, WvStringParm s2) { return s2 != s1; } #endif // __WVSTRING_H wvstreams-4.6.1/include/wvglobdiriter.h0000644000175000001440000000121311036722347017253 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Directory iterator. Recursively uses opendir and readdir, so you don't * have to. Basically implements 'find'. * */ #ifndef __WVGLOBDIRITER_H #define __WVGLOBDIRITER_H #include "wvdiriter.h" class WvGlob; class WvGlobDirIter : public WvDirIter { private: WvGlob *glob; public: WvGlobDirIter( WvStringParm dirname, WvStringParm globstr, bool _recurse = true, bool _skip_mounts = false, size_t sizeof_stat = sizeof(struct stat) ); ~WvGlobDirIter(); bool next(); }; #endif wvstreams-4.6.1/include/wvtimestream.h0000644000175000001440000000336611036722347017132 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVTIMESTREAM_H #define __WVTIMESTREAM_H #include "wvtimeutils.h" #include "wvstream.h" /** * WvTimeStream causes select() to be true after a configurable number * of milliseconds. Because programs using WvStream make no guarantees * about how often select() will be called, WvTimeStream tries to adjust * its timing to a correct _average_ number of milliseconds per tick. * * For example, if ms_per_tick=100, WvTimeStream will tick 10 times in one * second. However, there may be a few milliseconds of difference * ("jitter") for each individual tick, due to random system delays. */ class WvTimeStream : public WvStream { WvTime last; WvTime next; time_t ms_per_tick; public: WvTimeStream(); /** * Every 'msec' milliseconds, select() will return true on this * stream. if 'msec' is 0 (or less), the timer is disabled. * * Be careful when mixing alarm() with this. You can know whether * it was the alarm or if you had a timer event by looking at * alarm_was_ticking. But the alarm() has priority, so if there's * always an alarm, the timer event never gets to run. Calling * alarm(0) in the callback unconditionally would thus be a bad * idea, or even with an unsuitably small number (say, less than * the time it takes to go back into select()). So don't do it. */ void set_timer(time_t msec); virtual bool isok() const; virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void execute(); public: const char *wstype() const { return "WvTimeStream"; } }; #endif // __WVTIMESTREAM_H wvstreams-4.6.1/include/wvgzipstream.h0000644000175000001440000000166411036722347017144 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A Gzip stream. */ #ifndef __WVGZIPSTREAM_H #define __WVGZIPSTREAM_H #include "wvgzip.h" /** * A stream implementing Gzip compression and decompression. * * By default, written data is compressed using WvGzipEncoder::Deflate, * read data is decompressed using WvGzipEncoder::Inflate. * * @see WvGzipEncoder */ class WvGzipStream : public WvEncoderStream { public: WvGzipStream(WvStream *_cloned, WvGzipEncoder::Mode readmode = WvGzipEncoder::Inflate, WvGzipEncoder::Mode writemode = WvGzipEncoder::Deflate) : WvEncoderStream(_cloned) { readchain.append(new WvGzipEncoder(readmode), true); writechain.append(new WvGzipEncoder(writemode), true); } virtual ~WvGzipStream() { } public: const char *wstype() const { return "WvGzipStream"; } }; #endif /* __WVGZIPSTREAM_H */ wvstreams-4.6.1/include/wvautoconf.h.in0000644000175000001440000001473311260431130017165 0ustar wlachusers/* include/wvautoconf.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Compiler warning on deprecated functions */ #undef ATTR_DEPRECATED /* 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 to enable the XPLC delete detector. */ #undef ENABLE_DELETE_DETECTOR /* Size of ethernet address */ #undef ETHER_ADDR_LEN /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_ARGP_H /* Define to 1 if you have the header file. */ #undef HAVE_ARGZ_H /* Define to 1 if you have the header file. */ #undef HAVE_BOOST_FUNCTION_HPP /* Define to 1 if you have the header file. */ #undef HAVE_BOOST_THROW_EXCEPTION_HPP /* Solaris has a broken PAM implementation */ #undef HAVE_BROKEN_PAM /* Define to 1 if you have the `cfmakeraw' function. */ #undef HAVE_CFMAKERAW /* Define to 1 if you have the header file. */ #undef HAVE_DBUS_DBUS_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_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_INTTYPES_H /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Whether libc supports __libc_stack_end */ #undef HAVE_LIBC_STACK_END /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM /* Define to 1 if you have the `readline' library (-lreadline). */ #undef HAVE_LIBREADLINE /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL /* Define to 1 if you have the `tcl8.3' library (-ltcl8.3). */ #undef HAVE_LIBTCL8_3 /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SERIAL_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_SYSTM_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IP_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_ETHERNET_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H /* Whether libssl has the POLICY_MAPPING features (0.9.8 and up) */ #undef HAVE_OPENSSL_POLICY_MAPPING /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_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, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_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_TCL_H /* Define to 1 if you have the header file. */ #undef HAVE_TR1_FUNCTIONAL /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_VALGRIND_MEMCHECK_H /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_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 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 /* Verbose package version */ #undef VERBOSE_PACKAGE_VERSION /* Extra version string. */ #undef VER_STRING_EXTRA /* Define to enable DBUS support. */ #undef WITH_DBUS /* 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 to disable WvResolver forking for debugging with gdb. */ #undef WVRESOLVER_SKIP_FORK /* Define so that glibc/gnulib argp.h does not typedef error_t. */ #undef __error_t_defined /* Define to a type to use for `error_t' if it is not otherwise available. */ #undef error_t wvstreams-4.6.1/include/wvloopback.h0000644000175000001440000000105411036722347016542 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVLOOPBACK_H #define __WVLOOPBACK_H #include "wvfdstream.h" /** * Implementation of a WvLoopback stream. WvLoopback uses a * socketpair() to create a stream that allows you to read() * everything written to it, even (especially) across a fork() call. */ class WvLoopback : public WvFDStream { public: WvLoopback(); public: const char *wstype() const { return "WvLoopback"; } }; #endif // __WVLOOPBACK_H wvstreams-4.6.1/include/verstring.h0000644000175000001440000000011711036722347016415 0ustar wlachusers// this file exists only for backwards compatibility! #include "wvverstring.h" wvstreams-4.6.1/include/wvaddr.h0000644000175000001440000003051411036722347015665 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Device-independent and device-specific hardware/protocol address classes * that can store themselves efficiently as well as create a printable string * version of themselves. */ #ifndef __WVADDR_H #define __WVADDR_H #include "wvautoconf.h" #include "if_arp.h" /* To define ARPHRD_.* */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif #if HAVE_NETINET_IN_H # include #endif #ifdef _WIN32 #include #define ETHER_ADDR_LEN 6 #define IP_ALEN 4 #endif #ifdef _MSC_VER typedef unsigned int uint32_t; typedef unsigned short uint16_t; #endif #include "wvstring.h" static const char * type_wvaddr = "WvAddr"; static const char * type_wvipaddr = "WvIPAddr"; static const char * type_wvipnet = "WvIPNet"; static const char * type_wvipportaddr = "WvIPPortAddr"; #define WVADDR type_wvaddr #define WVIPADDR type_wvipaddr #define WVIPNET type_wvipnet #define WVIPPORTADDR type_wvipportaddr /** * Common packet encapsulation types, with the ability to convert a Linux * ARPHRD_* value or (struct sockaddr) sa_family value. (Those two use the * same set of values.) */ class WvEncap { static const char strings[][20]; // printable-string names per type static int extypes[]; // external types (ARPHRD_*, etc) public: // NOTE: if you change enum CapType, don't forget to change extypes[] // and strings[] in wvaddr.cc! enum CapType { // hardware encapsulation Unknown = 0, Loopback, Ethertap, Ethernet, ARCnet, SLIP, CSLIP, PPP, IPsec, // protocol encapsulation IPv4, Unix, // END NUM_ENCAP_TYPES }; CapType cap; WvEncap(CapType _cap = Unknown) { cap = _cap; } WvEncap(int extype); operator CapType () const { return cap; } operator WvString () const { return strings[cap]; } }; /** * Base class for different address types, each of which will have * the ability to convert itself to/from a printable string, as well * as other type-specific abilities. */ class WvAddr { protected: virtual WvString printable() const = 0; public: WvAddr() {}; virtual ~WvAddr() {}; static WvAddr *gen(struct sockaddr *addr); virtual WvEncap encap() const = 0; operator WvString() const { return printable(); } virtual bool comparator(const WvAddr *a2, bool first_pass = true) const; // Poor man's rtti virtual const char *type() const { return WVADDR; }; virtual bool isbroadcast() const; virtual struct sockaddr *sockaddr() const = 0; virtual size_t sockaddr_len() const = 0; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; virtual unsigned WvHash() const; bool operator== (const WvAddr &a2) const { return comparator(&a2); } bool operator!= (const WvAddr &a2) const { return ! (*this == a2); } }; // useful for hash tables (see wvhashtable.h) unsigned WvHash(const WvAddr &addr); /** * A WvAddr that simply contains a printable string with a user-defined * encapsulation type. */ class WvStringAddr : public WvAddr { WvString addr; WvEncap cap; protected: virtual WvString printable() const; public: WvStringAddr(WvStringParm s, const WvEncap &_cap); WvStringAddr(const struct sockaddr *_addr); virtual ~WvStringAddr(); virtual WvEncap encap() const; virtual struct sockaddr *sockaddr() const; virtual size_t sockaddr_len() const; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; }; #ifndef _WIN32 /** * An ethernet address is made up of a string of hex numbers, in the form * AA:BB:CC:DD:EE:FF */ class WvEtherAddr : public WvAddr { unsigned char binaddr[ETHER_ADDR_LEN]; protected: virtual WvString printable() const; public: WvEtherAddr(const unsigned char _binaddr[ETHER_ADDR_LEN] = NULL) { if (_binaddr) memcpy(binaddr, _binaddr, ETHER_ADDR_LEN); } WvEtherAddr(const char string[]) { string_init(string); } WvEtherAddr(WvStringParm string) { string_init(string); } void string_init(const char string[]); WvEtherAddr(const struct sockaddr *addr) { memcpy(binaddr, (void *)addr->sa_data, ETHER_ADDR_LEN); } virtual ~WvEtherAddr(); virtual WvEncap encap() const; virtual bool isbroadcast() const; virtual struct sockaddr *sockaddr() const; virtual size_t sockaddr_len() const; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; }; /** An ARCnet address is made up of a single hex number. */ class WvARCnetAddr : public WvAddr { unsigned char binaddr; protected: virtual WvString printable() const; public: WvARCnetAddr(const unsigned char _binaddr[1] = NULL) { if (_binaddr) binaddr = _binaddr[0]; } WvARCnetAddr(const char string[]) { binaddr = strtoul(string, NULL, 16); } WvARCnetAddr(WvStringParm string) { binaddr = strtoul(string, NULL, 16); } WvARCnetAddr(const struct sockaddr *addr) { binaddr = ((unsigned char *)addr->sa_data)[0]; } virtual ~WvARCnetAddr(); virtual WvEncap encap() const; virtual struct sockaddr *sockaddr() const; virtual size_t sockaddr_len() const; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; }; #endif // !_WIN32 /** * An IP address is made up of a "dotted quad" -- four decimal numbers in * the form * www.xxx.yyy.zzz * * We don't support automatic name lookups yet, but this will be the place * to do it when support is added. */ class WvIPAddr : public WvAddr { protected: virtual WvString printable() const; public: unsigned char binaddr[4]; WvIPAddr(const unsigned char *_binaddr) { if (_binaddr) memcpy(binaddr, _binaddr, 4); } WvIPAddr(const uint32_t _binaddr = 0) { memcpy(binaddr, &_binaddr, 4); } WvIPAddr(const char string[]) { string_init(string); } WvIPAddr(WvStringParm string) { string_init(string); } void string_init(const char string[]); WvIPAddr(const struct sockaddr *addr) { memcpy(binaddr, (void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, 4); } WvIPAddr(const WvIPAddr &_addr) { memcpy(binaddr, _addr.binaddr, 4); } virtual ~WvIPAddr(); virtual bool comparator(const WvAddr *a2, bool first_pass = true) const; virtual const char *type() const { return WVIPADDR; }; WvIPAddr operator& (const WvIPAddr &a2) const; WvIPAddr operator| (const WvIPAddr &a2) const; WvIPAddr operator^ (const WvIPAddr &a2) const; WvIPAddr operator~ () const; WvIPAddr operator+ (int n) const; WvIPAddr operator- (int n) const; uint32_t addr() const { return *(uint32_t *)binaddr; } bool is_zero() const { return addr() == 0; } virtual WvEncap encap() const; virtual struct sockaddr *sockaddr() const; virtual size_t sockaddr_len() const; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; }; /** * An IP network comprises two WvIPAddr structures: an address and a * netmask. The two ANDed together comprise the "network address", * which, if it is correct, can be ORed with any IP address on the * network without changing the address. Together, a network address * and netmask provide a good description of the IP addresses * available on a network. * * WvIPNet internally stores a base IP address (the inherited WvIPAddr) * and the netmask (a member variable). * * Note that the rawdata() function is inherited from WvIPAddr, so it does * not include the netmask in the raw data. */ class WvIPNet : public WvIPAddr { protected: WvIPAddr mask; virtual WvString printable() const; public: WvIPNet(const WvIPNet &_net); WvIPNet(const char string[]) : WvIPAddr(string) { string_init(string); } WvIPNet(WvStringParm string) : WvIPAddr(string) { string_init(string); } void string_init(const char string[]); WvIPNet(const WvIPAddr &base, const WvIPAddr &_mask); virtual bool comparator(const WvAddr *a2, bool first_pass = true) const; virtual const char *type() const { return WVIPNET; }; /** * construct an IPNet from a base address and a number of bits in * the netmask. The default of 32 gives a one-host network, * (netmask 255.255.255.255). */ WvIPNet(const WvIPAddr &base, int bits = 32); /** construct an empty IPNet for later copying (probably by operator=) */ WvIPNet(); virtual ~WvIPNet(); /** Override the hash and comparison functions */ virtual unsigned WvHash() const; /** Get the 'base IP address' component, netmask, network, and broadcast */ WvIPAddr base() const { return *this; } WvIPAddr netmask() const { return mask; } WvIPAddr network() const { return *this & mask; } WvIPAddr broadcast() const { return *this | ~mask; } /** adjust the netmask so that 'addr' would be included in this network */ void include(const WvIPNet &addr); /** determine whether the given address is already included in this net */ bool includes(const WvIPNet &addr) const; /** * weird netmasks such as 255.0.255.0 (easy example) are almost never * used -- they have '0' bits in the middle. However, using the * include() function will result in odd netmasks like this, since * it will not eliminate a '1' bit unless absolutely necessary. * normalize() would convert the above netmask into 255.0.0.0, which * is probably the netmask _really_ in use. bits() calculates * the number of leading '1' bits in the normalized netmask, without * actually doing the normalization. */ int bits() const; void normalize(); /** is this net the default gateway? (0.0.0.0/0) */ bool is_default() const { return mask.binaddr[0] == 0; } /** is it a plain host? (x.x.x.x/32) */ bool is_host() const { return mask.binaddr[3] == 255; } }; /** * An IP+Port address also includes a port number, with the resulting form * www.xxx.yyy.zzz:pppp * * Note that the rawdata() function is inherited from WvIPAddr, so it does * not include the port number in the raw data. */ class WvIPPortAddr : public WvIPAddr { protected: virtual WvString printable() const; public: uint16_t port; WvIPPortAddr(); WvIPPortAddr(const unsigned char _ipaddr[4], uint16_t _port = 0) : WvIPAddr(_ipaddr), port(_port) { }; WvIPPortAddr(const WvIPAddr &_ipaddr, uint16_t _port = 0); WvIPPortAddr(const char string[]) : WvIPAddr(string) { string_init(string); } WvIPPortAddr(WvStringParm string) : WvIPAddr(string) { string_init(string); } void string_init(const char string[]); WvIPPortAddr(uint16_t _port); // assumes address 0.0.0.0, (ie local) WvIPPortAddr(const char string[], uint16_t _port); WvIPPortAddr(struct sockaddr_in *sin) : WvIPAddr(sin->sin_addr.s_addr) { port = ntohs(sin->sin_port); } virtual ~WvIPPortAddr(); virtual bool comparator(const WvAddr *a2, bool first_pass = true) const; virtual const char *type() const { return WVIPPORTADDR; }; virtual struct sockaddr *sockaddr() const; // Override the hash and comparison functions virtual unsigned WvHash() const; }; #ifndef _WIN32 /** A Unix domain socket address is really just a filename. */ class WvUnixAddr : public WvAddr { protected: WvString sockname; virtual WvString printable() const; public: WvUnixAddr(const char *_sockname); WvUnixAddr(WvStringParm _sockname); WvUnixAddr(const WvUnixAddr &_addr); virtual ~WvUnixAddr(); virtual WvEncap encap() const; virtual struct sockaddr *sockaddr() const; virtual size_t sockaddr_len() const; virtual const unsigned char *rawdata() const; virtual size_t rawdata_len() const; }; #endif //windows #endif // __WVADDR_H wvstreams-4.6.1/include/wvdigest.h0000644000175000001440000000773211253746065016244 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * MD5, SHA-1 and HMAC digest abstractions. */ #ifndef __WVDIGEST_H #define __WVDIGEST_H #include "wvencoder.h" #include struct env_md_st; struct env_md_ctx_st; struct hmac_ctx_st; /** * Superclass for all message digests. * * All message digest encoders have the following semantics: * * - On encode() or flush(), data from the input buffer is * consumed and a message digest function is applied to * incrementally update the internal digest state. * No output is ever generated. * - On finish(), the message digest is finalized and its value * is written to the output buffer. Afterwards, no new data * can be processed unless reset() is called. * - On reset(), the current digest state is discarded allowing * a new stream of data to be processed. * */ class WvDigest : public WvEncoder { public: /** Returns the number of bytes in the message digest. */ virtual size_t digestsize() const = 0; }; /** * @internal * Base class for all digests constructed using the OpenSSL EVP API. */ class WvEVPMDDigest : public WvDigest { friend class WvHMACDigest; const env_md_st *evpmd; env_md_ctx_st *evpctx; bool active; public: virtual ~WvEVPMDDigest(); virtual size_t digestsize() const; protected: WvEVPMDDigest(const env_md_st *_evpmd); virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); // consumes input virtual bool _finish(WvBuf &outbuf); // outputs digest virtual bool _reset(); // supported: resets digest value const env_md_st *getevpmd() { return evpmd; } private: void cleanup(); }; /** * MD5 Digest. * Has a digest length of 128 bits. */ class WvMD5Digest : public WvEVPMDDigest { public: /** Creates an MD5 digest encoder. */ WvMD5Digest(); virtual ~WvMD5Digest() { } }; /** * SHA-1 Digest. * Has a digest length of 160 bits. */ class WvSHA1Digest : public WvEVPMDDigest { public: /** Creates an SHA1 digest encoder. */ WvSHA1Digest(); virtual ~WvSHA1Digest() { } }; /** * HMAC Message Authentication Code. * Has a digest length that equals that of its underlying * message digest encoder. */ class WvHMACDigest : public WvDigest { WvEVPMDDigest *digest; unsigned char *key; size_t keysize; hmac_ctx_st *hmacctx; bool active; public: /** * Creates an HMAC digest encoder. * * "digest" is the message digest encoder to use as a * hash function * "key" is the authentication key * "keysize" is the key size in bytes */ WvHMACDigest(WvEVPMDDigest *_digest, const void *_key, size_t _keysize); virtual ~WvHMACDigest(); virtual size_t digestsize() const; protected: virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); // consumes input virtual bool _finish(WvBuf &outbuf); // outputs digest virtual bool _reset(); // supported: resets digest value private: void cleanup(); }; /** * CRC32 checksum * Digest length of 4 bytes. */ class WvCrc32Digest : public WvDigest { uint32_t crc; public: WvCrc32Digest(); virtual ~WvCrc32Digest() { } virtual size_t digestsize() const; virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); // consumes input virtual bool _finish(WvBuf &outbuf); // outputs digest virtual bool _reset(); // supported: resets digest value }; /** * Adler32 checksum * Digest length of 4 bytes. */ class WvAdler32Digest : public WvDigest { uint32_t crc; public: WvAdler32Digest(); virtual ~WvAdler32Digest() { } virtual size_t digestsize() const; virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); // consumes input virtual bool _finish(WvBuf &outbuf); // outputs digest virtual bool _reset(); // supported: resets digest value }; #endif // __WVDIGEST_H wvstreams-4.6.1/include/wvsslstream.h0000644000175000001440000000770211057766345017004 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * SSL (Socket Security Layer) communications via WvStreams. */ #ifndef __WVSSLSTREAM_H #define __WVSSLSTREAM_H #include "wvfdstream.h" #include "wvlog.h" #include "wvstreamclone.h" #include "wvtr1.h" struct ssl_st; struct ssl_ctx_st; struct ssl_method_st; typedef struct ssl_ctx_st SSL_CTX; typedef struct ssl_st SSL; typedef struct ssl_method_st SSL_METHOD; class WvX509; class WvX509Mgr; class WvSSLStream; typedef wv::function WvSSLValidateCallback; typedef wv::function WvSSLGlobalValidateCallback; /** * SSL Stream, handles SSLv2, SSLv3, and TLS * Methods - If you want it to be a server, then you must feed the constructor * a WvX509Mgr object */ class WvSSLStream : public WvStreamClone { public: /* This ValidateCallback is purely more convenient to set (not passed in * via constructor) than its local cousin. It is used when you want an * easy way to assign a validation function to any WvSSLStream you might * be using. NOTE: It should be assigned before you instantiate a stream, * and should never be changed while WvSSLStreams still linger. * * NOTE: Using wv::bind can effectively bind an object with a particular * function for this callback, so you can do all sorts of interesting stuff * with it. */ static WvSSLGlobalValidateCallback global_vcb; /** * Start an SSL connection on the stream _slave. The x509 structure * is optional for a client, and mandatory for a server. You need to * keep the X509 object around for the entire life of this object! */ WvSSLStream(IWvStream *_slave, WvX509Mgr *_x509 = NULL, WvSSLValidateCallback _vcb = 0, bool _is_server = false); /** Cleans up everything (calls close + frees up the SSL Objects used) */ virtual ~WvSSLStream(); virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual void close(); virtual bool isok() const; virtual void noread(); virtual void nowrite(); protected: WvX509Mgr *x509; /** SSL Context - used to create SSL Object */ SSL_CTX *ctx; /** * Main SSL Object - after SSL_set_fd() we make all calls through the * connection through here */ SSL *ssl; virtual size_t uwrite(const void *buf, size_t len); virtual size_t uread(void *buf, size_t len); private: /** * Connection Status Flag, since SSL takes a few seconds to * initialize itself. */ bool sslconnected; SelectRequest connect_wants; /** Set the connected flag and flush the unconnected_buf */ void setconnected(bool conn); /** Keep track of whether we are a client or a server */ bool is_server; /** We have to override the WvStream noread/nowrite implementation... */ bool ssl_stop_read, ssl_stop_write; /** Keep track of whether we want to check the peer who connects to us */ WvSSLValidateCallback vcb; /** Internal Log Object */ WvLog debug; /** * SSL_write() may return an SSL_ERROR_WANT_WRITE code which * indicates that the function should be called again with * precisely the same arguments as the last time. To ensure that * this can happen, we must unfortunately copy data into a bounce * buffer and remeber the fact. We use a WvBuf here to allow * an arbitrary amount of data to be set aside. */ WvInPlaceBuf write_bouncebuf; size_t write_eat; /** Similar nastiness happens with SSL_read() */ WvInPlaceBuf read_bouncebuf; bool read_pending; /** Need to buffer writes until sslconnected */ WvDynBuf unconnected_buf; /** Prints out the entire SSL error queue */ void printerr(WvStringParm func); public: const char *wstype() const { return "WvSSLStream"; } }; #endif // __WVSSLSTREAM_H wvstreams-4.6.1/include/wvhash.h0000644000175000001440000000155011036722347015674 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Common hash functions for use with wvscatterhash.h and wvhashtable.h. */ #ifndef __WVHASH_H #define __WVHASH_H #include "wvstring.h" // predefined hashing functions (note: string hashes are case-insensitive) unsigned WvHash(WvStringParm s); unsigned WvHash(const char *s); unsigned WvHash(const int &i); unsigned WvHash(const void *p); // Default comparison function used by WvHashTable template struct OpEqComp { static bool compare(const K *key1, const K *key2) { return *key1 == *key2; } }; // Case-insensitive comparison function for WvHashTable template struct StrCaseComp { static bool compare(const K *key1, const K *key2) { return strcasecmp(*key1, *key2) == 0; } }; #endif // __WVHASH_H wvstreams-4.6.1/include/unifilesystemgen.h0000644000175000001440000000431111036722347017764 0ustar wlachusers#ifndef __UNIFILESYSTEMGEN_H #define __UNIFILESYSTEMGEN_H #include "uniconfgen.h" #include /** * Creates a UniConf tree that mirrors some point in the Linux filesystem, * with restrictions. The root of the point to be mirrored is a directory * name. Additionally, the mode for creation of all files and directories * must be given. * * UniConf keys are mapped to filesystem paths in the obvious way (delimit * and precede the list of names with "/", then append to the path for the * point being mirrored). * * Keys corresponding to regular files have value equal to the content of * that file (plus a terminating NUL). Keys whose corresponding pathname * does not exist have value equal to the null string. Keys corresponding * to things other than regular files have value equal to the empty string, * unless their last segment is "." or "..", in which case they have value * equal to the null string. * * Due to these definitions, the UniFileSystemGen violates the UniConfGen * semantics in that it is not possible for a key to have simultaneously a * non-empty value and children and it is not possible for a key named * "." or ".." to exist. Any set operation that by the UniConfGen semantics * would cause either of those things to be true will instead do nothing. * These shortcomings are permanent. * * If an unrecoverable error occurs during set, it will fail, but will * possibly still have an effect. If an unrecoverable error occurs * during get, it will return the null string. If an unrecoverable error * occurs during iterator(), it will return a NULL pointer. * * Presently, callbacks are never triggered. * * Files containing embedded NUL characters don't currently work quite right * because WvString can't deal with them. They'll stop at the first NUL. */ class UniFileSystemGen : public UniConfGen { public: UniFileSystemGen(WvStringParm _dir, mode_t _mode); virtual WvString get(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm value); virtual void setv(const UniConfPairList &pairs); virtual void flush_buffers() {} virtual Iter *iterator(const UniConfKey &key); private: WvString dir; mode_t mode; }; #endif wvstreams-4.6.1/include/wvstreamclone.h0000644000175000001440000000643711057766345017307 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Provides support for constructing streams that wrap other streams. * This can turn a (relatively useless) IWvStream into a useful WvStream. */ #ifndef __WVSTREAMCLONE_H #define __WVSTREAMCLONE_H #include "wvstream.h" /** * WvStreamClone simply forwards all requests to the "cloned" stream. * * A class derived from WvStreamClone can contain a WvStream as a * dynamically allocated data member, but act like the stream itself. * * This is useful for classes that need to create/destroy WvPipes * while they run, for example, yet do not want users to know about * the member variable. */ class WvStreamClone : public WvStream { public: /** * Constructs the stream, then calls setclone(_cloned). See setclone() * for important information. */ WvStreamClone(IWvStream *_cloned = NULL); /** * The WvStreamClone destructor. * * Note that this calls setclone(NULL), which calls WVRELEASE(cloned). * * However, we do *not* explicitly cloned->close(). If the clone is * ready to delete itself after the release, then it will close itself * anyway; if not, WvStreamClone leaves it alone. Note that this * behaviour was quite different before WvStreams 5. */ virtual ~WvStreamClone(); IWvStream *cloned; /** * WvStreamClone takes ownership of the given stream; it will WVRELEASE() * the stream when you setclone() it to something else or destroy this * object. If this is undesirable, you should addRef() the stream before * passing it in here. * * Note: setclone() changes the cloned stream's various callbacks. It * removes the callbacks from the old stream when you setclone() to * something else. This means it is not safe to clone the same stream * more than once at a time, but it is safe to un-clone and then re-clone * a stream (as long as you watch its reference count). * * Note: calling setclone() more than once on the same stream can cause * weird interactions with buffering. Be careful. It is often best to * flush your output buffer before calling setclone(). */ virtual void setclone(IWvStream *clone); /** * Close this stream. Note that this *does* close the inner stream. * However, see ~WvStreamClone() for a note about destroying vs. closing * the stream. */ virtual void close(); /** * WvStream overrides. These generally just call the cloned stream's * version. */ virtual bool flush_internal(time_t msec_timeout); virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); virtual bool isok() const; virtual int geterr() const; virtual WvString errstr() const; virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); virtual const WvAddr *src() const; virtual void execute(); virtual void noread(); virtual void nowrite(); virtual WvString getattr(WvStringParm name) const; private: void close_callback(); protected: WvString my_type; public: const char *wstype() const { return my_type; } }; #endif // __WVSTREAMCLONE_H wvstreams-4.6.1/include/wvbufstream.h0000644000175000001440000000307211077373036016744 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A buffered loopback stream. */ #ifndef __WVBUFSTREAM_H #define __WVBUFSTREAM_H #include "wvstream.h" /** * WvBufStream stores data written by write(), and returns it * later on in read(). * * Handy for making virtual streams, like WvHttpPool. * * After seteof(), the stream closes itself (without error) once the inbuf * is emptied out by read(). * * FIXME: WvStream itself should probably deal better with streams that go * !isok() with stuff still in inbuf. Then we could skip seteof() altogether, * and just do close() when we're done write()ing data. For now, it's just * too unreliable to do that, since streams do things like drop out of * WvStreamLists automatically when they're !isok(), even if they still have * data in inbuf. * * 2003/12/09: This is cleaned up a lot by WvStream's new noread()/nowrite() * functions, but we still need to actually *use* them in WvBufStream... */ class WvBufStream : public WvStream { bool dead, /*!< true if the stream has been closed */ eof; /*!< true if the sender has no more data to write(). */ public: WvBufStream(); virtual ~WvBufStream(); virtual void close(); virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); virtual bool isok() const; virtual void pre_select(SelectInfo &si); virtual bool post_select(SelectInfo &si); void seteof() { eof = true; } }; #endif // __WVBUFSTREAM_H wvstreams-4.6.1/include/wvdbusserver.h0000644000175000001440000000536611077124114017137 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * * This class represents a dbus server, which may have multiple connections * at the same time. It is intended purely for unit testing and debugging * purposes and by no means should be used in production code (use the * dbus daemon for that). * */ #ifndef __WVDBUSSERVER_H #define __WVDBUSSERVER_H #include "wvlistener.h" #include "wvhashtable.h" #include "wvlog.h" #include "wvistreamlist.h" #include class WvDBusMsg; class WvDBusConn; DeclareWvList(WvDBusConn); class WvDBusServer : public WvIStreamList { WvIStreamList listeners; public: /* * Constructs a new DBus server. You must then call listen() to * actually listen for new connections. */ WvDBusServer(); /** * Not actually defined. Just prevents accidental copying. */ WvDBusServer(WvDBusServer &c); /** * Shut down this server. */ virtual ~WvDBusServer(); /** * Listen using a given WvListener moniker. Until you do this at least * once, this stream is !isok(). It is okay to call listen() more * than once if you want to listen on more than one port. * * For example: * WvDBusServer s; * s.listen("unix:/tmp/foo"); */ void listen(WvStringParm moniker); virtual bool isok() const; virtual int geterr() const; /** * Register a given dbus service name as belonging to a particular * connection. */ void register_name(WvStringParm name, WvDBusConn *conn); /** * Undo a register_name(). */ void unregister_name(WvStringParm name, WvDBusConn *conn); /** * Forget all name registrations for a particular connection. Also * forget all serial numbers attached to that connection. Mostly useful * when a connection closes. */ void unregister_conn(WvDBusConn *conn); /** * get the full, final address (identification guid and all) of the server * if there's more than one listener, returns one of them. */ WvString get_addr(); private: WvLog log; WvDBusConnList all_conns; std::map name_to_conn; void new_connection_cb(IWvStream *s); void conn_closed(WvStream &s); bool do_server_msg(WvDBusConn &conn, WvDBusMsg &msg); bool do_bridge_msg(WvDBusConn &conn, WvDBusMsg &msg); bool do_broadcast_msg(WvDBusConn &conn, WvDBusMsg &msg); bool do_gaveup_msg(WvDBusConn &conn, WvDBusMsg &msg); }; #endif // __WVDBUSSERVER_H wvstreams-4.6.1/include/wverror.h0000644000175000001440000000670011036722347016104 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for managing error numbers and strings. */ #ifndef __WVERROR_H #define __WVERROR_H #include "wvstring.h" /** * A class for managing error numbers and strings. * * It can have either a system error value, like those defined * in errno.h, or an arbitrary error string. In either case, it * can return a string representation of the error message. * * This object is most useful for using as a base class of your own class, * for historical/backwards compatibility reasons. Consider using a WvError * instead, and making it a member of your class instead of a parent. */ class WvErrorBase { protected: int errnum; WvString errstring; public: WvErrorBase() { noerr(); } virtual ~WvErrorBase(); /** * By default, returns true if geterr() == 0. * Might be overridden so that isok() == false even though no * error code has been specified. */ virtual bool isok() const { return errnum == 0; } /** * If isok() is false, return the system error number corresponding to * the error, -1 for a special error string (which you can obtain with * errstr()) or 0 on end of file. If isok() is true, returns an * undefined number. */ virtual int geterr() const { return errnum; } virtual WvString errstr() const; /** * A replacement for the operating system ::strerror() function that * can map more kinds of error strings (especially in win32). */ static WvString strerror(int errnum); /** * Set the errnum variable -- we have an error. If called more than * once, seterr() doesn't change the error code away from the previous * one. That way, we remember the _original_ cause of our problems. * * Subclasses may want to override seterr(int) to shut themselves down * (eg. WvStream::close()) when an error condition is set. * * Note that seterr(WvString) will call seterr(-1). */ virtual void seterr(int _errnum); void seterr(WvStringParm specialerr); void seterr(WVSTRING_FORMAT_DECL) { seterr(WvString(WVSTRING_FORMAT_CALL)); } void seterr_both(int _errnum, WvStringParm specialerr); void seterr_both(int _errnum, WVSTRING_FORMAT_DECL) { seterr_both(_errnum, WvString(WVSTRING_FORMAT_CALL)); } void seterr(const WvErrorBase &err); /** Reset our error state - there's no error condition anymore. */ void noerr() { errnum = 0; errstring = WvString::null; } }; /** * A variant of WvErrorBase suitable for embedding as a member of your own * object, preferably called 'err'. It adds some extra convenience functions * to remove function name redundancy, so you can say "obj.err.get()" instead * of "obj.err.geterr()", for example. */ class WvError : public WvErrorBase { public: int get() const { return geterr(); } WvString str() const { return errstr(); } void set(int _errnum) { seterr(_errnum); } void set(WvStringParm specialerr) { seterr(specialerr); } void set(WVSTRING_FORMAT_DECL) { seterr(WvString(WVSTRING_FORMAT_CALL)); } void set_both(int _errnum, WvStringParm specialerr) { seterr_both(_errnum, specialerr); } void set(const WvErrorBase &err) { seterr(err); } void reset() { noerr(); } }; #endif // __WVERROR_H wvstreams-4.6.1/include/wvstringmask.h0000644000175000001440000000250311036722347017132 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Implementation of an efficient lookup for a set characters. * * It is, however, a little space intensive, but you should statically * create them in your functions, and then they won't be so bad. */ #ifndef __WVSTRINGMASK_H #define __WVSTRINGMASK_H #include "wvstring.h" /** * A class used to provide a masked lookup for characters in a string. */ class WvStringMask { public: /** * Create a WvStringMask out of a WvString. When looked up, * characters in 's' will return true. */ WvStringMask(WvStringParm s = WvString::null); WvStringMask(char c); /** * Look up a character. This will return true if 'c' is in 'set'. */ bool operator[](const char c) const; /** * Get the first character set into the mask */ const char first() const; /** * Clear the WvStringMask, so that all lookups return false. */ void zap(); /** * Set a character 'c' to a particular truth value. */ void set(const char c, bool value); /** * Set all characters in string 's' to a particular truth value. */ void set(WvStringParm s, bool value); private: bool _set[256]; char _first; }; #endif // __WVSTRINGMASK_H wvstreams-4.6.1/include/wvtimeoutstream.h0000644000175000001440000000153311036722347017654 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVTIMEOUTSTREAM_H #define __WVTIMEOUTSTREAM_H #include "wvstream.h" /** * WvTimeoutStream is a stream that becomes !isok() after a * configurable number of milliseconds. It will wake up a select(). It * will return true if select()ed and that the timeout has * expired. But using it in a WvStreamList will not have it call the * callback/execute because the WvStreamList checks whether isok() is * true before doing the select(). */ class WvTimeoutStream: public WvStream { bool ok; public: WvTimeoutStream(time_t msec); virtual bool isok() const { return ok; } virtual void execute(); private: const char *wstype() const { return "WvTimeoutStream"; } }; #endif // __WVTIMEOUTSTREAM_H wvstreams-4.6.1/include/wvurl.h0000644000175000001440000000301311036722347015547 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvURL is a simple URL-parsing class with built-in (though still somewhat * inconvenient) DNS resolution. */ #ifndef __WVURL_H #define __WVURL_H #include "wvstring.h" #include "wvresolver.h" class WvIPPortAddr; class WvUrl { public: WvUrl(WvStringParm url); WvUrl(const WvUrl &url); ~WvUrl(); bool isok() const { return port != 0 && (resolving || addr != NULL); } WvStringParm errstr() const { return err; } bool resolve(); // dns-resolve the hostname (returns true if done) operator WvString () const; // not actually defined - this just prevents accidental copying const WvUrl &operator= (const WvUrl &); WvStringParm getproto() const { return proto; } // this one is ONLY valid if resolve() returns true! const WvIPPortAddr getaddr() const { return addr ? *addr : WvIPPortAddr(); } WvStringParm getfile() const { return file; } WvStringParm gethost() const { return hostname; } int getport() const { return port; } WvStringParm getuser() const { return user; } WvStringParm getpassword() const { return password; } protected: WvString proto, hostname, user, password; int port; bool resolving; WvResolver dns; WvIPPortAddr *addr; WvString file, err; }; // backwards compatibility typedef WvUrl WvURL; #endif // __WVURL_H wvstreams-4.6.1/include/wvwindebuglog.h0000755000175000001440000000026511036722347017264 0ustar wlachusers/* -*- Mode: C++ -*- */ #include "wvlogrcv.h" class WvWinDebugLog : public WvLogRcv { virtual void _mid_line(const char *str, size_t len); virtual ~WvWinDebugLog(); }; wvstreams-4.6.1/include/wvsocketpair.h0000644000175000001440000000072711036722347017122 0ustar wlachusers#ifndef __WVSOCKETPAIR_H #define __WVSOCKETPAIR_H #ifndef _WIN32 #include #endif /** * Like socketpair(), but works in win32 and doesn't ask you about the * protocol (since that's irrelevant, really). 'type' is like the type * parameter to socketpair(), and should be either SOCK_DGRAM or SOCK_STREAM. * * The return value and errno codes are the same as for socketpair(). */ int wvsocketpair(int type, int socks[2]); #endif // __WVSOCKETPAIR_H wvstreams-4.6.1/include/wvmonikerregistry.h0000644000175000001440000000277111057766345020225 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Support for moniker registries. See wvmoniker.h. */ #ifndef __WVMONIKERREGISTRY_H #define __WVMONIKERREGISTRY_H #include "wvmoniker.h" #include "wvlinklist.h" /** * A list for holding moniker-prefix to factory-function mappings. * * This is used by WvMoniker and wvcreate(). See those for details. */ class WvMonikerRegistry //: public GenericComponent { struct Registration { WvString id; WvMonikerCreateFunc *func; Registration(WvStringParm _id, WvMonikerCreateFunc *_func) : id(_id), func(_func) { } }; DeclareWvList(Registration); unsigned refcount; public: UUID reg_iid; RegistrationList list; WvMonikerRegistry(const UUID &iid); virtual ~WvMonikerRegistry(); virtual void add(WvStringParm id, WvMonikerCreateFunc *func, const bool override = false); virtual void del(WvStringParm id); virtual void *create(WvStringParm _s, IObject *_obj); // find a registry for objects of the given interface UUID static WvMonikerRegistry *find_reg(const UUID &iid); // IObject stuff virtual IObject *getInterface(const UUID &uuid); // we can't use GenericComponent's implementation, since we have to // unregister ourselves on the second-last release(). virtual unsigned int addRef(); virtual unsigned int release(); }; #endif // __WVMONIKERREGISTRY_H wvstreams-4.6.1/include/wvlinkerhack.h0000644000175000001440000000203511057766345017074 0ustar wlachusers#ifndef __WVLINKERHACK_H #define __WVLINKERHACK_H /* * Don't call this directly. It's used by WV_LINK_TO(). */ extern int **__wv_link_func(int **to); /** * Create a target that WV_LINK_TO can point at when it wants to make sure * your object file is linked into the final binary. * * Do not put the name in quotes. * * Example (in uniinigen.cc): WV_LINK(UniIniGen); */ #define WV_LINK(name) volatile int __wv_link_##name /** * Link to a target created by WV_LINK, ensuring that the file which created * the WV_LINK is included in your final binary. This is useful for ensuring * particular monikers will always be available when you link statically, * even though you don't refer to any particular classes implementing that * moniker directly. * * Do not put the name in quotes. * * Example (somewhere other than uniinigen.cc): WV_LINK_TO(UniIniGen); */ #define WV_LINK_TO(name) \ extern volatile int __wv_link_##name; \ namespace { volatile int __wv_local_a_##name = __wv_link_##name; } #endif // __WVLINKERHACK_H wvstreams-4.6.1/include/unipermgen.h0000644000175000001440000000615311036722347016551 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __UNIPERMGEN_H #define __UNIPERMGEN_H #include "unifiltergen.h" #include "wvstringtable.h" /** * UniPermGen wraps a tree encoding Unix-style permissions, and provides an * API for setting and checking them. read permission allows you to read the * value of a key, write allows you to set it (duh). exec allows you to get * subkeys. You cannot iterate on a key unless you have exec permission. * (This is badly named, but it's inherited from Unix.) * * Permissions for 'key' are stored in the subkeys key/owner, key/group, * and key/user-read through key/world-write. owner and group store arbitrary * text strings, and the remainder are boolean values. * * If you want to use monikers, UniPermGen can only be via UniSecureGen (see * unisecuregen.h) since it provides its own API beyond just UniConfGen. */ class UniPermGen : public UniFilterGen { public: UniPermGen(IUniConfGen *_gen); UniPermGen(WvStringParm moniker); enum Level { USER = 0, GROUP, WORLD }; static WvString level2str(Level l); enum Type { READ = 0, WRITE, EXEC }; static WvString type2str(Type t); struct Credentials { WvString user; mutable WvStringTable groups; // mutable because stupid WvHashTable has no const lookup methods Credentials() : groups(7) { } }; /** get and set the owner for a path */ void setowner(const UniConfKey &path, WvStringParm owner); WvString getowner(const UniConfKey &path); /** get and set the group for a path */ void setgroup(const UniConfKey &path, WvStringParm group); WvString getgroup(const UniConfKey &path); /** * Return true if a user with the given credentials is allowed to * read/write/exec the given path. */ bool getread(const UniConfKey &path, const Credentials &cred) { return getperm(path, cred, READ); } bool getwrite(const UniConfKey &path, const Credentials &cred) { return getperm(path, cred, WRITE); } bool getexec(const UniConfKey &path, const Credentials &cred) { return getperm(path, cred, EXEC); } bool getperm(const UniConfKey &path, const Credentials &cred, Type type); void setread(const UniConfKey &path, Level level, bool read) { setperm(path, level, READ, read); } void setwrite(const UniConfKey &path, Level level, bool write) { setperm(path, level, WRITE, write); } void setexec(const UniConfKey &path, Level level, bool exec) { setperm(path, level, EXEC, exec); } void setperm(const UniConfKey &path, Level level, Type type, bool val); /** * Set permissions for path using Unix style chmod (with the second form, * be sure to use octal) */ void chmod(const UniConfKey &path, unsigned int owner, unsigned int group, unsigned int world); void chmod(const UniConfKey &path, unsigned int mode); virtual void flush_buffers() { } private: bool getoneperm(const UniConfKey &path, Level level, Type type); }; #endif // __UNIPERMGEN_H wvstreams-4.6.1/include/ftpparse.h0000644000175000001440000000334211036722347016221 0ustar wlachusers/* -*- Mode: C++ -*- */ #ifndef FTPPARSE_H #define FTPPARSE_H #include /* ftpparse(&fp,buf,len) tries to parse one line of LIST output. The line is an array of len characters stored in buf. It should not include the terminating CR LF; so buf[len] is typically CR. If ftpparse() can't find a filename, it returns 0. If ftpparse() can find a filename, it fills in fp and returns 1. fp is a struct ftpparse, defined below. The name is an array of fp.namelen characters stored in fp.name; fp.name points somewhere within buf. */ struct ftpparse { char *name; /* not necessarily 0-terminated */ int namelen; int flagtrycwd; /* 0 if cwd is definitely pointless, 1 otherwise */ int flagtryretr; /* 0 if retr is definitely pointless, 1 otherwise */ int sizetype; long size; /* number of octets */ int mtimetype; time_t mtime; /* modification time */ int idtype; char *id; /* not necessarily 0-terminated */ int idlen; } ; #define FTPPARSE_SIZE_UNKNOWN 0 #define FTPPARSE_SIZE_BINARY 1 /* size is the number of octets in TYPE I */ #define FTPPARSE_SIZE_ASCII 2 /* size is the number of octets in TYPE A */ #define FTPPARSE_MTIME_UNKNOWN 0 #define FTPPARSE_MTIME_LOCAL 1 /* time is correct */ #define FTPPARSE_MTIME_REMOTEMINUTE 2 /* time zone and secs are unknown */ #define FTPPARSE_MTIME_REMOTEDAY 3 /* time zone and time of day are unknown */ /* When a time zone is unknown, it is assumed to be GMT. You may want to use localtime() for LOCAL times, along with an indication that the time is correct in the local time zone, and gmtime() for REMOTE* times. */ #define FTPPARSE_ID_UNKNOWN 0 #define FTPPARSE_ID_FULL 1 /* unique identifier for files on this FTP server */ extern int ftpparse(struct ftpparse *,char *,int); #endif wvstreams-4.6.1/include/wvoakley.h0000644000175000001440000000127611036722347016242 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2003 Net Integration Technologies, Inc. * * Diffie-Hellman shared secret creation. */ #ifndef __WVOAKLEY_H #define __WVOAKLEY_H #include "wvstream.h" #include "wvdiffiehellman.h" class WvOakleyAuth { public: WvOakleyAuth(int group); short public_len(); short other_pub_len(); short get_public_key(WvBuf &outbuf, short len); short get_other_public_key(WvBuf &outbuf, short len); void create_secret(WvBuf &_other_pub_key, short len); WvDynBuf dh_secret; private: WvDiffieHellman *dh; short pub_len, other_len; short secret_len; WvDynBuf other_pub_key; }; #endif /* __WVOAKLEY_H */ wvstreams-4.6.1/include/wvtimeutils.h0000644000175000001440000000464511077124114016771 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #ifndef __WVTIMEUTILS_H #define __WVTIMEUTILS_H #ifdef _WIN32 #include "winsock2.h" #include int gettimeofday(struct timeval *tv, struct timezone *tz); #else #include #endif /** Based on (and interchangeable with) struct timeval. */ class WvTime : public timeval { public: WvTime() { } // WARNING: leaves members uninitialized, like timeval would do! WvTime(long long t) { tv_sec = long(t/1000000L); tv_usec = long(t%1000000L); } WvTime(time_t sec, time_t usec) { tv_sec = long(sec); tv_usec = long(usec); } WvTime(const struct timeval &tv) { tv_sec = tv.tv_sec; tv_usec = tv.tv_usec; } WvTime(const WvTime &tv) { tv_sec = tv.tv_sec; tv_usec = tv.tv_usec; } operator long long() const { return ((long long)tv_sec)*1000000LL + tv_usec; } }; static const WvTime wvtime_zero(0, 0); /** Returns the number of milliseconds between times a and b (ie a-b). * Value returned is not rounded, it is chopped via integer division * For example: if the result of the subtraction is 0.9, the returned * value is 0 if the result is -0.9, the result is also 0. */ time_t msecdiff(const WvTime &a, const WvTime &b); /** Returns the current time of day. */ WvTime wvtime(); /** Adds the specified number of milliseconds to a time value. */ WvTime msecadd(const WvTime &a, time_t msec); /** Returns the timeval difference between two timevals (ie a-b). */ WvTime tvdiff(const WvTime &a, const WvTime &b); /** Normalizes the time value. * This means that any two 'equally valued' timevals will be converted * so that the seconds and the microseconds are the same in each timeval. */ inline void normalize(WvTime &tv) { tv.tv_sec += tv.tv_usec < 0 ? (tv.tv_usec/1000000)-1 : tv.tv_usec/1000000; tv.tv_usec %= 1000000; tv.tv_usec += tv.tv_usec < 0 ? 1000000 : 0; } // Stepped time functions. Used to synchronize wvstreams. const WvTime &wvstime(); void wvstime_sync(); // This function is just like wvstime_sync(), but will never make the // time go backward. void wvstime_sync_forward(); // This sets the time returned by wvstime() to the specified value. To // be used for unit testing. void wvstime_set(const WvTime &); /** * Delay for a requested number of milliseconds. */ void wvdelay(int msec_delay); #endif // __WVTIMEUTILS_H wvstreams-4.6.1/include/wvblowfish.h0000644000175000001440000000502111036722347016563 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Blowfish cryptography abstractions. */ #ifndef __WVBLOWFISH_H #define __WVBLOWFISH_H #include "wvencoder.h" #include "wvencoderstream.h" struct bf_key_st; /** * An encoder implementing the Blowfish encryption method. * * Supports reset(). * */ class WvBlowfishEncoder : public WvEncoder { public: enum Mode { ECBEncrypt, /*!< Encrypt using ECB mode (avoid) */ ECBDecrypt, /*!< Decrypt using ECB mode (avoid) */ CFBEncrypt, /*!< Encrypt using CFB mode (simulates a stream) */ CFBDecrypt /*!< Decrypt using CFB mode (simulates a stream) */ }; /** * Creates a new Blowfish cipher encoder. * * "mode" is the encryption mode * "key" is the initial key * "keysize" is the initial key size in bytes */ WvBlowfishEncoder(Mode mode, const void *key, size_t keysize); virtual ~WvBlowfishEncoder(); /** * Sets the current Blowfish key and resets the initialization * vector to all nulls. * * "key" is the new key * "keysize" is the key size in bytes */ void setkey(const void *key, size_t keysize); /** * Sets the current Blowfish initialization vector. * * "iv" is the new IV must be 8 bytes */ void setiv(const void *iv); /** Return true if mode is encrypting or false if decrypting. */ bool is_encrypting() const { return (mode == ECBEncrypt || mode == CFBEncrypt); } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush); virtual bool _reset(); // supported: restores most recently set // key and initialization vector Mode mode; size_t keysize; unsigned char *key; struct bf_key_st *bfkey; unsigned char ivec[8]; // initialization vector int ivecoff; // current offset into initvec void preparekey(); }; /** * A crypto stream implementing Blowfish encryption. * * By default, written data is encrypted using * WvBlowfishEncoder::CFBEncrypt, read data is decrypted using * WvBlowfishEncoder::CFBDecrypt. * * @see WvBlowfishEncoder */ class WvBlowfishStream : public WvEncoderStream { public: WvBlowfishStream(WvStream *_cloned, const void *key, size_t _keysize, WvBlowfishEncoder::Mode readmode = WvBlowfishEncoder::CFBDecrypt, WvBlowfishEncoder::Mode writemode = WvBlowfishEncoder::CFBEncrypt); virtual ~WvBlowfishStream() { } }; #endif // __WVBLOWFISH_H wvstreams-4.6.1/include/wvstdstring.h0000644000175000001440000000131611036722347016772 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Some helper functions for WvString so it's more easily interchangeable * with std::string. These functions are in a separate include file so we * don't need a separate library *and* we don't need to #include in * wvstring.h. */ #ifndef __WVSTDSTRING_H #define __WVSTDSTRING_H #include "wvstring.h" inline WvFastString::WvFastString(const std::string &s) { construct(s.c_str()); } inline WvString::WvString(const std::string &s) { construct(s.c_str()); } #if 0 inline WvFastString::operator std::string() const { return cstr(); } #endif #endif // __WVSTDSTRING_H wvstreams-4.6.1/include/wvbellpull.h0000644000175000001440000000370311036722347016566 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #ifndef __WVBATCHSIGNAL_H #define __WVBATCHSIGNAL_H #include #include #include class WvInvertedStream: public WvStream { public: WvInvertedStream(char *_id): WvStream() { WvIStreamList::globallist.append(this, false, _id); } ~WvInvertedStream() { WvIStreamList::globallist.unlink(this); } }; /* * This class is a functor compatible with UniConfCallback, * IWvStreamCallback and WvStreamCallback, as well as supporting being * called with no parameters. * * It will turn any number of calls to any of these callbacks into a * single call to the callback you give to it, which will be sent on * the next run through the main loop. * * Think of it as an elevator button: pressing it a bunch of times has * no more effect than pressing it once, and while it doesn't do what * you tell it right away, it will do it soon enough. */ class WvBellPull { public: WvBellPull(WvCallback<> _cb): cb(_cb), bellpull(new WvInvertedStream("bellpull")) { bellpull->setcallback( WvStreamCallback(this, &WvBellPull::bellpull_cb), NULL); } WvBellPull(const WvBellPull& _other): cb(_other.cb), bellpull(_other.bellpull) { bellpull->addRef(); } ~WvBellPull() { bellpull->release(); } void delay(time_t msec_timeout) { bellpull->alarm(msec_timeout); } void cancel() { bellpull->alarm(-1); } void operator()() { bellpull->alarm(0); } void operator()(IWvStream&) { bellpull->alarm(0); } void operator()(WvStream&, void*) { bellpull->alarm(0); } void operator()(const UniConf &, const UniConfKey &) { bellpull->alarm(0); } private: WvCallback<> cb; WvInvertedStream *bellpull; void bellpull_cb(WvStream&, void*) { cb(); } }; #endif /* __WVBATCHSIGNAL_H */ wvstreams-4.6.1/include/wvatomicfile.h0000644000175000001440000000220711036722347017065 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * A simple class to access filesystem files using WvStreams. */ #ifndef __WVATOMFILE_H #define __WVATOMFILE_H #include "wvfile.h" /** * WvAtomicFile implements a simple extension to wvfile to allow for * atomic file creation. Files normally can be created and written * to, however, in the event of a kernel panic the file can be left in * an unusable state. * * A WvAtomicFile is atomically created on file close * */ class WvAtomicFile : public WvFile { private: WvString atomic_file; WvString tmp_file; public: WvAtomicFile(WvStringParm filename, int flags = O_TRUNC | O_CREAT, mode_t create_mode = 0666); ~WvAtomicFile(); bool open(WvStringParm filename, int flags = O_TRUNC | O_CREAT, mode_t create_mode = 0666); void close(); // Like chmod(2), does *not* respect umask bool chmod(mode_t mode); bool chown(uid_t owner, gid_t group); public: const char *wstype() const { return "WvAtomicFile"; } }; #endif // __WVATOMFILE_H wvstreams-4.6.1/include/wvsslhacks.h0000644000175000001440000000223011077124114016551 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Functions to make us compile with both newer and older versions of openssl. * * The trick here is to write C wrappers for functions where different * versions of openssl have changed the pointer types of arguments: C * files only give warnings about mismatched pointers, where C++ files * fail completely. */ #ifndef __WVSSLHACKS_H #define __WVSSLHACKS_H #include #include #include #ifdef __cplusplus extern "C" { #endif RSA *wv_d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length); RSA *wv_d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length); DSA *wv_d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); DSA *wv_d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); X509_REQ *wv_d2i_X509_REQ(X509_REQ **a, const unsigned char **pp, long length); X509 *wv_d2i_X509(X509 **a, unsigned char **pp, long length); int wv_i2d_OCSP_REQUEST_bio(BIO *bio, OCSP_REQUEST *req); #ifdef __cplusplus }; #endif #endif // __WVSSLHACKS_H wvstreams-4.6.1/include/wvtask.h0000644000175000001440000000721711036722347015721 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A set of classes that provide co-operative multitasking support. By * default there's no scheduler -- you have to provide it yourself. As it * stands, this is just a convenient way to switch from one context to * another when you know exactly what you want to do. * * This is mainly intended for use by WvStream, but that's probably not the * only possible use... see also WvCont. */ #ifndef __WVTASK_H #define __WVTASK_H #ifdef _WIN32 #include "wvwin32task.h" #else #include "wvstring.h" #include "wvlinklist.h" #include "wvstreamsdebugger.h" #include "wvstringlist.h" #include "setjmp.h" #include #define WVTASK_MAGIC 0x123678 class WvTaskMan; /** Represents a single thread of control. */ class WvTask { friend class WvTaskMan; // you might think it would be useful to have this return an int, since // yield() and run() both return int. But that ends up being more // confusing than you think, because if you call task1->run(), and he // calls task2->run(), and task2 calls yield(), then task1->run() returns // the value *task2* passed to yield! So we avoid the confusion by not // using return values here, which discourages people from thinking of // them as return values. typedef void TaskFunc(void *userdata); static int taskcount, numtasks, numrunning; int magic_number, *stack_magic; WvString name; int tid; size_t stacksize; void *stack; bool running, recycled; WvTaskMan &man; ucontext_t mystate; // used for resuming the task ucontext_t func_call, func_return; TaskFunc *func; void *userdata; WvTask(WvTaskMan &_man, size_t _stacksize = 64*1024); public: virtual ~WvTask(); void start(WvStringParm _name, TaskFunc *_func, void *_userdata); bool isrunning() const { return running; } void recycle(); int get_tid() const { return tid; } WvString get_name() const { return name; } }; DeclareWvList(WvTask); /** Provides co-operative multitasking support among WvTask instances. */ class WvTaskMan { friend class WvTask; static WvTaskMan *singleton; static int links; static int magic_number; static WvTaskList all_tasks, free_tasks; static void get_stack(WvTask &task, size_t size); static void stackmaster(); static void _stackmaster(); static void do_task(); static void call_func(WvTask *task); static char *stacktop; static ucontext_t stackmaster_task; static WvTask *stack_target; static ucontext_t get_stack_return; static WvTask *current_task; static ucontext_t toplevel; WvTaskMan(); virtual ~WvTaskMan(); #ifdef ENABLE_DELETE_DETECTOR friend void operator &&(CheckIObject, const WvTaskMan *); #endif public: /// get/dereference the singleton global WvTaskMan static WvTaskMan *get(); static void unlink(); WvTask *start(WvStringParm name, WvTask::TaskFunc *func, void *userdata, size_t stacksize = 64*1024); // run() and yield() return the 'val' passed to run() when this task // was started. static int run(WvTask &task, int val = 1); static int yield(int val = 1); static WvTask *whoami() { return current_task; } static const void *current_top_of_stack(); static size_t current_stacksize_limit(); private: static WvString debugger_tasks_run_cb(WvStringParm, WvStringList &, WvStreamsDebugger::ResultCallback, void *); }; #endif // ifdef _WIN32 #endif // __WVTASK_H wvstreams-4.6.1/include/wvipnetlist.h0000644000175000001440000000045211036722347016764 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Declares WvIPNetList * */ #ifndef __WVIPNETLIST_H #define __WVIPNETLIST_H #include "wvlinklist.h" #include "wvaddr.h" DeclareWvList(WvIPNet); #endif // __WVIPNETLIST_H wvstreams-4.6.1/include/wvtcp.h0000644000175000001440000000671311036722347015545 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStream-based TCP connection and server classes. */ #ifndef __WVTCP_H #define __WVTCP_H #include "wvautoconf.h" #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #include "wvfdstream.h" #include "wvaddr.h" #include "wvresolver.h" class WvTCPListener; /** * WvTCPConn tries to make all outgoing connections asynchronously (in * the background). You can tell the connection has been established * when a select() call returns 'true' with writable==true. */ class WvTCPConn : public WvFDStream { friend class WvTCPListener; protected: bool resolved, connected; WvString hostname; bool incoming; WvIPPortAddr remaddr; WvResolver dns; /** Start a WvTCPConn on an already-open socket (used by WvTCPListener) */ WvTCPConn(int _fd, const WvIPPortAddr &_remaddr); /** Connect to the remote end - note the "Protected" above ;) */ void do_connect(); /** Resolve the remote address, if it was fed in non-IP form */ void check_resolver(); public: /** * WvTCPConn tries to make all outgoing connections asynchronously (in * the background). You can tell the connection has been established * when a select() call returns 'true' with writable==true. */ WvTCPConn(const WvIPPortAddr &_remaddr); /** Resolve the hostname, then connect a new socket */ WvTCPConn(WvStringParm _hostname, uint16_t _port = 0); /** * Destructor - rarely do you need to call this - close() * is a much better way to tear down a TCP Stream ;) */ virtual ~WvTCPConn(); /** * function to set up a TCP socket the way we like * (Read/Write, Non-Blocking, KeepAlive) */ void nice_tcpopts(); /** * function to set up a TCP socket the way we like * In addition to the nice_tcpopts(), set TCP_NODELAY */ void low_delay(); /** * function to set up a TCP socket the way we *don't* like: turn the * timeouts way down so that network errors show up easily for debugging */ void debug_mode(); /** * the local address of this socket (ie. from getsockname()) * really useful only for transparent proxies, but always available. * may be 0.0.0.0 if we did not bind explicitly! */ WvIPPortAddr localaddr(); /** * return the remote address (source of all incoming packets), * which is a constant for any given TCP connection. */ virtual const WvIPPortAddr *src() const; /** has the connection been completed yet? */ bool isconnected() const { return connected; } /** override pre_select() to cause select() results when resolving names. */ virtual void pre_select(SelectInfo &si); /** * override post_select() to set the 'connected' variable as soon as we * are connected. */ virtual bool post_select(SelectInfo &si); /** * Is this connection OK? * Note: isok() will always be true if !resolved, even though fd==-1. */ virtual bool isok() const; protected: virtual size_t uwrite(const void *buf, size_t count); public: const char *wstype() const { return "WvTCPConn"; } }; #endif // __WVTCP_H wvstreams-4.6.1/include/wvunixlistener.h0000644000175000001440000000220711203076532017474 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVUNIXLISTENER_H #define __WVUNIXLISTENER_H #include "wvlistener.h" #include "wvaddr.h" #ifndef _WIN32 /** Server end of a Unix Sockets stream */ class WvUnixListener : public WvListener { public: WvUnixListener(const WvUnixAddr &_addr, int create_mode); virtual ~WvUnixListener(); virtual void close(); /** * return a new WvUnixConn socket corresponding to a newly-accepted * connection. If no connection is ready immediately, we wait for * one indefinitely. You can use select(read=true) to check for a * waiting connection. */ IWvStream *accept(); /** src() is a bit of a misnomer, but it returns the socket address. */ virtual const WvUnixAddr *src() const; protected: WvUnixAddr addr; bool bound_okay; void accept_callback(WvIStreamList *list, wv::function cb, IWvStream *_connection); public: const char *wstype() const { return "WvUnixListener"; } }; #endif // _WIN32 #endif // __WVUNIXLISTENER_H wvstreams-4.6.1/include/uniconf.h0000644000175000001440000004251411036722347016042 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines a hierarchical registry abstraction. */ #ifndef __UNICONF_H #define __UNICONF_H #include #include "uniconfgen.h" #include "uniconfkey.h" #include "wvtr1.h" class WvStream; class UniConf; class UniConfRoot; /** * The callback type for signalling key changes from UniConf. * * Parameters: cfg, relkey * cfg - the UniConf config object representing the key that has changed * relkey - the changed keypath, relative to the config object */ typedef wv::function UniConfCallback; /** * UniConf instances function as handles to subtrees of a UniConf * tree and expose a high-level interface for clients. * * All operations are marked "const" unless they modify the target * of the handle. In effect, this grants UniConf handles the * same semantics as pointers where a const pointer may point * to a non-const object, which simply means that the pointer * cannot be reassigned. * * When handles are returned from functions, they are always marked * const to guard against accidentally assigning to a temporary by * an expression such as cfg["foo"] = cfg["bar"]. * Instead this must be written as * cfg["foo"].setme(cfg["bar"].getme()) * which is slightly * less elegant but avoids many subtle mistakes. Also for this * reason, unusual cast operators, assignment operators, * or copy constructors are not provided. Please do not add any. * */ class UniConf { friend class UniConfRoot; protected: UniConfRoot *xroot; UniConfKey xfullkey; /** * Creates a handle to the specified subtree of the given root. * * You can't create non-NULL UniConf objects yourself - ask UniConfRoot * or another UniConf object to make one for you. */ UniConf(UniConfRoot *root, const UniConfKey &fullkey = UniConfKey::EMPTY); public: /** Creates a NULL UniConf handle, useful for reporting errors. */ UniConf(); /** Copies a UniConf handle. */ UniConf(const UniConf &other); /** Destroys the UniConf handle. */ virtual ~UniConf(); /***** Handle Manipulation API *****/ /** Returns a handle to the root of the tree. */ UniConf root() const { return UniConf(xroot, UniConfKey::EMPTY); } /** Returns a handle to the parent of this node. */ UniConf parent() const { return UniConf(xroot, xfullkey.removelast()); } /** * Returns a pointer to the UniConfRoot that manages this node. * This may be NULL, to signal an invalid handle. */ UniConfRoot *rootobj() const { return xroot; } /** Returns true if the handle is invalid (NULL). */ bool isnull() const { return xroot == NULL; } /** Returns the full path of this node, starting at the root. */ UniConfKey fullkey() const { return xfullkey; } /** Returns the full path of this node, starting at the given key. * Assumes that k is an ancestor of fullkey(). */ UniConfKey fullkey(const UniConfKey &k) const; /** Returns the full path of this node, starting at the given handle. */ UniConfKey fullkey(const UniConf &cfg) const { return fullkey(cfg.fullkey()); } /** Returns the path of this node relative to its parent. */ UniConfKey key() const { return xfullkey.last(); } /** * Returns a handle for a subtree below this key. 'key' is the path * of the subtree to be appended to the full path of this handle to * obtain the full path of the new handle. */ const UniConf operator[] (const UniConfKey &key) const { return UniConf(xroot, UniConfKey(xfullkey, key)); } /** * Return a subtree handle (see operator[]). Mainly to support bindings * for languages that can't handle methods named []. */ const UniConf u(const UniConfKey &key) const { return (*this)[key]; } /** Reassigns the target of this handle to match a different one. */ UniConf &operator= (const UniConf &other) { xroot = other.xroot; xfullkey = other.xfullkey; return *this; } /***** Key Retrieval API *****/ /** See UniConfGen::prefetch(). */ void prefetch(bool recursive) const; /** * Fetches the string value for this key from the registry. If the * key is not found, returns 'defvalue' instead. */ WvString getme(WvStringParm defvalue = WvString::null) const; /** A different way to say cfg.getme(): use *cfg instead. */ WvString operator* () const { return getme(); } /** A different way to say cfg.getme().num(): use cfg->num() instead. */ WvStringStar operator -> () const { return getme(); } /** A different way to say cfg[x].getme(y). */ WvString xget(WvStringParm key, WvStringParm defvalue = WvString::null) const { return (*this)[key].getme(defvalue); } /** * Fetches the integer value for this key from the registry. If the * key is not found, returns 'defvalue' instead. (This is also used to * fetch booleans - 'true', 'yes', 'on' and 'enabled' are recognized as * 1, 'false', 'no', 'off' and 'disabled' as 0. Note that a nonexistant * key is false by default.) */ int getmeint(int defvalue = 0) const; /** A different way to say cfg[x].getmeint(y). */ int xgetint(WvStringParm key, int defvalue = 0) const { return (*this)[key].getmeint(defvalue); } /** * Without fetching its value, returns true if this key exists. * * This is provided because it is often more efficient to * test existance than to actually retrieve the value. */ bool exists() const; /***** Key Storage API *****/ /** * Stores a string value for this key into the registry. If the value * is WvString::null, deletes the key and all of its children. */ void setme(WvStringParm value) const; /** * Stores a string value for this key into the registry. */ void setme(WVSTRING_FORMAT_DECL) const { return setme(WvString(WVSTRING_FORMAT_CALL)); } /** A different way to say cfg[x].setme(y). */ void xset(WvStringParm key, WvStringParm value) const { (*this)[key].setme(value); } /** * Stores an integer value for this key into the registry. */ void setmeint(int value) const; /** A different way to say cfg[x].setme(y). */ void xsetint(WvStringParm key, int value) const { (*this)[key].setmeint(value); } /***** Key Handling API *****/ /** * Equivalent to "mv" in a standard unix filesystem. This recursively * moves a given key and any subkeys to a new point. If the new point * exists then the key will be left as a subkey at the new point. * Otherwise, the key will also be renamed to the new point (as when * using mv). * * Don't try to do dumb stuff like making dst a subkey of this one, * or vice versa, because we won't try to save you. * * Unlike unix mv(), this is *not* currently atomic. It's more like * cp-then-rm. */ void move(const UniConf &dst) const; /** * Removes this key and all of its children from the registry. */ void remove() const { setme(WvString::null); } /** * Equivalent to "cp -r" in a standard unix filesystem. This * recursively copies a given key to a new location. Any keys that * already exist at that location will not be overridden unless force * is true. * * Don't try to do dumb stuff like making dst a subkey of this one, * or vice versa, because we won't try to save you. */ void copy(const UniConf &dst, bool force) const; /***** Key Persistence API *****/ /** * Refreshes information about this key recursively. * May discard uncommitted data. * Returns true on success. */ bool refresh() const; /** * Commits information about this key recursively. */ void commit() const; /***** Generator Mounting API *****/ /** * Mounts a generator at this key using a moniker. * * If 'refresh' is true, automatically refresh()es the generator * after mounting. * * Returns the mounted generator, or NULL on failure. */ IUniConfGen *mount(WvStringParm moniker, bool refresh = true) const; /** * Mounts a generator at this key. * * Takes ownership of the supplied generator instance. * * If 'refresh' is true, automatically refresh()es the generator * after mounting. * * Returns the mounted generator, or NULL on failure. */ IUniConfGen *mountgen(IUniConfGen *gen, bool refresh = true) const; /** Unmounts the generator providing this key and destroys it. */ void unmount(IUniConfGen *gen, bool commit) const; /** Determines if any generators are mounted at this key. */ bool ismountpoint() const; /** Returns true if the generator at this key isok(). */ bool isok() const; /** * Finds the generator that owns this key. * * If the key exists, returns the generator that provides its * contents. Otherwise returns the generator that would be * updated if a value were set. * * If non-NULL, 'mountpoint' is set to the actual key where the generator * is mounted. */ IUniConfGen *whichmount(UniConfKey *mountpoint = NULL) const; /***** Notification API *****/ /** * Requests notification when any of the keys covered by the * recursive depth specification change by invoking a callback. * * As a programmer, you probably DO NOT want to use this. Use * UniWatchList.add() instead. Otherwise, make sure you call * del_callback at the appropriate time. */ void add_callback(void *cookie, const UniConfCallback &callback, bool recurse = true) const; /** * Cancels notification requested using add_callback(). */ void del_callback(void *cookie, bool recurse = true) const; /** * Requests notification when any of the keys covered by the * recursive depth specification change by setting a flag. */ void add_setbool(bool *flag, bool recurse = true) const; /** * Cancels notification requested using add_setbool(). */ void del_setbool(bool *flag, bool recurse = true) const; /** * Pauses notifications until matched with a call to unhold_delta(). * * While paused, notification events are placed into a pending list. * Redundant notifications may be discarded. * * Use this to safeguard non-reentrant code. */ void hold_delta(); /** * Resumes notifications when each hold_delta() has been matched. * * On resumption, dispatches all pending notifications except * those that were destined to watches that were removed. * * Use this to safeguard non-reentrant code. */ void unhold_delta(); /** * Clears the list of pending notifications without sending them. * Does not affect the hold nesting count. */ void clear_delta(); /** * Flushes the list of pending notifications by sending them. * Does not affect the hold nesting count. */ void flush_delta(); /***** Key Enumeration API *****/ /** * Prints the entire contents of this subtree to a stream. * If 'everything' is true, also prints empty values. */ void dump(WvStream &stream, bool everything = false) const; /** * Returns true if this key has children. * * This is provided because it is often more efficient to * test existance than to actually retrieve the keys. */ bool haschildren() const; /*** Iterators (see comments in class declaration) ***/ // internal base class for all of the key iterators class IterBase; // iterates over direct children class Iter; // iterates over all descendents in preorder traversal class RecursiveIter; // iterates over children matching a wildcard class XIter; // internal base class for sorted key iterators class SortedIterBase; // sorted variant of Iter class SortedIter; // sorted variant of RecursiveIter class SortedRecursiveIter; // sorted variant of XIter class SortedXIter; // lists of iterators DeclareWvList(Iter); }; /** * An implementation base class for key iterators. */ class UniConf::IterBase { protected: UniConf top; UniConf current; IterBase(const UniConf &_top) : top(_top) { } public: const UniConf *ptr() const { return ¤t; } WvIterStuff(const UniConf); }; /** * This iterator walks through all immediate children of a UniConf node. */ class UniConf::Iter : public UniConf::IterBase { UniConfGen::Iter *it; public: /** Creates an iterator over the direct children of a branch. */ Iter(const UniConf &_top); ~Iter() { delete it; } void rewind() { it->rewind(); } bool next() { if (!it->next()) return false; current = top[it->key()]; return true; } // FIXME: this is a speed optimization only. Don't use this unless // you're apenwarr. It will change. WvString _value() const { return it->value(); } }; /** * This iterator performs depth-first traversal of a subtree. */ class UniConf::RecursiveIter : public UniConf::IterBase { UniConfGen::Iter *it; public: /** Creates a recursive iterator over a branch. */ RecursiveIter(const UniConf &_top); ~RecursiveIter() { delete it; } void rewind() { it->rewind(); } bool next() { if (!it->next()) return false; current = top[it->key()]; return true; } // FIXME: this is a speed optimization only. Don't use this unless // you're apenwarr. It will change. WvString _value() const { return it->value(); } }; /** * This iterator walks over all children that match a wildcard * pattern. * * See UniConfKey::matches(const UniConfKey&) for information about patterns. * * Example patterns: (where STAR is the asterisk character, '*') * * "": a null iterator * "a": matches only the key "a" if it exists * "STAR": matches all direct children * "STAR/foo": matches any existing key "foo" under direct children * "STAR/STAR": matches all children of depth exactly 2 * "foo/...": matches all keys including and below "foo" * "foo/STAR/...": matches all keys below "foo" * ".../foo/STAR": matches all keys below any subkey named "foo" in the tree */ class UniConf::XIter : public UniConf::IterBase { UniConfKey pathead; UniConfKey pattail; UniConf::XIter *subit; UniConf::Iter *it; /*!< iterator over direct children */ UniConf::RecursiveIter *recit; /*!< iterator over descendents */ bool ready; /*!< next key is ready */ public: /** Creates a wildcard iterator. */ XIter(const UniConf &_top, const UniConfKey &pattern); ~XIter(); void rewind(); bool next(); private: void cleanup(); bool qnext(); void enter(const UniConf &child); }; /** * An implementation base class for sorted key iterators. * * Unfortunately WvSorter is too strongly tied down to lists and pointers * to be of use here. The main problem is that UniConf::Iter and company * return pointers to temporary objects whereas WvSorter assumes that the * pointers will remain valid for the lifetime of the iterator. */ class UniConf::SortedIterBase : public UniConf::IterBase { public: typedef int (*Comparator)(const UniConf &a, const UniConf &b); /** Default comparator. Sorts alphabetically by full key. */ static int defcomparator(const UniConf &a, const UniConf &b); SortedIterBase(const UniConf &_top, Comparator comparator = defcomparator); ~SortedIterBase(); bool next(); private: Comparator xcomparator; int index; int count; void _purge(); void _rewind(); protected: std::vector xkeys; template void populate(Iter &i) { _purge(); for (i.rewind(); i.next(); ) xkeys.push_back(*i); _rewind(); } }; /** * A sorted variant of UniConf::Iter. */ class UniConf::SortedIter : public UniConf::SortedIterBase { UniConf::Iter i; public: SortedIter(const UniConf &_top, Comparator comparator = defcomparator) : SortedIterBase(_top, comparator), i(_top) { } void rewind() { populate(i); } }; /** * A sorted variant of UniConf::RecursiveIter. */ class UniConf::SortedRecursiveIter : public UniConf::SortedIterBase { UniConf::RecursiveIter i; public: SortedRecursiveIter(const UniConf &_top, Comparator comparator = defcomparator) : SortedIterBase(_top, comparator), i(_top) { } void rewind() { populate(i); } }; /** * A sorted variant of UniConf::XIter. */ class UniConf::SortedXIter : public UniConf::SortedIterBase { UniConf::XIter i; public: SortedXIter(const UniConf &_top, const UniConfKey &pattern, Comparator comparator = defcomparator) : SortedIterBase(_top, comparator), i(_top, pattern) { } void rewind() { populate(i); } }; #endif // __UNICONF_H wvstreams-4.6.1/include/wvtr1.h0000644000175000001440000000167711036722347015471 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Provide some aliases for TR1 stuff, with a fallback on Boost. */ #ifndef __WVTR1_H #define __WVTR1_H #include "wvautoconf.h" #if defined(HAVE_TR1_FUNCTIONAL) #include #include namespace wv { using std::tr1::bind; using std::tr1::cref; using std::tr1::function; using std::tr1::ref; using std::tr1::shared_ptr; } namespace { using namespace std::tr1::placeholders; } #elif defined(HAVE_BOOST_FUNCTION_HPP) #include #include #include namespace wv { using boost::bind; using boost::cref; using boost::function; using boost::ref; using boost::shared_ptr; } #else /* We have neither TR1 or Boost, punt. */ #error "One of TR1 or Boost is required to use WvStreams" #endif #endif /* __WVTR1_H */ wvstreams-4.6.1/include/wvwin32-sanitize.h0000644000175000001440000000175611036722347017547 0ustar wlachusers#ifndef __WIN32_SANITIZE_H #define __WIN32_SANITIZE_H #ifdef __GNUC__ #include "wvautoconf.h" #endif #include #include #include #include #include #include #ifndef _SYS_GUID_OPERATOR_EQ_ #define _SYS_GUID_OPERATOR_EQ_ 1 #endif #ifndef SIGALRM #define SIGALRM 14 #endif #ifndef SIGPIPE #define SIGPIPE 13 #endif #ifndef ECONNREFUSED #define ECONNREFUSED WSAECONNREFUSED #endif #ifndef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK #endif typedef int socklen_t; #ifdef __cplusplus extern "C" { #endif unsigned int sleep(unsigned int secs); extern pid_t getpid(); unsigned int alarm(unsigned int t); int fsync(int fd); #ifdef __cplusplus } #endif // refer to _wvinitialize to ensure that we suck in some stuff that makes // wvstreams actually work properly. #ifdef __cplusplus extern void *_wvinitialize; static void *_wvinitialize_local = _wvinitialize; #endif // #define _alloca(x) alloca(x) #endif // __WIN32_SANITIZE_H wvstreams-4.6.1/include/if_arp.h0000644000175000001440000001054011036722347015633 0ustar wlachusers/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * Global definitions for the ARP (RFC 826) protocol. * * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988 * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. * Based on a version 1.0.1 04/16/93 taken from Linux * Ross Biro, * Fred N. van Kempen, * Florian La Roche, * Jonathan Layes * Arnaldo Carvalho de Melo ARPHRD_HWX25 * Stripped down by Net Integration Technologies, 2004 * Simon Law * Adrian Dewhurst * * This is just an interface, so it's public domain information. */ #ifndef _WV_IF_ARP_H #define _WV_IF_ARP_H /* ARP protocol HARDWARE identifiers. */ #define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */ #define ARPHRD_ETHER 1 /* Ethernet 10Mbps */ #define ARPHRD_EETHER 2 /* Experimental Ethernet */ #define ARPHRD_AX25 3 /* AX.25 Level 2 */ #define ARPHRD_PRONET 4 /* PROnet token ring */ #define ARPHRD_CHAOS 5 /* Chaosnet */ #define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ #define ARPHRD_DLCI 15 /* Frame Relay DLCI */ #define ARPHRD_ATM 19 /* ATM */ #define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */ #define ARPHRD_EUI64 27 /* EUI-64 */ #define ARPHRD_IPSEC 31 /* IPSec tunnel */ /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 #define ARPHRD_CSLIP 257 #define ARPHRD_SLIP6 258 #define ARPHRD_CSLIP6 259 #define ARPHRD_RSRVD 260 /* Notional KISS type */ #define ARPHRD_ADAPT 264 #define ARPHRD_ROSE 270 #define ARPHRD_X25 271 /* CCITT X.25 */ #define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */ #define ARPHRD_PPP 512 #define ARPHRD_CISCO 513 /* Cisco HDLC */ #define ARPHRD_HDLC ARPHRD_CISCO #define ARPHRD_LAPB 516 /* LAPB */ #define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */ #define ARPHRD_RAWHDLC 518 /* Raw HDLC */ #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ #define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */ #define ARPHRD_FRAD 770 /* Frame Relay Access Device */ #define ARPHRD_SKIP 771 /* SKIP vif */ #define ARPHRD_LOOPBACK 772 /* Loopback device */ #define ARPHRD_LOCALTLK 773 /* Localtalk device */ #define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */ #define ARPHRD_BIF 775 /* AP1000 BIF */ #define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */ #define ARPHRD_IPDDP 777 /* IP over DDP tunneller */ #define ARPHRD_IPGRE 778 /* GRE over IP */ #define ARPHRD_PIMREG 779 /* PIMSM register interface */ #define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */ #define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */ #define ARPHRD_ECONET 782 /* Acorn Econet */ #define ARPHRD_IRDA 783 /* Linux-IrDA */ /* ARP works differently on different FC media .. so */ #define ARPHRD_FCPP 784 /* Point to point fibrechannel */ #define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */ #define ARPHRD_FCPL 786 /* Fibrechannel public loop */ #define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */ /* 787->799 reserved for fibrechannel media types */ #define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */ /* ARP protocol opcodes. */ #define ARPOP_REQUEST 1 /* ARP request */ #define ARPOP_REPLY 2 /* ARP reply */ #define ARPOP_RREQUEST 3 /* RARP request */ #define ARPOP_RREPLY 4 /* RARP reply */ #define ARPOP_InREQUEST 8 /* InARP request */ #define ARPOP_InREPLY 9 /* InARP reply */ #define ARPOP_NAK 10 /* (ATM)ARP NAK */ /* ARP Flag values. */ #define ATF_COM 0x02 /* completed entry (ha valid) */ #define ATF_PERM 0x04 /* permanent entry */ #define ATF_PUBL 0x08 /* publish entry */ #define ATF_USETRAILERS 0x10 /* has requested trailers */ #define ATF_NETMASK 0x20 /* want to use a netmask (only for proxy entries) */ #define ATF_DONTPUB 0x40 /* don't answer this addresses */ #endif /* _WV_IF_ARP_H */ wvstreams-4.6.1/include/wvunixsocket.h0000644000175000001440000000372611036722347017154 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #ifndef __WVUNIXSOCKET_H #define __WVUNIXSOCKET_H #include "wvfdstream.h" #include "wvaddr.h" class WvIStreamList; class WvUnixListener; class WvUnixConn; #ifndef _WIN32 /** * WvStream-based Unix domain socket connection class. * * Unlike WvTCPConn, WvUnixConn makes connections synchronously because either * the remote server is there, or it isn't. For convenience, we'll just * ignore situations where it's a local server but still slow. * * FIXME: support SOCK_DGRAM mode somehow. This is a bit tricky since the * listener/connection separation doesn't make as much sense then. I guess we * could just ignore the listener or something... * * FIXME: use the weird credential-passing stuff to exchange pid, uid, and gid * with the remote end of the socket. See the unix(7) man page. This would * be very cool for authentication purposes. */ class WvUnixConn : public WvFdStream { friend class WvUnixListener; protected: WvUnixAddr addr; /** connect an already-open socket (used by WvUnixListener) */ WvUnixConn(int _fd, const WvUnixAddr &_addr); public: /** connect a new socket */ WvUnixConn(const WvUnixAddr &_addr); virtual ~WvUnixConn(); /** * the local address of this socket (ie. from getsockname()) * really useful only for transparent proxies, but always available. * may be 0.0.0.0 if we did not bind explicitly! */ const WvUnixAddr &localaddr() { return addr; } /** * return the remote address (source of all incoming packets), * which is a constant for any given connection. * This doesn't make much sense in Unix domain sockets, so we just * return localaddr() instead. */ virtual const WvUnixAddr *src() const; public: const char *wstype() const { return "WvUnixConn"; } }; #endif // _WIN32 #endif // __WVUNIXSOCKET_H wvstreams-4.6.1/include/wvfunctorencoder.h0000644000175000001440000000430011036722347017765 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Provides an encoder for applying a functor to data extracted * from a buffer and stored in another. * Assumes binary input is in machine order. */ #ifndef __WVFUNCTORENCODER_H #define __WVFUNCTORENCODER_H #include "wvtypedencoder.h" /** * Functor specifies the functor type which must have an operator() * with a signature compatible with invocations of the form: * const IT data = ...; * OT result = func(data); * * The best way to use this monster is to subclass with friendly * names for the implementations that are needed. For maximum * performance, define the functor as a struct that provides an * operator() inline. This is extremely efficent since this class is * templated, so there's room for lots of compiler optimization. * * "IT" is the input buffer datatype * "OT" is the output buffer datatype * "FT" is the functor type */ template class WvFunctorEncoder : public WvTypedEncoder { protected: FT f; public: typedef FT FType; typedef IT IType; typedef OT OType; typedef WvBufBase IBuffer; typedef WvBufBase OBuffer; WvFunctorEncoder(const FType &f) : f(f) { } virtual ~WvFunctorEncoder() { } protected: virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf, bool flush) { size_t count; while ( (count = inbuf.optgettable()) ) { size_t avail = outbuf.optallocable(); if (avail == 0) return ! flush; if (avail < count) count = avail; const IType *indata = inbuf.get(count); OType *outdata = outbuf.alloc(count); while (count-- > 0) *(outdata++) = f(*(indata++)); } return true; } virtual bool _reset() { // Assume most functor encoders will be stateless and therefore // support reset() implicitly. // If this is not the case, then override this method for // particular subclasses to return false. return true; } }; #endif // __WVFUNCTORENCODER_H wvstreams-4.6.1/include/wvstreamsdaemon.h0000644000175000001440000000715411203076660017615 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * High-level abstraction for creating daemon processes that do * nothing but listen on a list of WvStreams and add connections * to the global list. */ #ifndef __WVSTREAMSDAEMON_H #define __WVSTREAMSDAEMON_H #include "wvdaemon.h" #include "iwvstream.h" #include "wvistreamlist.h" /*! @brief WvStreamsDaemon - High-level abstraction for a daemon process that does nothing but add streams to the global list and execute it. This is generally what a modern WvStreams-based daemon should look like. The WvDaemonCallback function passed in the constructor is used to populate the globallist with streams that are necessary when the daemon starts, such as listening sockets. These streams are added using the WvStreamsDaemon::add_stream, WvStreamsDaemon::add_die_stream and WvStreamsDaemon::add_restart_stream members, the last two governing what happens to the daemon when the stream is !isok(). */ class WvStreamsDaemon : public WvDaemon { private: WvDaemonCallback callback; bool do_full_close; WvIStreamList streams; void init(WvDaemonCallback cb); protected: virtual void do_start(); virtual void do_run(); virtual void do_stop(); private: void restart_close_cb(IWvStream *s, const char *id); void die_close_cb(IWvStream *s, const char *id); public: //! Construct a new WvStreamsDaemon with given name and version, and //! use the cb function to populate the daemon with its initial streams WvStreamsDaemon(WvStringParm name, WvStringParm version, WvDaemonCallback cb) : WvDaemon(name, version, WvDaemonCallback(), WvDaemonCallback(), WvDaemonCallback()) { init(cb); } //! Add a stream to the daemon; don't do anything if it goes !isok(). //! This should be called from the WvDaemonCallback function //! passed to the constructor. void add_stream(IWvStream *istream, bool auto_free, const char *id); //! Add a stream to the daemon; the daemon will restart, re-populating //! the initial streams using the callback passed to the constructor, //! if the stream goes !isok(). //! This should be called from the WvDaemonCallback function //! passed to the constructor. void add_restart_stream(IWvStream *istream, bool auto_free, const char *id); //! Add a stream to the daemon; if the stream goes !isok() the daemon //! will exit. //! This should be called from the WvDaemonCallback function //! passed to the constructor. void add_die_stream(IWvStream *istream, bool auto_free, const char *id); //! If this member is called then any existing streams on the globallist //! added *after* the WvDaemonCallback was executed will be closed //! if the daemon restarts; otherwise, they will persist after the restart. void close_existing_connections_on_restart() { do_full_close = true; } //! Change the callback function and userdata void setcallback(WvDaemonCallback cb); private: //! Create some undefined overrides to prevent accidentally using a //! WvString as an id; these functions will keep a long-term reference to //! the string, so you should probably use a string constant. void add_stream(IWvStream *istream, bool auto_free, WvString id); void add_restart_stream(IWvStream *istream, bool auto_free, WvString id); void add_die_stream(IWvStream *istream, bool auto_free, WvString id); public: const char *wstype() const { return "WvStreamsDaemon"; } }; #endif // __WVSTREAMSDAEMON_H wvstreams-4.6.1/include/wvx509.h0000644000175000001440000002676211100156471015461 0ustar wlachusers/* -*- Mode: C++ -*- * * X.509 certificate class: This class abstracts some of the common operations * performed on basic X.509 certificates (signature verification, public * key identification, etc.). If you want to perform operations with * a certificate and its corresponding private key, consider using WvX509Mgr * instead. */ #ifndef __WVX509_H #define __WVX509_H #include "wvlog.h" #include "wverror.h" #include "wvrsa.h" #include "wvstringlist.h" // Structures to make the compiler happy so we don't have to include x509v3.h ;) struct x509_st; typedef struct x509_st X509; struct ssl_ctx_st; typedef struct ssl_ctx_st SSL_CTX; struct X509_name_st; typedef struct X509_name_st X509_NAME; struct asn1_string_st; typedef struct asn1_string_st ASN1_TIME; // workaround for the fact that OpenSSL initialization stuff must be called // only once. void wvssl_init(); void wvssl_free(); WvString wvssl_errstr(); /** * X509 Class to handle certificates and their related * functions */ class WvX509 : public IObject { IMPLEMENT_IOBJECT(WvX509); public: /** * Type for the @ref encode() and @ref decode() methods. * CertPEM = PEM Encoded X.509 Certificate * CertDER = DER Encoded X.509 Certificate * CertHex = DER Encoded X.509 Certificate in hexified form * CertFilePEM = PEM Encoded X.509 Certificate from file * CertFileDER = DER Encoded X.509 Certificate from file * * CertFilePEM and CertFileDER are only valid modes for @ref decode(), * calling encode with these modes will result in no effect. */ enum DumpMode { CertPEM = 0, CertDER, CertHex, CertFilePEM, CertFileDER }; enum FprintMode { FingerMD5 = 0, FingerSHA1 }; /** * Initialize a completely empty X509 Object with an X509 certificate * that doesn't have anything it it... good for building custom * certificates. */ WvX509(); /** * Initialize a blank X509 Object with the certificate *cert * (used for client side operations...) * * This either initializes a completely empty object, or takes _cert, * and extracts the distinguished name into dname, and the RSA * public key into rsa. rsa->prv is empty. */ WvX509(X509 *_cert); /** * Copy Constructor. */ WvX509(const WvX509 &x509); public: /** Destructor */ virtual ~WvX509(); /** * Allow us to access the certificate member - this will be going away * eventually, but for now, it gets us out of a couple of issues :/ */ X509 *get_cert() { return cert; } /** * Set the public key of the certificate to the public key rsa_pubkey. */ void set_pubkey(WvRSAKey &rsa_pubkey); /** * Create a certificate request (PKCS#10) using this function.. this * request is what you would send off to Verisign, or Entrust.net (or any * other CA), to get your real certificate. It leaves the RSA key pair * in rsa, where you MUST save it for the certificate to be AT ALL * valid when you get it back. Returns a PEM Encoded PKCS#10 certificate * request, and leaves the RSA keypair in rsa. */ static WvString certreq(WvStringParm subject, const WvRSAKey &rsa); /** * Function to verify the validity of a certificate that has been * placed in cert. It checks and make sure that it was signed by * the CA certificate cacert, as well as that it is not expired (or * not yet valid). */ bool validate(WvX509 *cacert = NULL) const; /** * Check the certificate in cert against the CA certificate in cacert * - returns true if cert was signed by that CA certificate. */ bool signedbyca(WvX509 &cacert) const; /** * Check to see if the certificate in cert was issued by the CA * certificate in cacert. Note: You are going on the certificate's * say-so by using this function. You may also want to use signedbyca * to check if the certificate is actually signed by who it claims * to be issued by. */ bool issuedbyca(WvX509 &cacert) const; /** * Verify that the contents of data were signed * by the certificate currently in cert. This only * checks the signature, it doesn't check the validity * of the certificate. */ bool verify(WvBuf &original, WvStringParm signature) const; bool verify(WvStringParm original, WvStringParm signature) const; /** * Return the information requested by mode. */ WvString encode(const DumpMode mode) const; void encode(const DumpMode mode, WvBuf &buf) const; /** * Load the information from the format requested by mode into * the class - this overwrites the certificate. */ virtual void decode(const DumpMode mode, WvStringParm str); virtual void decode(const DumpMode mode, WvBuf &encoded); /** * Get and set the Certificate Issuer (usually the CA who signed * the certificate). */ WvString get_issuer() const; void set_issuer(WvStringParm name); void set_issuer(const WvX509 &cacert); /** * get and set the Subject field of the certificate */ WvString get_subject() const; void set_subject(WvStringParm name); void set_subject(X509_NAME *name); /** * get and set the serialNumber field of the certificate */ WvString get_serial(bool hex = false) const; void set_serial(long serial_no); /** * get and set the Netscape Comment extension */ WvString get_nscomment() const; void set_nscomment(WvStringParm comment); /** * get and set the Netscape SSL Server extension */ WvString get_nsserver() const; void set_nsserver(WvStringParm server_fqdn); /** * get the CRL Distribution points if they exist, WvString::null * if they don't. */ WvString get_crl_dp() const; /** * Get any certificate Policy OIDs. Returns true if the policy oids * extension is present, false otherwise. */ bool get_policies(WvStringList &policy_oids) const; /** * Set the Certificate Policy OIDs in the certificate to that of * the input array. */ void set_policies(WvStringList &policy_oids); /** * Set the Certificate to use X509v3, since that's all modern * PKI uses anyways :) */ void set_version(); /** * Get and set the keyUsage field. */ WvString get_key_usage() const; void set_key_usage(WvStringParm values); /** * Get and set the extendedKeyUsage field. */ WvString get_ext_key_usage() const; void set_ext_key_usage(WvStringParm values); /** * Return the Subject alt name if it exists, and WvString::null if * it doesn't. */ WvString get_altsubject() const; /** * Set the Subject Alt Name. */ void set_altsubject(WvStringParm name); /** * Get the values in the basic constraints extension. Returns true if the * basic constraints extension exists and is valid, false otherwise. */ bool get_basic_constraints(bool &ca, int &pathlen) const; /** * Set the values in the basic constraints extension. */ void set_basic_constraints(bool ca, int pathlen); /** * Get the values in the policy constraints extension. Returns true if the * policy constraints extension exists, false otherwise. */ bool get_policy_constraints(int &require_explicit_policy, int &inhibit_policy_mapping) const; /** * Set the values in the policy constraints extension. */ void set_policy_constraints(int require_explicit_policy, int inhibit_policy_mapping); struct PolicyMap { PolicyMap(WvStringParm _issuer_domain, WvStringParm _subject_domain) { issuer_domain = _issuer_domain; subject_domain = _subject_domain; } WvString issuer_domain; WvString subject_domain; }; DeclareWvList(PolicyMap); /** * Get the policy mappings for this certificate. Returns true if there * were any policy mappings to be found. */ bool get_policy_mapping(PolicyMapList &list) const; /** * Set the policy mappings for this certificate. */ void set_policy_mapping(PolicyMapList &list); /** * Return the not before and not after in a format we're more able to easily use. */ time_t get_notvalid_before() const; time_t get_notvalid_after() const; /** * Set the lifetime to be used for this certificate... the lifetime starts * from the minute that the certificate is signed... */ void set_lifetime(long seconds); /** * Get the authority info access information. Usually includes a list of URLs * where the issuer's CA certificate may be fetched, as well as a list of * OCSP responders. Note that this function returns this information in * a giant string: get_ca_urls and get_ocsp may return this information in a * more useful format. */ WvString get_aia() const; /** * Set a list of urls that have the Certificate of the CA that issued * this certificate, as well as the list of OCSP responders for this * certificate. */ void set_aia(WvStringList &ca_urls, WvStringList &responders); /** * Get a list of OCSP Responders for this certificate */ void get_ocsp(WvStringList &responders) const; /** * Get a list of urls that have the Certificate * of the CA that issued this certificate */ void get_ca_urls(WvStringList &urls) const; /** * Get a list of URLs that are valid CRL distribution * points for this certificate. */ void get_crl_urls(WvStringList &urls) const; /** * Set the list of URLs that are valid CRL distribution * points for this certificate. */ void set_crl_urls(WvStringList &urls); /** * Get the Subject Key Info */ WvString get_ski() const; /** * Get the Authority key Info */ WvString get_aki() const; /** * Get the certHash (fingerprint) of the certificate */ WvString get_fingerprint(const FprintMode mode = FingerSHA1) const; /** * Is the certificate object valid? */ virtual bool isok() const; /** * Returns an error string if isok() is not true. */ virtual WvString errstr() const; /** * The not operator returns true if !isok() */ bool operator! () const; private: friend class WvCRL; friend class WvX509Mgr; friend class WvOCSPReq; friend class WvOCSPResp; /** X.509v3 Certificate - this is why this class exists */ X509 *cert; mutable WvLog debug; /** * Get and the Extension information - returns NULL if extension doesn't exist * Used internally by all of the get_??? and set_??? functions (crl_dp, cp_oid, etc.). */ WvString get_extension(int nid) const; void set_extension(int nid, WvStringParm values); /** * Populate the Subject Key Info (from the public key) */ void set_ski(); /** * Populate the Authority key Info, based on the Subject Key Info in * cacert. */ void set_aki(const WvX509 &cacert); /** * Helper method to log an error message when we try to set an X509 value when * cert is null. */ void warningset(WvStringParm var); /** * Return a WvRSAKey filled with the public key from the * certificate in cert */ WvRSAKey *get_rsa_pub() const; }; #endif // __WVX509_H wvstreams-4.6.1/ChangeLog0000644000175000001440000044600311260431126014347 0ustar wlachuserscommit eccc25c3da04b39e13fa5c1675bbf609a46565ae Author: William Lachance Date: Tue Sep 29 12:11:42 2009 -0400 Slight cleanup to D-Bus detection in configure Put stuff that's only used inside an if, inside the if commit 135a5b682977d237e7e7e5c8cb0b044ab2328681 Merge: 663871d... 5faa73b... Author: William Lachance Date: Fri Sep 18 18:23:20 2009 -0400 Merge branch 'master' of git://github.com/apenwarr/wvstreams commit 5faa73bc30f0d4791f8f6ace7b0c3335ea66799c Author: Avery Pennarun Date: Fri Sep 18 16:16:35 2009 -0400 wvurl.cc: include ldap/ldaps default port numbers. As submitted by Patrick Patterson commit 663871dfe7d0f2c0d957a68852e3d9eada040017 Merge: 7bea740... 8abcbcf... Author: William Lachance Date: Tue Sep 15 15:53:51 2009 -0400 Merge git://github.com/apenwarr/wvstreams into apenwarr-integration commit 8abcbcf78070316395a32f797f1010721c909cfd Merge: a81ca7a... 658701e... Author: Avery Pennarun Date: Tue Sep 15 15:48:01 2009 -0400 Merge commit 'origin/master' * commit 'origin/master': git-grafts-setup: a script for fixing up the git history. Makefile: add 'autodep-test' target for testing autodependencies. Fix autodependencies, which were broken by changes to gen-cc. commit a81ca7a348c0f676dcbaf3ca53d78e77a759268a Author: Avery Pennarun Date: Tue Sep 15 15:47:17 2009 -0400 configure.ac: fix support for linking a dbus from wvbuild. commit 7bea7407661924d4fc59a66fe244211fa6bbec8d Merge: 000fd0a... 658701e... Author: William Lachance Date: Tue Sep 15 14:23:42 2009 -0400 Merge git://github.com/apenwarr/wvstreams into apenwarr-integration commit 000fd0a2ed1c6b86634f99435272612a2635964c Author: William Lachance Date: Tue Sep 15 14:14:41 2009 -0400 Using an external dbus through pkg-config should now work This common case was not working before due to a misuse of the DBUS_LIBS variable. We now set it in the right place, which will hopefully fix the problem. commit 658701e2494ed4d363799173699f83daa7b7ca41 Author: Avery Pennarun Date: Fri Jul 24 14:56:52 2009 -0400 git-grafts-setup: a script for fixing up the git history. The 'master' branch had a major bit of missing history (ie. everything before 2007) due to a mis-import by git-svn. This reattaches the missing history to make things more linear. Of course, all the svn merges aren't known by git to be merges, so 'git blame' will blame changes that appeared in a merge on the person who merged, rather than the person who originally wrote them. Oh well. commit 8166258e0e9acf88a775a5feb50d0ee4070b8deb Author: Avery Pennarun Date: Fri Jul 10 15:06:44 2009 -0400 Makefile: add 'autodep-test' target for testing autodependencies. People (including me, sometimes) keep on breaking header autodependencies and not noticing, and it wastes a lot of time. Now the Makefile has a self-test to ensure the dependencies are (at least basically) working correctly. 'make test' now depends on the autodep-test target so that you can't forget to run it. commit c47a91311b487bc2645d4bb9a28f20443bf16e41 Author: Avery Pennarun Date: Fri Jul 10 14:46:48 2009 -0400 Fix autodependencies, which were broken by changes to gen-cc. These were broken earlier during the attempted portability fixes to gen-cc by ppatters. All it *really* needed was a change of $() syntax to backquote syntax, but we got a terrible mess instead. commit 2da2550fec889b707e87931a01fcc096ba6027aa Author: William Lachance Date: Wed Jun 3 23:23:37 2009 -0400 Remove debugging messages around solaris/mac linking in wvrules.mk commit da0f399d1fb72771828874044f8a811e942e504a Author: William Lachance Date: Wed May 20 11:03:21 2009 -0700 Further changes to make wvstreams compile with gcc 4.4. In particular, the usage of strchr is overloaded with this new version of the compiler to enforce const correctness. Modify our type information accordingly. commit 37dee9bc3e821c9a96e2bf8c634fd134212782af Author: Avery Pennarun Date: Wed May 20 12:54:13 2009 -0400 Make WvStreams compile with gcc 4.4. Patch provided by jue . I test-compiled it on my system, but I don't have a way to confirm that it actually works in gcc 4.4. commit 7cf12b93bc867d80e019d94762d1aeda4a68f2d8 Author: Avery Pennarun Date: Thu May 14 18:58:03 2009 -0400 Fix win32 build problems. commit 60d813523ee65baccf0d81de364ec68e8b45e9ef Author: Avery Pennarun Date: Thu May 14 18:40:38 2009 -0400 Fix some problems with autoconf detection of the need for argp on win32. commit 0e44abbadb51fe8c7a2d46e9854322ee490d556a Author: Avery Pennarun Date: Thu May 14 17:45:07 2009 -0400 configure.ac: work correctly with static libdbus.a. Static libraries should be in LIBS, not LDFLAGS, because they have to come *after* the source/.o files. commit 33f6c7db187e4e9c890eb1b6aef2ebddab1686d6 Author: Avery Pennarun Date: Thu May 14 17:15:58 2009 -0400 Update wvtestrunner.pl->wvtestrun from the WvTest project. The main improvement, other than the shorter script name, is that we now report the amount of time taken by each test section. Particularly slow tests are highlighted in yellow or red, which helps to figure out (and hopefully improve) why 'make test' is taking so darn long. commit e30d8af13a5f6cef776e7947db02ef3761d0bece Author: Avery Pennarun Date: Thu May 14 17:12:34 2009 -0400 Fix several warnings that appear in gcc 4.3.2. None of them seem very important, but this leaves us "almost" warning-free There's still a scary warning that remains: crypto/wvsslhacks.c: In function ‘wv_i2d_OCSP_REQUEST_bio’: crypto/wvsslhacks.c:48: warning: function called through a non-compatible type crypto/wvsslhacks.c:48: note: if this code is reached, the program will abort I have no idea what it's talking about. 'make test' passes, at least, though I don't really know if it tests that function or not. commit e7a59777f53f1043f94e175b815e58e88ebf4c28 Author: William Lachance Date: Thu May 14 17:28:32 2009 -0300 Bump version to 4.6. commit ffef541a7f39432ff337702634409b82da384f02 Author: William Lachance Date: Thu May 14 17:24:39 2009 -0300 Remove deprecated and useless auto_accept API. For more information, see: http://groups.google.com/group/wvstreams-devel/browse_thread/thread/981ca4fb015fe90b/3aca4b7f7f630ab9?lnk=gst&q=auto_accept#3aca4b7f7f630ab9 Also remove example code from wvstreamsdaemon comment at the same time. I'm not comfortable having long-winded example code in comments, where it is not tested for workingness. There are no less than two wvstreams daemon tests that people can check out if they want something to build on. commit 1b2621c72dd208ac3af232d07c4d7c51f6f610df Merge: 65fb08c... 56b41a2... Author: William Lachance Date: Wed May 13 18:43:31 2009 -0300 Merge branch 'dbus-refactoring' commit 65fb08cb3b6de4b5a09338a7c1e8747867dd4b09 Author: Patrick Patterson Date: Wed Jan 7 05:45:10 2009 +0800 Ok - thanks to Avery, WvStreams Libraries and Tests now compile, run, and are generally happy. Signed-off-by: William Lachance commit b2b0d1a509b807e45a7ca033177a88b3a44d820c Author: Patrick Patterson Date: Mon Jan 5 10:01:38 2009 +0800 Add in a make target for debugging some of the crazy variables, and fix an embarrassing mistake in the evil gen-cc script. Signed-off-by: William Lachance commit eda58c0608b1ff4f9f3301c161bb3fdaa628d66a Author: Patrick Patterson Date: Mon Jan 5 05:52:36 2009 +0800 Ok - I've got most of the tests compiling now, but I'm still fighting with a couple of them. Signed-off-by: William Lachance commit af1e147293d6f9ff3734d153911b96f3b156a90e Author: Patrick Patterson Date: Mon Jan 5 05:01:32 2009 +0800 Ok - I think this has all of the bits working necessary to compile WvStreams on MacOS. Now, let's see if there are any of the unit tests that don't work... Signed-off-by: William Lachance commit cbb8f75cf55ca830be5fe574c2076d06acd7b115 Author: Patrick Patterson Date: Sun Jan 4 02:13:59 2009 +0800 A bunch of changes that make WvStreams mostly compile on MacOS. Still have a couple of issues with libwvstreams.so, but it's getting close. Signed-off-by: William Lachance commit 6fb411f70dfb9405be7d306dcd4fe6e2645024b7 Author: Patrick Patterson Date: Fri Dec 5 10:15:13 2008 +0800 Ok - since I'm in the mood for porting things, let's get the MACOS port going at the same time. This has the added advantage of finally cleaning up more of the argp stuff. What a mess. Signed-off-by: William Lachance commit 871133dc3d6fe7002a43212cecc2796dd9b248ba Author: Patrick Patterson Date: Fri Dec 5 03:53:21 2008 +0800 Fix up the argp configure script, and actually have it generated when you call autogen.sh Signed-off-by: William Lachance commit 08e9f1116fe2d215b3c6e8ce12b640e4096a1f4a Author: Patrick Patterson Date: Fri Dec 5 03:35:43 2008 +0800 Actually let the configure scripts tell which OS it is being built on, and then set the variables used correctly. Signed-off-by: William Lachance commit bf369c3c4e85b529cfc9b2a3b43b563ea5412aa1 Author: Patrick Patterson Date: Fri Dec 5 01:35:26 2008 +0800 Fix gen-cc so that the backtick also works on Linux. Signed-off-by: William Lachance commit c5962df89c2fe457a23ade4531a775c3036b290e Author: Patrick Patterson Date: Fri Dec 5 01:20:30 2008 +0800 A bunch of fixes to do a few things: First of which is to fix the distclean target to actually clean up argp stuff properly. Second is to add proper detection of AR for argp. Third is to begin Solaris port, and get it to the point where at least it compiles all of the code, and creates libwvstatic.a. Signed-off-by: William Lachance commit 56b41a2116b83e3cac492e21e1c324b2d984afaa Author: William Lachance Date: Wed May 13 16:25:50 2009 -0300 Link with dbus dynamically, and insist at least 1.2.14 be installed 1.2.14 is the first release with the symbols we need to do this. commit 28a24eb145931353bcd7ac49d48266eae80c9670 Author: William Lachance Date: Fri May 8 18:02:22 2009 -0300 Remove the old code that depends on a statically linked copy of D-Bus. On second thought, having two code paths like this is a recipe for insanity. commit ca788ceb74020fffab8762f6b2e92c7b094464da Author: William Lachance Date: Fri May 8 17:25:54 2009 -0300 Ensure our bytes are aligned before demarshalling them in D-Bus. The way we do this is rather gross (allocating a temporary buffer), but there's basically no other way of accomplishing this. commit cf54b4af7c5999195cf7bb4b73d6ba8dc9847633 Author: William Lachance Date: Wed Jan 14 13:38:52 2009 -0400 Bring back forward declaration of custom marshalling functions, minor cleanups. I've decided to keep the custom marshalling functions in wvdbusmarshal_c.c for now (as thin wrappers around calls into the actual dbus API), just in case we need them later. commit f1c71278289fc43084f5a8879f637ce1ef789799 Author: William Lachance Date: Wed Jan 14 13:21:44 2009 -0400 Add changes to wvdbus_marshal_c.c to only use (now public) dbus intefaces. commit 6e47d999d4c4fb91d43c35657da195b09fe3c6c9 Author: William Lachance Date: Tue Jan 13 21:26:02 2009 -0400 Start work on a branch of wvstreams which doesn't depend on dbus internals. We use a new (written by me) function in dbus to demarshal stuff. Marshalling stuff comes next. commit 3e1aac7e1afcee7465f05a182cf307af6d7400eb Author: William Lachance Date: Tue Dec 23 19:22:08 2008 -0400 Don't say that a temporary WvString object in a const char argument list. Not sure how this ever worked, quite frankly, but it sure was a giant bucket of fail on OpenSUSE 11.1. commit 70b45c90a7eb19d1cd0e6ada8c9455ec775a4ca5 Author: William Lachance Date: Tue Dec 23 19:21:33 2008 -0400 Fix inconsequential typo in unit test commit 60d4599d663e7c3b6f388b2663368d797802cda0 Author: William Lachance Date: Tue Dec 23 19:20:53 2008 -0400 insist on using a uint32 for the crc in adler32/crc32 in wvdigest. commit 6710e7ab297f740f4f6633554c4647209f95ce9e Author: William Lachance Date: Tue Dec 23 16:40:11 2008 -0400 Replace a few printfs with wvcon->prints, helps remove compiler warnings commit 8ad48ff26e5b076f81e280f563b748ab75147e55 Author: William Lachance Date: Mon Dec 22 16:56:02 2008 -0400 Bump version to 4.5.1, in preparation for a release. commit 0d0bb796573b4f8cc1ebca90c465feb8302bad19 Author: William Lachance Date: Mon Dec 22 16:53:57 2008 -0400 Remove non-existence install-xplc target from install dependancies. commit 178b4e70c960a6e1f2d8ee260df0f0e343fbb36c Author: William Lachance Date: Wed Dec 17 10:58:10 2008 -0400 Remove extern keyword from deserialize function. Not sure why it was ever there (extern for functions is just supposed to be a hint for humans), but it sure confused the heck out of gcc 4.3. commit e413f17001f825bd7ceb930135ae599cd168c688 Author: William Lachance Date: Wed Dec 17 10:05:28 2008 -0400 Remove Debian packaging from WvStreams. Packaging should be done downstream. commit c9b9a3082dbeaba28d95e2f70d868b0fdd58f259 Author: William Lachance Date: Wed Dec 17 08:49:59 2008 -0400 Make use of valgrind optional. Thanks to Peter Alfredson for the fix. commit d69b14e7fdb6af77828837e757d2442748135800 Author: William Lachance Date: Wed Dec 17 08:44:31 2008 -0400 Search for qt3 using pkg-config (in addition to the other methods). Thanks to Peter Alfredson for the fix. commit 8a573160ccbdbeee2706db4a3e6a4fe2429c029b Author: William Lachance Date: Wed Dec 17 08:42:38 2008 -0400 Makes configure see --with-dbus as the same as the default. We use pkg-config to get the libdir. Thanks to Peter Alfredson for the fix. commit d01ba5cfa8b4820de0c91c52650da73c82b73701 Author: William Lachance Date: Wed Dec 17 08:37:45 2008 -0400 Unbreak finding of qt3 in configure. Autoconf swallowed the []s so we would never find qt-3. Thanks to Peter Alfredson for the fix. commit bfea1cf4a126cdad3250dce204d4ba897cf7beac Author: William Lachance Date: Wed Dec 17 08:35:58 2008 -0400 Apply some fixes from Fedora for compilation on gcc 4.3. Thanks to Peter Alfredson for pointing this out. commit b4311f7f18d0c010e7efd83d14bb1578b80d76a3 Author: William Lachance Date: Wed Dec 17 08:26:19 2008 -0400 Use the moc that we find in configure, not the first one in path. Patch from Peter Alfredson of Gentoo. commit d19f208f2b86797e13bd2bba55cadb556cb135e4 Author: William Lachance Date: Wed Dec 17 08:24:29 2008 -0400 Apply fix to unbreak compilation by no longer setting obsolete sa_restorer flag See: https://bugzilla.redhat.com/show_bug.cgi?id=402531. Thanks to Peter Alfredson for pointing this out. commit 9aff60fa6d55a46440a8e4d6bf343753b2bdc1ec Author: Avery Pennarun Date: Mon Nov 24 17:28:39 2008 -0500 wvtestrunner: catch segfaults in the subprogram. wvtestrunner would notice if the subprogram returned a non-zero exit code, but not if it died on a signal. Thus, a unit test program dying on a segfault was considered a success. Oops! commit fedfb1c3e10781c250460206fb9a6f0c5b7a1cca Author: Avery Pennarun Date: Fri Nov 21 04:49:54 2008 -0500 Oops, fix unit tests to match my recent dbus bool/byte format changes. commit 331198b0e7007d82cf2863dc07eeac4a70c746f9 Merge: 73aa242... da6816d... Author: Avery Pennarun Date: Fri Nov 21 02:33:10 2008 -0500 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams * 'master' of ssh://repo.or.cz/srv/git/wvstreams: Make the copy constructor for WvX509 much more efficient. get_signing_cert in ocsp response returns a reference to a cert, not a pointer Fail more nicely when the "openssl" utility doesn't return correct results Add static method to allow conversion of the ocsp response enum to a string Fix incorrect comment in configure.ac Update debian packaging for WvStreams 4.5. Port over the new dist rule prototyped in wvdial. commit 73aa24224b81f3ed94cbf7ae8d6c19c6529fbabd Author: Avery Pennarun Date: Fri Nov 21 02:31:19 2008 -0500 wvdbusmsg: don't prepend 'y' or 'b' to bytes and booleans in get_str(). As pretty as it looks in debug output, it corrupts things for people who expect an "int8" to come out as a parseable numeric string. commit da6816d195169fe21bee1115c1516860a5706376 Merge: 30bf6e9... 8012f6c... Author: William Lachance Date: Thu Oct 23 18:05:45 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 30bf6e907f65dd3921034972b07cf435a03cd121 Author: William Lachance Date: Thu Oct 23 17:54:40 2008 -0300 Make the copy constructor for WvX509 much more efficient. commit 06e9a94c95fcb6df9e760a00bd47a8e5ab4ccd1f Author: William Lachance Date: Thu Oct 23 17:48:17 2008 -0300 get_signing_cert in ocsp response returns a reference to a cert, not a pointer If there is no signing cert, the cert will be "bad" and !isok(). Also add an operator ! to WvX509 and WvX509Mgr for more concisely testing this sort of thing. commit 8012f6c3afb3e5cece40a86157a961bf46d52512 Author: Lukasz Kosewski Date: Thu Oct 23 18:55:17 2008 +0000 crypto/t/wvocsp.t.cc: Fail out if 'openssl' binary is missing. Without the 'openssl' binary, there is no way to run OCSP unit tests. If said binary isn't present fail and don't run the rest of the tests. commit 10441bae1a3b6660ecdb0e4afbfd010a4fd54890 Author: William Lachance Date: Thu Oct 23 15:42:45 2008 -0300 Fail more nicely when the "openssl" utility doesn't return correct results commit 4674e54ba05ffa814d44730f1f0c45ba76f74816 Author: William Lachance Date: Thu Oct 23 15:17:08 2008 -0300 Add static method to allow conversion of the ocsp response enum to a string commit e48b955ac4c78991a0049203ff5555244e34e262 Author: William Lachance Date: Thu Oct 23 15:16:57 2008 -0300 Fix incorrect comment in configure.ac commit 7ffa23d0e866fd691973937affef4a7352e6f575 Author: William Lachance Date: Wed Oct 22 19:22:00 2008 -0300 Update debian packaging for WvStreams 4.5. commit c9806257a5b1d1698e7de87aada88ff6deefa726 Author: Lukasz Kosewski Date: Thu Oct 23 13:40:07 2008 -0400 wvrules.mk: Stripped out xplc references here (missed them last time). commit c649de1097feda57102fb3b25479df7f596759e8 Author: Lukasz Kosewski Date: Thu Oct 23 13:10:43 2008 -0400 config.mk.in/configure-mingw32: Remove all traces of xplc configure. commit 42899a8c81cd27389ca709e965f02bfd55446060 Author: William Lachance Date: Wed Oct 22 18:36:03 2008 -0300 Port over the new dist rule prototyped in wvdial. We can now easily prepare pristine tarballs with a nice fat ChangeLog. Also, for wvstreams only (for now), invoke autogen.sh so that distributables have a configure. commit ead6b6a31d145788d940101c73efaa1370817c41 Merge: 5b21be4... 12e74a9... Author: William Lachance Date: Wed Oct 22 18:32:11 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 5b21be433dc5f07b97a83442237785bf08f0bc6a Author: William Lachance Date: Wed Oct 22 18:30:16 2008 -0300 Make module loader addition conform to XPLC's proper coding style Also don't bother initializing the temporary void * symbol. It's an out parameter, not an in/out. commit 12e74a90d859c82fe6d1f8d68e54bf3c656c84b8 Merge: 7d17c34... ada063d... Author: Avery Pennarun Date: Tue Oct 21 16:31:57 2008 -0400 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams into HEAD * 'master' of ssh://repo.or.cz/srv/git/wvstreams: Remove a useless, wrong comment. commit 7d17c34ab27077fa25d462ac530e11d862193854 Author: Avery Pennarun Date: Tue Oct 21 16:31:34 2008 -0400 win32: Disabled a couple of test programs that don't work in win32. commit ada063d112b26c0c1be0ea1f1b17798b348a85be Author: Peter McCurdy Date: Tue Oct 21 02:07:54 2008 -0400 Remove a useless, wrong comment. It was wrong both before and after the code it refers to was changed, but differently each time. Oops. This is a sign it wasn't really helpful. commit c9770de0f8452c51d34666fca6972f8660a7502f Author: William Lachance Date: Tue Oct 21 17:04:27 2008 -0300 Bump version to 4.5, in anticipation of a release. commit b1f489481b7fc98a87426f9a3f258ab0b886d141 Merge: 3996315... 9a2ac75... Author: William Lachance Date: Tue Oct 21 16:57:29 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 39963157bb141d26e4e9d8de836bef50eb137882 Author: William Lachance Date: Tue Oct 21 16:55:54 2008 -0300 Make url_encode take a set of "unsafe characters" instead of a regex Unfortunately wvregex is not supported on win32 so we'll have to do make do with something much more crude. In my case I only wanted to escape /'s and %'s (for url encoding uniconf keys in human readable form), and this will work fine for that. commit a8edda70b22ad922a2b3c7072baa532985c1afe6 Author: William Lachance Date: Tue Oct 21 16:29:54 2008 -0300 "dist" target works again. commit 5f8aed0df7a6874ade5b0da87bd2063f7c1d25ce Author: William Lachance Date: Tue Oct 21 16:29:30 2008 -0300 Make build depend on config.mk. commit 9a2ac757cbc41b4f6c7f8967a5b01375c50281da Author: Avery Pennarun Date: Tue Oct 21 14:44:31 2008 -0400 xplc needs a patch to compile correctly on win32 with gcc 3.4.5. (And maybe other gcc versions.) This patch was taken from wvports. commit 699aac46b50c001bb9236ef11a2219077d1b2303 Author: William Lachance Date: Tue Oct 21 15:10:21 2008 -0300 Remove obsolete header. commit 77fa4ff7403951bf0fcef26eaa7628b56571ff9b Author: William Lachance Date: Tue Oct 21 13:59:18 2008 -0300 Remove the "death_notify" functionality from wvhttppool. It was generating a warning and the functionality can be better provided by a close callback in any event... commit ed7e736ff5dc0c2a24bfc2a07f3aaef8e144eee3 Author: William Lachance Date: Tue Oct 21 13:42:57 2008 -0300 Avoid a warning about type-punning in XPLC. Basically make it explicit that we won't type punn a pointer. commit ef43954ba5d9939396002cb6cbe53c03f24b3937 Author: William Lachance Date: Tue Oct 21 13:40:02 2008 -0300 Add some virtual destructors to XPLC to suppress some warnings commit 0cc296ffe7cb04a4e154f4cab4eac477514b5c0a Author: William Lachance Date: Tue Oct 21 11:31:58 2008 -0300 Include and compile our own copy of xplc 0.3.13 commit ff5ae062e689f39e7f9d1dc6d13759ebdcb3aed1 Author: William Lachance Date: Mon Oct 20 14:51:03 2008 -0300 url_encode now takes a regular expression to decide which characters to encode This expression defaults to [^A-Za-z0-9_.!~*'()-], the same as perl's uri_escape function. commit f63b44e9e8e02a386e28f4c066b44c72290b0758 Author: Avery Pennarun Date: Mon Oct 20 21:04:31 2008 -0400 wvtest.cc: consider it an error if 0 tests were run. When there's a linker problem of some sort, you might end up linking in wvtestmain without any actual test programs, and 'make test' will succeed because no tests failed. But that's obviously not what you really wanted, because no tests *passed* either. We add a check at the end of run_all() to ensure that at least one test was run; if not, we return a failure code. versaplexd had this problem for a while, and I'd rather not ever see it again. commit 06991d81fdb5a0f9d5f0098628765df65fc1d546 Author: Avery Pennarun Date: Mon Oct 20 21:01:02 2008 -0400 Oops, some Makefile rules depended on "WVSTREAMS=." If we had a dependency on $(WVSTREAMS_LIB)/libwvdbus.so, for example, it wouldn't be satisfied by a rule for just "libwvdbus.so", but it works fine if $(WVSTREAMS_LIB) is ".". So change it back. To fix the LD_LIBRARY_PATH bug from earlier, just set it to `pwd` instead of WVSTREAMS_LIB. commit d5a4b47ca50470774c99f3aa23ecc8837c032a16 Author: Avery Pennarun Date: Mon Oct 20 20:55:12 2008 -0400 "wvtestmain ''" actually still runs all the tests, so skip the warning. wvtest.cc prints a message "WARNING: WvTest: only ran tests starting with specifed prefix(es)" if you give it any parameters restricting the tests to be run. But 'make runtests' actually sometimes provides an existing but empty parameter, which doesn't restrict anything because *any* test starts with the empty string. So suppress the warning in that case; it's the desired behaviour. commit c7f9bdfd0203aee30c7aa33f2aaf803b7e8ee576 Author: Avery Pennarun Date: Mon Oct 20 17:01:53 2008 -0400 Try to fix a timeout in wvstreamsdaemon.t.cc. The autobuilder machine is pretty busy, so the test might have timed out rather than actually failing. commit 52f37ed729b00acf600564653c7f6e9411f211a5 Author: Avery Pennarun Date: Mon Oct 20 15:29:22 2008 -0400 Remove the NULL-related check in wvstring.t.cc, and the warning it caused. WvString(NULL) actually produces a wvstring containing "0", because in C++ NULL is defined as 0, not (void *)0, and thus the pointer-based WvString constructor doesn't run. It has always been like that, since some version of gcc where the correct C++ behaviour was added. The unit test just checked that this was in fact the case, in case it ever changed. Signs are that it might, in fact, change when C++0x comes out. In any case, checking the current behaviour is somewhat pointless, because anyone who *relies* on the current behaviour is obviously crazy anyway, and it might indeed change - for the better - when C++ changes. So let's git of this warning. I've hated it for years anyway. commit 8978a2bfe5248b3ecd723b68c49905eec2514507 Author: Avery Pennarun Date: Mon Oct 20 15:24:50 2008 -0400 Get rid of autoconf --datarootdir related warning. commit 430b1f6ba5b840a7bf8f2d7b2dabaffdc2ca00e9 Author: Avery Pennarun Date: Mon Oct 20 15:08:05 2008 -0400 Set WVSTREAMS explicitly so that WVSTREAMS_LIB is right. Otherwise the unitest.sh script were failing, since they add WVSTREAMS_LIB to the LD_LIBRARY_PATH, but that was just ".", and they were running from a different directory. Hopefully this fixes "make test" for people who haven't set LD_LIBRARY_PATH by hand. commit 917677a902dea23590fd7ae35f4e1a37807d66e1 Author: Avery Pennarun Date: Mon Oct 20 15:01:48 2008 -0400 Fix some "non-virtual destructor" warnings in tests. commit d3560c1ab74d13f4051bb78c33fc01baa1a6a742 Author: Peter McCurdy Date: Fri Oct 17 18:48:42 2008 -0400 Fix some compiler warnings from sending a long int to a %d printf format. commit 3acbddd1de7990bd6139723b2dbd467e868ad668 Merge: 0c16c90... 1f74015... Author: William Lachance Date: Fri Oct 17 12:33:31 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 0c16c9071bb1382fec462fd600eb1c5b452a6ec4 Author: William Lachance Date: Fri Oct 17 12:32:23 2008 -0300 Fix typo in wvx509.h commit fb2675bbab064d1440ce8800c8ac8f83fd207bc0 Author: William Lachance Date: Thu Oct 16 16:42:51 2008 -0300 Make OCSP response class much simpler (don't check signing of OCSP response) Also add a special method for getting the OCSP response certificate so you can do this yourself, as well as a method for making sure that an OCSP response is signed by a specific certificate. commit 1f74015b0d3f11dd43fa21f93d576b91b2a7118d Author: Lukasz Kosewski Date: Thu Oct 16 14:03:47 2008 -0400 crypto/wvocsp.cc: Call wvsslhacks macro instead of openssl directly. In order to allow compilation with gcc 4.2, we wrapped i2d_OCSP_REQUEST_bio in C code, and now call that from within wvocsp.cc instead of the original openssl macro. Don't ask why this only breaks with gcc 4.2, as it probably should have broken long before that. commit a70385ffc57263248b46cedac97c2572920ce9f5 Author: Lukasz Kosewski Date: Thu Oct 16 14:01:34 2008 -0400 wvsslhacks.{c,h}: Added a wrapper for i2d_OCSP_REQUEST_bio. i2d_OCSP_REQUEST_bio didn't work when called directly from C++, because it calls an underlying macro which assumes a void * can be implictly cast into an unsigned char *, which is not the case here, however, it *is* the case in C. Added a C wrapper. commit 3657ec4b91f0dd284c18c7f25abcfc80cbf1d29e Author: William Lachance Date: Wed Oct 15 18:22:00 2008 -0300 Fix unit tests which were broken by enum renaming. commit 9d28048e4c0639de54a056dc20c5bc2d330074ff Merge: 8d05762... 0917915... Author: William Lachance Date: Wed Oct 15 17:54:21 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 8d05762daafbb6905bd50f606e9e36f52acc28ba Author: William Lachance Date: Wed Oct 15 17:53:20 2008 -0300 Delete X509 extensions before adding a new one of the same type Before it wasn't possible to rewrite X509 extensions once they had been set. Boo. commit 319088469b8c2fd30c06fa36bcafd1d90456ddd8 Author: William Lachance Date: Wed Oct 15 17:25:32 2008 -0300 New OCSP tests to make sure that key usage information is checked. Also add a copy constructor for WvX509Mgr, required by test. commit 09179154664859d39d9524c3dd863e8a8aeb3d8b Author: Lukasz Kosewski Date: Wed Oct 15 15:53:36 2008 -0400 wvocsp.{cc,h}: Renamed enum Status members from all-uppercase. All-uppercase enum Status members caused compile errors (doubtless conflicting with some Win32 macros) using mingw32. Renamed the members to begin with an uppercase letter and be all lowercase otherwise, and the errors went away. commit 8412e68c53a4f5deb080ff79533322d830a7391a Author: William Lachance Date: Wed Oct 15 15:57:44 2008 -0300 Really remove wvdsp.cc commit 65beea7d1716cec1397439e7f2173f945b1b22c8 Author: William Lachance Date: Tue Oct 14 14:04:27 2008 -0300 Use OpenSSL's pem decoding routine for decoding certificate requests Our routines to do this rejected some perfectly valid requests (specifically, base64 that starts with MIH instead of MII...). commit 49ecb0fe2304690ba47bf7988ba4a5cac16a1618 Author: William Lachance Date: Fri Oct 10 13:22:56 2008 -0300 Support 'file' urls in WvURL. This is kind of hacky, given that the class is intended for IP resolution, but I can't really bring myself to try and come up with a general URI parsing abstraction/strategy right now. commit b56d5388895f44a2011efef361e971317158e680 Author: William Lachance Date: Fri Oct 10 12:47:31 2008 -0300 Correct misleading comment. commit d6e1f01cc6333dd427a25f3609e79d27f3185050 Author: William Lachance Date: Fri Oct 10 12:47:03 2008 -0300 Fix edge case in url_decode. Add unit tests for url_decode/encode edge cases. commit dcd84fc941243d51ee00b6004331ab637a88c97c Author: William Lachance Date: Fri Oct 10 12:37:42 2008 -0300 Update win32.mk to no longer omit some objects which no longer exist commit e3b52b0e8bae4c1363196b20e6a9943444788e5b Author: William Lachance Date: Thu Oct 9 13:45:45 2008 -0300 Make sure CRL can still be signed by CA, even if the CA lacks an AKI. Also move some stuff which sets CRL information (version, time) into WvCRL from WvX509Mgr. commit 1785c2fce931b443e363d3f7f1b18af0f3198ae3 Author: William Lachance Date: Thu Oct 9 12:37:39 2008 -0300 Remove a bunch of header files for stuff that we no longer include. Also remove the remainder of the audio stuff, which isn't used by anything (and probably doesn't even work anymore). commit e17f43e01c6bb68451cb029d1550f2c351a32fd3 Author: William Lachance Date: Wed Oct 8 17:47:11 2008 -0300 We probably don't want the CA certificates we create to be used for OCSP Maybe in the future, I dunno. Seems like a case of YAGNI for now. You should really be generating certificates you're actually using for stuff in OpenSSL anyways... commit d9fc56a524e33703ada31a3ff9524006d7702b30 Author: William Lachance Date: Wed Oct 8 16:12:48 2008 -0300 Move wvgrep from examples/ into utils/tests. Remove custom rule for it. commit 578f230b66a1da2c4f5fb37c681bf4ffa99ea5dc Author: William Lachance Date: Wed Oct 8 15:05:31 2008 -0300 Pull out support for having a seperate "trusted" responder certificate for ocsp Basically, there are two common cases for OCSP: 1. The issuer of the certificate signs OCSP responses as well. 2. The issuer of the certificate signs the certificate of the OCSP responder (included with the response). In neither case do we need to support a seperate "trusted" responder certificate (that's basically an extra provided by OpenSSL), so just take out the complication of allowing one. commit 544bbe761ee71b761c9d6d02b89713f1a2fe0ef7 Merge: f9b4f78... ac555f1... Author: William Lachance Date: Wed Oct 8 11:28:41 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit f9b4f780f82977827a26fe3765c28a627d3ea578 Author: William Lachance Date: Tue Oct 7 13:24:02 2008 -0300 More tweaks to wvocsp and ocsptest commit ac555f139d97edbad2c5a427f418d9e12dc13741 Author: Lukasz Kosewski Date: Wed Oct 8 02:03:15 2008 -0400 Makefile: Moved some documentation around. It was erroneous. commit 71f4703489693dbbdce667befa398dd5a34d366c Merge: acb6d2b... 128cf54... Author: Lukasz Kosewski Date: Wed Oct 8 02:01:45 2008 -0400 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit acb6d2bf67d35ca1ee10cde38604813f2f45a87c Author: Lukasz Kosewski Date: Wed Oct 8 01:59:51 2008 -0400 Makefile: Massively clean-up argp inclusion in wvstreams. Hacks are a thing of the past with this new clean-up. Pull in the libargp.list file for libwvstatic.a, link the libargp.a library for libwvutils.so. No more @echo -n's, strange-case variables, or .PHONY targets which look like they shouldn't be phony. Bonus: works with -j2, though there are still other parts of the Makefile which don't. commit 0c93852e5c88dff6f9585c6e436d832758727a1c Author: Lukasz Kosewski Date: Wed Oct 8 01:59:17 2008 -0400 argp/.gitignore: Added libargp.list to .gitignore. commit c3da0fd01e4a3710787eaadb3ed91881748abba5 Author: Lukasz Kosewski Date: Wed Oct 8 01:57:04 2008 -0400 argp/Makefile.in: Add support for generating a .list file. Regarding support to use .list files for static libraries, argp can now generate a .list file of the important objects we need from it. commit d95b30dbdbb1e0e7679fe550fa58e6e5177a0dd5 Author: Lukasz Kosewski Date: Wed Oct 8 01:50:11 2008 -0400 WvStreams build system: Add support for '.list' files and -EXTRA var. Two cool new features in the WvStreams build system for statically- linked libraries: .list files: If you add a '.list' file as a dependency to a library we statically link during the wvstreams build process, and use the wvlink_ar macro to put it all together, the .list will be processed correctly. The .list file is a list of .o files to pull in to said library; useful if, say, we're deconstructing another .a file and want to pull its objects into this library. NOTE: If you specify a .list file as a prerequsite for a dynamically -linked object, the object will rebuild, but nothing more will happen. You mus still use the $1-LIBS variable for a particular dynamically-linked library to pull in dependencies. $1-EXTRA variables: If you absolutely need to specify some sort of object file/list which you don't want the build system to use as a rebuild dependency, specify the $1-EXTRA variable for a particular .a (static library) to have it be included in the library, but not the Make dependencies. ... also, I fixed the indentation on some of the shell scripting craziness here. commit 128cf545c444d3d44db18b2cb563d7c7a84dd506 Author: Avery Pennarun Date: Wed Oct 8 00:34:12 2008 -0400 WSANOTINITIALISED is an okay error when shutting down WvStreams in win32. If someone shuts down winsock before closing wvcon, we can get this error. But if winsock is shut down, it *doesn't* mean that someone accidentally closed our socket, as the assertion in stream.cc suggests; it just means we're shutting down. So avoid asserting in that case. commit f5b862fbed285e3560a5b8c506df45faa25d55c6 Author: Lukasz Kosewski Date: Tue Oct 7 16:40:04 2008 -0400 Update argp .gitignore. commit f5c7ffbcf7301b5d11233e76d44ee69778ad38b7 Author: Lukasz Kosewski Date: Tue Oct 7 16:38:06 2008 -0400 wvstreams + argp: I hate life and argp. Argp seems to require a few more .o files from its repository for Win32... and naturally, they're generated from its own configure. Add code that parses the resulting Makefile from argp to get those objects which we need to throw into libwvstatic.a. commit 6ccd782b53ebaf6f582d4ced9c742f317781f136 Author: Lukasz Kosewski Date: Tue Oct 7 16:36:30 2008 -0400 wvstreams + argp: Stupid autoconf variables screwed things up. We pass --host=i586-mingw32msvc to the wvstreams configure, but when we run the argp configure from within it, the $ac_cv_host variable has morphed into something else. Use good ol' $ac_cv_env_host_alias instead to fix the problem. commit af71f1131f36a0a09b72e9e9289a1c11f87c4678 Author: Lukasz Kosewski Date: Tue Oct 7 15:22:57 2008 -0400 argp now has a .gitignore file. commit 95540d2cf49f8e4bee95de63df6060e29fe44e75 Author: Lukasz Kosewski Date: Tue Oct 7 15:16:33 2008 -0400 WvStreams argp: make WvStreams build and use argp. Based on the changes to the config.mk file, we no longer just arbitrarily link -largp with our files, instead, we pick up whether or not to use the WvStreams argp, and if so, include it directly into libwvstatic (as .o files), or link it with libwvutils.so, as needed. commit 7d00c09ffcdf6571c9390327516cd56d3d7bfa3e Author: Lukasz Kosewski Date: Tue Oct 7 15:14:53 2008 -0400 WvStreams configures argp. WvStreams now configures argp for building during its own configure process. It also sets the USE_WVSTREAMS_ARGP flag in config.mk, signifying whether or not we should recognize that the WvStreams argp should be built and linked. configure-mingw32 no longer passes in argp flags for wvbuild. commit e252aa4039eea539355c2e47e26d3475f25ec0f1 Author: Lukasz Kosewski Date: Tue Oct 7 14:42:43 2008 -0400 argp: Patch 08-use_fputc_instead_of_putc_on_win32.diff Patch description: Mingw is stupid and seems to evaluate the 'stream' parameter to putc in some strange way, which causes this program to abort. We replace instances of 'putc' with 'fputc' when building for WIN32, and everything is happy. commit 8e897de234a50f345081954eb5394b47d7f75208 Author: Lukasz Kosewski Date: Tue Oct 7 14:41:21 2008 -0400 argp: 07-use_rand_instead_of_random_on_win32.diff Patch description: Win32 doesn't have 'random.' Use 'rand' there instead. commit b366bfb4284750e9126c951d67f1ca3601c4d4e8 Author: Lukasz Kosewski Date: Tue Oct 7 14:40:04 2008 -0400 argp: Patch 06-include_malloc_h_for_win32_alloca.diff Patch description: 'alloca' is defined in malloc.h on Win32. commit 4a0623338d20145733e10f6406b5e7914c6703d3 Author: Lukasz Kosewski Date: Tue Oct 7 14:38:56 2008 -0400 argp: Patch 05-use_winapi_for_sleep.diff Patch description: There is no 'sleep(secs)' in win32; there is Sleep(millisecs). commit 6b8aa8f7b16f4530f584c49407d327517e283ada Author: Lukasz Kosewski Date: Tue Oct 7 14:37:25 2008 -0400 argp: Patch 04-remove_stuff_defined_by_mingw.diff Patch description: Mingw32 defines __argc and __argv as (*__p__arg{c,v})() respectively. Of course, this breaks the actual implementations of these functions further on, which are not expecting a function pointer, but instead a simple type. We'll just add types with no names in these declarations. commit 54ed4cb918ca95d23baf25d4c2ab7b9067a6b694 Author: Lukasz Kosewski Date: Tue Oct 7 14:29:20 2008 -0400 argp: Patch 02-dont_include_linux_headers_on_mingw.diff Patch description: Mingw32 has no sysexits.h file to work with. commit 6c6e0ed8385c778a23b8f2cbee6a0bf6e48d31ab Author: Lukasz Kosewski Date: Tue Oct 7 14:09:36 2008 -0400 argp: Patch 01-compile_with_new_gcc.diff from wvbuild. Patch description: Remove __THROW (which expands to __attribute__ (__nothrow__) on my system) from the function instantiations (as opposed to declarations) on a number of functions, as GCC > 3.2 no longer supports such a thing. commit 3b3339cf6dc8ed912f844157db70966803e3a540 Author: Lukasz Kosewski Date: Tue Oct 7 00:48:23 2008 -0400 argp: First commit of argp-standalone 1.3 to wvstreams. commit 39d2aaa80e4e4aae35fe15e1e148d529d56c6953 Author: Avery Pennarun Date: Mon Oct 6 12:27:16 2008 -0400 Don't use 'tempfile' in the gen-cc script. It appears to be Debian specific. Anyway, just naming the temp file with '$$' (the shell's PID) in the name should work fine. commit 1117161d5fdb6769ffbc00762e4c6413765bcb94 Author: William Lachance Date: Fri Oct 3 21:49:12 2008 -0300 Refactor wvocsp a bit to be more flexible and useful In particular, you no longer need to keep a request around in order to check revocation of a certificate in the reply. You can use the request to check the nonce seperately. commit 027198ec48b923e6be19725dabde3ab12d426405 Author: William Lachance Date: Fri Oct 3 12:01:20 2008 -0300 Don't let httppool spin an infinite loop when it can't resolve a hostname It seemed like we had code which had the intention of doing this, but didn't actually do it. Also added a unit test to make sure this problem doesn't crop up again. commit 7eb04cc71c27bb0dc106ab09b515f85e01768d62 Author: William Lachance Date: Wed Oct 1 10:54:25 2008 -0300 More refinements to the new OCSP abstraction. commit 49d3c1eab0e88581cfd55c95c2da30b23a38f6a2 Author: William Lachance Date: Tue Sep 30 21:37:41 2008 -0300 Various cleanups to the new OCSP stuff. commit ea51e4ae109ec6e98af1a6ee682093e6320b870c Author: William Lachance Date: Tue Sep 30 16:44:39 2008 -0300 More exciting ocsp additions. commit 7237988c371012092c16f7026cf1ccd80fe86c17 Author: William Lachance Date: Tue Sep 30 16:13:06 2008 -0300 New OCSP class needs access to WvX509's internals. commit ff32af5adda49fd5e0c69ba461763a6fe7dcb661 Author: William Lachance Date: Tue Sep 30 15:59:10 2008 -0300 Send data as part of an http request as a buffer, not a string This enables us to send arbitrary data as part of an httppool request, and has the side bonus of being simpler and more efficient. commit 71deac756591d2173432ed080d56c055d5278f04 Author: William Lachance Date: Tue Sep 30 15:57:51 2008 -0300 Remove old artifact of SWIG python bindings commit 1c7ba301819efb08f37a68850e66ec0c656894d8 Author: William Lachance Date: Tue Sep 30 14:51:08 2008 -0300 New OCSP abstraction for WvStreams. WvOCSPReq lets you create a request for an OCSP server. WvOCSPResp lets you parse an OCSP response. commit 871ef701a8b165e36f091bbcdddd72bdc2de5dab Author: William Lachance Date: Tue Sep 30 13:53:21 2008 -0300 Insist that a version string be passed to WvDaemon/WvStreamsDaemon The old way was to default to a WEAVER version, which makes absolutely no sense for projects outside of Nitix/Foundations. If IBM ever should want to use our version of WvStreams, they can add the extra argument to their WvStreams daemon constructor. commit c53e3f1cbd2849a075917071e39c383b5c2adbc8 Merge: 30f7f93... a7889bc... Author: Avery Pennarun Date: Mon Sep 29 15:54:12 2008 -0400 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams * 'master' of ssh://repo.or.cz/srv/git/wvstreams: WvDBusMsg: when printing REPLY packets, print the serial, not just rserial. wvdbusserver: implement NameHasOwner request. WvTCP: make *all* TCP streams low_delay(). wvgzip: use Z_BEST_SPEED instead of Z_DEFAULT_COMPRESSION. Skip prociter objects in new streams directory when building under Win32 WvDBusConn: use delay_output() to make things go faster. Add quick test for wvx509's copy constructor Set the CRL's AKI when creating from a cacert. Ripped wvprotectdata/wvunprotect data out of WvStreams. Fix logic error (== => !=) in UniRegistryGen.exists(). Fix compile warning ("%d" -> "%ld" in printf) in uniregistrygen.cc commit c21c0bad420c81877042428abea855824b7c5141 Author: William Lachance Date: Mon Sep 29 16:14:12 2008 -0300 Use rm_rf instead of WvSystem("rm", "-rf", ...); commit a7889bc56699a9640cf723e4f926d71f2a8c66ea Merge: 8faa452... 287801e... Author: Lukasz Kosewski Date: Fri Sep 26 18:06:40 2008 +0000 Merge branch 'master' of /home/lkosewsk/versabanq/versabuild_win/wv/wvstreams Conflicts (very silly and fixed): include/wvstrutils.h utils/strutils.cc commit d318855e26ac225aacdcb94b6bac3d185e314aa8 Author: William Lachance Date: Fri Sep 26 10:29:08 2008 -0300 Fix a misleading log message in WvX509::decode commit 30f7f93cd6af82aba0517501b8668d10dc9cd893 Author: Avery Pennarun Date: Thu Sep 25 18:08:23 2008 -0400 wvdbusserver: implement NameHasOwner request. commit 8faa4521ab63a3517d722cf12215abb0c74a090d Author: Avery Pennarun Date: Thu Sep 25 18:08:43 2008 -0400 WvDBusMsg: when printing REPLY packets, print the serial, not just rserial. commit 46c05047cc54efa623532a8052ce9c425e655d28 Author: Avery Pennarun Date: Thu Sep 25 18:08:23 2008 -0400 wvdbusserver: implement NameHasOwner request. commit a4dcd9de0a8725ce94146d5aadb64892ecc85b32 Author: Avery Pennarun Date: Wed Sep 24 18:21:45 2008 -0400 WvTCP: make *all* TCP streams low_delay(). The Nagle algorithm isn't really that great for modern systems, and WvStreams has lots of better output buffering options, like delay_output(). Furthermore, it's actually easier to see from a tcpdump/wireshark dump that you're being inefficient when you have Nagle turned *off*, because then you have a bunch of tiny packets. Otherwise you get random unexpected delays that can be hard to see. Okay, I'm convinced. We'll do low_delay() (ie. TCP_NODELAY) by default. This further speeds up versaplex. commit 58e5fb858503d151ef112bf0e47873fd440cf792 Merge: f3b15cb... 5349165... Author: Avery Pennarun Date: Wed Sep 24 17:29:40 2008 -0400 Merge branch 'master' of git+ssh://repo.or.cz/srv/git/wvstreams into HEAD * 'master' of git+ssh://repo.or.cz/srv/git/wvstreams: Skip prociter objects in new streams directory when building under Win32 commit f3b15cb0d1e102f76bc00a331799b4b29cc2113e Author: Avery Pennarun Date: Wed Sep 24 17:28:00 2008 -0400 wvgzip: use Z_BEST_SPEED instead of Z_DEFAULT_COMPRESSION. Since this is WvStreams, we can assume people using WvGzip will want to use it for network stuff, and in that case, speed is more important than compression ratio. The speed difference this makes is pretty huge. It might be better to add an option to let you set it, but it didn't seem worth the trouble right now since hardly anyone uses WvGzip anyhow. commit 5349165ab213596c82fca07e7ac003854412fd8a Merge: a63f711... 7a4b1b6... Author: William Lachance Date: Wed Sep 24 18:13:19 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit a63f7114ca62e436dc875243c2c0a6158531cb04 Author: William Lachance Date: Wed Sep 24 18:12:43 2008 -0300 Skip prociter objects in new streams directory when building under Win32 Fixes build breakage. commit 7a4b1b687c4fd8f115a27ebd77cd80c88fe1349e Merge: 152b7ac... 2a86ba6... Author: Avery Pennarun Date: Wed Sep 24 17:06:22 2008 -0400 Merge branch 'master' of git+ssh://repo.or.cz/srv/git/wvstreams into HEAD * 'master' of git+ssh://repo.or.cz/srv/git/wvstreams: Add quick test for wvx509's copy constructor Set the CRL's AKI when creating from a cacert. commit 152b7ac811a2e73f583fe5a6bacc06b04f547701 Author: Avery Pennarun Date: Wed Sep 24 17:04:12 2008 -0400 WvDBusConn: use delay_output() to make things go faster. Yeah, I know it sounds counterintuitive :) This combines multiple packets together when you're sending them, which uses fewer packets for the same job and prevents Nagle from kicking in. More than doubles the speed of versaplex with small queries. commit 2a86ba6d7f9649e12e3fdd4286bc110fdafcf255 Author: William Lachance Date: Wed Sep 24 15:44:33 2008 -0300 Add quick test for wvx509's copy constructor commit c9cc5be5586198bd0e4b94fe743e5f2a9961c866 Merge: 3c4c856... c4a7afc... Author: William Lachance Date: Wed Sep 24 15:42:03 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit c4a7afc69e38156cb5c83a5ae0fe5dfa64a9a01e Merge: 59dd32a... 121853e... Author: Avery Pennarun Date: Wed Sep 24 11:37:10 2008 -0400 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams into HEAD * 'master' of ssh://repo.or.cz/srv/git/wvstreams: Add copy constructor for WvX509. Move wvreadlink from strutils to fileutils. sleep(1) -> wvdelay(100) in a bunch of unit tests. Speeds things up somewhat. Move wvdelay to wvtimeutils, which is a much more sensible place for it. Make url_encode encode according to a very strict interpretation of rfc3986 Add explanatory comment on why the dbus:system moniker doesn't often work web_unescape -> url_decode (make it symetrical with url_encode!) How about we not wait 1 sec for a client connection to work? That'd be swell. commit 59dd32a8011098f2e37cfab76bd48ecf8618dd34 Author: Avery Pennarun Date: Wed Sep 24 11:34:39 2008 -0400 WvDBusServer: remove serial_to_conn map. That's weird; it turns out serial_to_conn is completely unnecessary, because the destination of a reply message is always set to the person you're replying to anyway. I'm not sure why I thought otherwise. Remove the silly mapping function. As a bonus, this gets rid of ridiculous problems that can be caused when different clients produce messages with the same serial number, which is not only possible, but common. commit 3c4c8561d2278d7538ad08a51040c8d866fc4732 Author: William Lachance Date: Tue Sep 23 17:37:29 2008 -0300 Set the CRL's AKI when creating from a cacert. commit 121853e231b1c5306592f54d6414eda141fc851b Author: William Lachance Date: Mon Sep 22 16:25:54 2008 -0300 Add copy constructor for WvX509. commit 75caf3387ecd93eab231eab476add703ea7b1675 Author: William Lachance Date: Mon Sep 22 14:01:42 2008 -0300 Move wvreadlink from strutils to fileutils. Also move wvprociter into the streams/ at the same time because it now uses wvfileutils. This makes more sense than before, since it uses wvfile (a stream). commit 287801e99feb6020fa9ff1bc4a0d74d7fb76c384 Author: Lukasz Kosewski Date: Fri Sep 19 20:34:16 2008 +0000 Ripped wvprotectdata/wvunprotect data out of WvStreams. Banished these Win32 functions which had only one user (not WvStreams) out of here. commit 07962be4531087179bddaa88a14d92ff5501ca40 Author: Lukasz Kosewski Date: Fri Sep 19 20:11:20 2008 +0000 Fix logic error (== => !=) in UniRegistryGen.exists(). commit ab5507fd00ea265465d6f70b596f23160edd1a90 Author: Lukasz Kosewski Date: Fri Sep 19 20:10:40 2008 +0000 Fix compile warning ("%d" -> "%ld" in printf) in uniregistrygen.cc commit 70334ad87ff2eb6006a8bfb0a56025ae049bba2b Merge: 70a88a8... 32a6a77... Author: William Lachance Date: Fri Sep 19 00:36:02 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 70a88a881f42496439f7d503c56349d55aa69361 Author: William Lachance Date: Fri Sep 19 00:33:56 2008 -0300 sleep(1) -> wvdelay(100) in a bunch of unit tests. Speeds things up somewhat. commit 5cc44a91a36137613d9669dd46b33c43ff60a5ab Author: William Lachance Date: Thu Sep 18 23:47:01 2008 -0300 Move wvdelay to wvtimeutils, which is a much more sensible place for it. commit f121f29fe5e06628e83472569eba87d28bbfa6e8 Author: William Lachance Date: Thu Sep 18 23:46:20 2008 -0300 Make url_encode encode according to a very strict interpretation of rfc3986 commit 8cffcf54f0b2a21be5cd85380eebdad4f6b5b5c3 Author: William Lachance Date: Thu Sep 18 19:12:13 2008 -0300 Add explanatory comment on why the dbus:system moniker doesn't often work commit b14430633f679132df600c1ca7b2f307064f3662 Author: William Lachance Date: Wed Sep 17 20:34:59 2008 -0300 web_unescape -> url_decode (make it symetrical with url_encode!) commit 091f9631be7f02e549ebfad2f1f442f45f954324 Author: William Lachance Date: Wed Sep 17 20:10:52 2008 -0300 How about we not wait 1 sec for a client connection to work? That'd be swell. commit 32a6a77de8a646f031214a085ee4de095067830f Author: Avery Pennarun Date: Tue Sep 16 02:38:21 2008 -0400 Add a new wvgzipstream.cc, just to implement the gzip: moniker. wvgzipstream.h already implemented the actual WvGzipStream, but there was no moniker available. Add it. Now, like magic, wvdbus/wvdbusd support gzip encoding. (Try "wvdbusd 'tcp:5555 gzip:'" and "wvdbus -m 'gzip:tcp:5555'") commit 525d2ddff4b48f8e293d51e853ab03f0e93ecdd2 Author: William Lachance Date: Sat Sep 13 18:07:54 2008 -0300 Set SIGPIPE to SIG_DFL before running every unit test. This ensures that tests where a socket connection is broken work correctly, and don't assume that the signal handler is set by another test before it. Strangely enough, there was only one test that made this fatal assumption (in uniclientgen.t.cc), which was fixed in an earlier commit. commit d79e18cfccf406ef9c105a5db5d60ac8ef151c31 Author: William Lachance Date: Fri Sep 12 17:03:20 2008 -0300 The "id" parameter is now mandatory when adding a stream to wvistreamlist We always want people to identify streams to a wvistreamlist. Don't let them be lazy and make their programs hard to debug! commit c09babbd9c6e109b630a6e945c6cfa79918b76f2 Author: William Lachance Date: Fri Sep 12 17:00:30 2008 -0300 Set time of ini file in uniclientgen test into the past instead of sleeping This both corrects a bug where the daemon subprocess would have a different time than that of the unit test (possible in unix) and is faster than sleeping. Thanks to pmccurdy/apenwarr for the suggestion. commit 59f650a9cd86a198a6b7f4e933ce7dfd5cc2cfeb Author: William Lachance Date: Fri Sep 12 16:01:39 2008 -0300 Remove reference to non-existent class in comment in wvdbusmsg.h commit d4b2aac74e225f7b0119de1939780b1624824a99 Author: William Lachance Date: Fri Sep 12 15:46:48 2008 -0300 Make sure we ignore all SIGPIPE signals at the beginning of uniclientgen commit dd43625457e8aad997fc09dbcec3d1b76194e106 Merge: a12ba4a... 402429a... Author: William Lachance Date: Fri Sep 12 13:43:47 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 402429a3f6a926772ef54dce197cc8341de09c32 Author: Peter McCurdy Date: Thu Sep 11 15:56:53 2008 -0400 Flush connections for all DBus server tests, not just the last one. WvDBusServer objects are refcounted for each open connection. So they don't necessarily go away immediately when you delete them. This can cause Valgrind to complain about memory leaks in the unit tests, and/or the open file descriptor check to fail. The reason these things didn't normally happen is that, as it happened, the last test in the file had code to run the globallist a few times to clear everything out. Move this code to the TestDBusServer destructor, so now all the individual tests work as expected. commit a12ba4a5905d115d59ab3035f5db6371ff410ece Merge: a7d957d... ff9cd28... Author: William Lachance Date: Thu Sep 11 16:33:10 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit ff9cd2868155ff91201e457008a1bfe0da3e6e40 Author: Avery Pennarun Date: Wed Sep 10 01:03:37 2008 -0400 Improvements to wvtestrunner.pl added for an internal project. We now time out if there are no test results for 120 seconds. Also handle surprise CRLFs in the input stream. commit de374a4cc2b749f434914a8baf64d6cd4c93afb9 Merge: 49efbe2... b4eb2bb... Author: Avery Pennarun Date: Tue Sep 9 19:03:05 2008 -0400 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams into HEAD * 'master' of ssh://repo.or.cz/srv/git/wvstreams: Extended WvDBusConn to allow setup function before send_and_wait. commit b4eb2bb63f96256333af298a2cee117b43c2c844 Author: Lukasz Kosewski Date: Tue Sep 9 18:15:47 2008 -0400 Extended WvDBusConn to allow setup function before send_and_wait. Added an optional serial_cb parameter to the send_and_wait function in WvDBusConn which allows for some set-up based on the serial of an outgoing DBus message before the runonce() loop is engaged. commit 49efbe24c148d69873ca78c05e9c5825d50ef49d Author: Avery Pennarun Date: Tue Sep 9 17:57:25 2008 -0400 Replaced wvtesthelper/meter/colour scripts with an all-new wvtestrunner.pl. This one is much smarter than previous versions: by default, it prints out only the headers from "Testing blah blah:" lines and then prints just a "." for each "! whatever ok" line. But, if a test does fail, it prints out *all* the stdout/stderr that was produced by the test from the "Testing blah blah" line all the way to the failing test. It also auto-colours ok/FAILED lines, but only if stdout is a tty, so you don't need to decide whether you want it coloured or not. Finally, its output is actually compatible with itself: you can run a top-level wvtestrunner and it'll further summarize the output of inner wvtestrunners, because the complete output of a given testrunner is in a single "Testing blah blah:" section. But if a failure occurs, you'll still get the more detailed results. commit 63d58ce6a85a26049efca35e050c4a7773cf2447 Author: Avery Pennarun Date: Tue Sep 9 17:56:11 2008 -0400 Ugh. Found out unitest.sh wasn't running as part of 'make test'. This has probably been the situation for *years*. Sadly, enabling it found at least two separate bugs, which I've added FIXMEs for but I don't have time to fix right now. Let's hope I don't get bitted by that someday... commit a7d957de07d3d869188e2866fa1c75895fbbf91d Author: William Lachance Date: Mon Sep 8 15:03:19 2008 -0300 Fix comment referring to obsolete info in wvdbusconn.h. commit 3b551b568ca26fe488c70a0c0f1f8c8c47f8cb08 Author: William Lachance Date: Mon Sep 8 15:01:36 2008 -0300 Rename COPYING.LIB to LICENSE. Some source code comments mention the latter, and the former was always a silly and non-standard name. commit 843f32cab70225afbe9b62fa05ae07f1e5f38bde Author: William Lachance Date: Mon Sep 8 14:38:15 2008 -0300 Add pkg-config files for wvdbus. commit 857f6bccd84edfd17671f1ae7d265f0a46d12839 Author: William Lachance Date: Mon Sep 8 14:37:25 2008 -0300 Fix XPLC-related errors in our pkg-config files. commit 46fe035c2533109611074449551f6871fa89c094 Author: William Lachance Date: Mon Sep 8 14:22:42 2008 -0300 Fix typos in libwvqt pkg-config files. commit e59ba2411ea7c51e9a1b27c97c94b5106ff07fd4 Merge: 0e1bee9... 8b3428b... Author: William Lachance Date: Mon Sep 8 12:48:51 2008 -0300 Merge branch 'x509-doc' into HEAD commit 8b3428b8b9fefcf66492615fcc4cb94d2328c1da Author: William Lachance Date: Mon Sep 8 12:35:46 2008 -0300 Better comments for WvX509, WvX509Mgr, and WvCRL classes. commit 0e1bee97097a95b90e2636303a19cca631ea8046 Author: Avery Pennarun Date: Fri Sep 5 14:29:08 2008 -0400 valgrind: suppress more stupid errors in ld.so. commit 9c891a9fad6a1bb8c2e7d3fcf8f7195178142b32 Author: Avery Pennarun Date: Thu Sep 4 20:04:23 2008 +0000 Clean up the one unit test that still fails with openssl 0.9.7. Can't figure out why it actually fails, but I did some cleanups and expansions of the test while I was working on it. commit f0b5bd67d0fe4d7d094055468e1af6e8aab217e9 Author: Avery Pennarun Date: Thu Sep 4 20:03:23 2008 +0000 Fix some unrelated unit tests when !HAVE_OPENSSL_POLICY_MAPPING. We were still checking some policy-related flags that openssl 0.9.7 doesn't know how to set properly. commit c08fb6b8c733c77aefcaaea62ee04ef5f1c452f6 Author: Avery Pennarun Date: Thu Sep 4 19:41:32 2008 +0000 Fix some lines that exceed 80 characters. commit 6386a208a9355390d7e215989bd21ce4e26bcbd0 Author: Avery Pennarun Date: Thu Sep 4 19:24:20 2008 +0000 Add a global object in wvx509.cc to prevent SSL errors from getting unloaded. I suspect this is only needed in OpenSSL 0.9.7, so protect it with an ifdef. This loads SSL error messages at the start of the program, which is kind of lame since the program might not even need them. But it's the only safe way to delay *unloading* the messages until the end, assuming we still want valgrind's memory leak checker to work in unit tests. commit dc8d6ed161005f5353dbfae1c42d4066fc67575b Author: Avery Pennarun Date: Thu Sep 4 19:21:41 2008 +0000 WvX509: fix calling of wvssl_init() and wvssl_free(). We were calling wvssl_free() unnecessarily in one place, thus screwing up the refcounts and causing potentially random problems. Added an assert() that will catch that in the future, and removed it. Also removed calls to wvssl_init()/free() in WvSSLStream's error printer; the message should be initialized by WvSSLStream anyway. commit 31198b819435af4c3d79fcd77ab042d55fb41736 Author: Avery Pennarun Date: Thu Sep 4 19:19:13 2008 +0000 x509-related error message: don't just say "there was an error." Now we call the SSL error message classes. Thanks to a suggestion by wlach, rephrasing by me. commit 3a134c135f4b079d711e0fe6fe593fcdb2d031ca Author: Avery Pennarun Date: Wed Sep 3 23:15:18 2008 -0400 Include limits.h in a few more places where we use INT_MAX. Noticed by: thE_29 as he tries to make wvstreams cross-compile under uClibc. commit 2937a6affc90f9106b2c96e1c51907486c5a43fc Merge: a180c8e... 48c7618... Author: Avery Pennarun Date: Wed Sep 3 17:57:46 2008 -0400 Merge branch 'wvassert-portability' into HEAD * wvassert-portability: wvassert: default to old-fashioned assert if no __GLIBC__, not just on win32. commit a180c8ef6c5dbe22cdf1f38ce338a8949400dc10 Author: Avery Pennarun Date: Wed Sep 3 21:31:40 2008 +0000 WvProcIter now gives a warning when /proc isn't mounted. Also made the unit test fail more gracefully in that case. commit 9ea89e45a277fa57461e457ed8c530c6a28cacf0 Author: Avery Pennarun Date: Wed Sep 3 21:31:20 2008 +0000 Don't compile ipstreams/tests/wsd if there's no readline. commit 5a8b4a02744b531ff6990d1c8b2c4ceab98dd2ba Author: Avery Pennarun Date: Wed Sep 3 21:12:32 2008 +0000 When dbus isn't available, don't build an empty libdbus.so. Also don't build the wvdbus unit tests. commit 3b7dcc4c089faf956414a52971730adff2b9be9f Author: Avery Pennarun Date: Wed Sep 3 20:47:35 2008 +0000 Restore support for openssl 0.9.7 (Debian Sarge). This adds a HAVE_OPENSSL_POLICY_MAPPING autoconf setting, which is false on 0.9.7 but true on 0.9.8. A few WvX509-related methods are #ifdef'd out when this define is false, which is okay because wvstreams itself doesn't depend on them anyway. commit bc5730c19b219aa4bd8daf18932dd78ec284535f Author: Avery Pennarun Date: Wed Sep 3 19:38:36 2008 +0000 configure.ac: if neither boost nor tr1 is available, die right away. Previously configure would succeed, but compilation would fail, which was delaying the inevitable. commit 5c417be71550ec88e93706f4ee45c4006c7a80ad Author: Avery Pennarun Date: Wed Sep 3 19:29:22 2008 +0000 configure.ac: autodetect libxplc 0.3.11 vs 0.3.13. 0.3.13 is the one we keep in wvports, but 0.3.11 was included with Debian Sarge and works just fine, so we might as well support it. commit 4b4e5db49faf0a4e860d974f2b15e511d26b59c6 Author: Avery Pennarun Date: Wed Sep 3 20:47:13 2008 +0000 Add autogen.sh, which just runs autoheader and autoconf. Apparently this is fairly standard. commit 68f658d4d03ac279ed1eea9ef79e948b319752a1 Author: Avery Pennarun Date: Tue Sep 2 21:25:23 2008 -0400 gen-cc: gcc autodependency generation doesn't work as documented, sigh. All our autodependencies weren't working (at least with Debian g++ 4.1.1-21) because the default autodependency target is uselessly the *filename* of the output file, not the *pathname* of the output file as the documentation claims it is. Force the situation by using the -MQ option. commit 48c7618b0efb68c4d6dfed87f83a3263617b2937 Author: Avery Pennarun Date: Tue Sep 2 12:31:03 2008 -0400 wvassert: default to old-fashioned assert if no __GLIBC__, not just on win32. This hopefully helps with uclibc compile problems. commit 01b3d77b82d68797d7b27d75bab7a06f86f28135 Author: Lukasz Kosewski Date: Fri Aug 29 10:46:46 2008 -0400 Added WvDBusMsg support to get the 'error' field out of DBus messages. commit fd10eccd7d90a575728bb9a5a4a9e9170ae8cda4 Author: Avery Pennarun Date: Wed Aug 20 19:40:22 2008 -0400 Try another fix for wvlinkerhack and static libraries. This time we use volatile ints instead of normal ints. Theoretically, the read of the WV_LINK() volatile int should not be allowed to be optimized away, nor should the store to the WV_LINK_TO() volatile int. Sadly, this will generate actual init-time code in the program, unlike the old system that just generated a symbol reference, but any compiler that optimizes it away is broken. commit 0f94649a06d86a810f9f9f35bb435164b3387fc5 Author: Avery Pennarun Date: Wed Aug 20 18:57:43 2008 -0400 Revert "Fixed static linking with WvMonikers and Mingw32." This reverts commit 3a7be211e56cd3b350e900fca6a9c8aae5de36e3. The new version is definitely not right; it creates static functions instead of static ints, and static functions are *certifiably* possible to optimize away. I'm not sure how it ever worked, but doing it that way broke wvlinkerhack on g++ 4.1.2 on Linux. commit 2240bf1565843c8af3cf1bbd529f24a872736fa7 Author: Avery Pennarun Date: Wed Aug 20 18:03:07 2008 -0400 The LIBS line was apparently accidentally deleted from configure-mingw32. Brokenness was introduced in 21f200872f0ae79063682256a80874febc5d0d32. commit 7dc3f9d6f408ba471e2dc381cb405ff5c8d5ca0f Author: Lukasz Kosewski Date: Thu Aug 14 17:28:29 2008 +0000 Added a template of a wvdbus.ini file to give WvDBusD SSL powers. commit 7824daca6d15d5b15d725af08d525f02b32702f1 Author: Lukasz Kosewski Date: Mon Aug 18 18:49:25 2008 -0400 Added wvprotectdata/wvunprotect data to wvstrutils. Ever wanted data that only YOU can access under Windows? Ever wanted functions to encrypt and decrypt it for you in WvStreams? Well... now you've got 'em! wvprotectdata and wvunprotect data wrap around CryptProtectData and CryptUnprotectData respectively from the Win32 API. WvStreams now links against libcrypt32 for these functions. commit 21f200872f0ae79063682256a80874febc5d0d32 Author: Lukasz Kosewski Date: Mon Aug 18 20:13:18 2008 +0000 WvStreams support for building with wvports/win32api. Needed for newer Windows Crypt* functions. commit 84d15ddc883ff26e027982843f83dedb43211889 Author: Lukasz Kosewski Date: Mon Aug 18 20:09:58 2008 +0000 @ac_libs@ => @LIBS@ in config.mk.in, as the former was never populated. commit 3a7be211e56cd3b350e900fca6a9c8aae5de36e3 Author: Lukasz Kosewski Date: Mon Aug 18 16:49:41 2008 +0000 Fixed static linking with WvMonikers and Mingw32. Mingw32 had the awesome property (with version 4.2.1) that it optimised out WV_LINK_TO lines, as the anonymous namespace contained therein was no longer considered exported (gcc 4.2.x), and was unused in the local file. This has been changed into a static function, which, thanks to the wonders of gcc, is /not/ optimised out until after designating that we should link in other .o modules containing the monikers we want. The downside is that we use the GCC 'unused' attribute to prevent compiler warnings, and so this isn't portable to Windows. If anyonee wants to fix WvStreams compilation on Windows, you should look at this! commit 3944679bf3b98351bbc06147a1fdf9735b8d8d69 Author: Lukasz Kosewski Date: Thu Aug 14 13:32:05 2008 -0400 Fixed a warning under Win32 compiles in wvsslstream.cc. We don't need to define error_t, as it's already defined in wvautoconf.h. commit 643bcac02e046c30a04970912faf795053e86bd6 Author: Avery Pennarun Date: Thu Aug 14 18:18:24 2008 -0400 UniTempGen should have a WV_LINK for people who need to link statically. commit 355990dd0c72fdb1f3fb1618d368ebfe2a3b9e83 Author: Peter McCurdy Date: Thu Aug 14 00:34:21 2008 -0400 Minor wvtestcolour tweaks. Colour both WvTest-style FAILED and WvTest.Net-style FAIL entries in red. Also change the blue regex for lines that start with exclamation marks to properly deal with wvtesthelper's output - most other lines that start with exclamation marks will start with "! filename:linenum", but wvtesthelper's output is missing the line numbers. commit 9fa2c2e18c15d7b53cbe7c11df3913c85dd9c24d Author: Lukasz Kosewski Date: Thu Aug 14 00:52:03 2008 -0400 Wvdbusd now reads your SSL certificates! That's right. Now YOU can generate a PEM-encoded SSL cert and private RSA key, throw them in a file, and... voila, you've got a WvX509Mgr object that wvdbusd will use for any ssl connections it opens up. commit 624e892e2b7efcbb49dc0083b50c56ecddc0c1f2 Author: Lukasz Kosewski Date: Thu Aug 14 00:48:55 2008 -0400 Never hurts to add a unit test (for string params passed to wvargs). commit c760c33d0f8e4cb625d4b59306fb1f0f3af27f3b Author: Lukasz Kosewski Date: Wed Aug 13 22:39:08 2008 -0400 Added GetConnectionCertFingerprint to WvDbusServer. ... for getting just fingerprints, not whole certificates over. We still support getting whole certificates for the super-paranoid. commit 0dcbb69ce86a02a00572a5cb2a615826bb7c3a30 Author: Lukasz Kosewski Date: Wed Aug 13 17:24:39 2008 -0400 Oops! Forgot how to trigger an assert; true -> false in wvmoniker.cc. commit 9efef4e0ab181ba86591c0f222292f7b394838a2 Author: Lukasz Kosewski Date: Wed Aug 13 01:42:30 2008 -0400 Added WvDBusServer support for GetConnectionCert... The fancy pants way of grabbing a certificate for a particular connection to WvDBusServer. This is useful if, say, you are Versaplexd and have a mapping of certificates to usernames. commit bbd5e2d2d5e00e8fbb838a1d55a039ae630d4d91 Author: Lukasz Kosewski Date: Wed Aug 13 05:28:12 2008 +0000 Whitespace fix in WvDBusServer.cc commit 90879865aea7b90fed23c7681c7e468885f1ca24 Author: Lukasz Kosewski Date: Wed Aug 13 05:25:51 2008 +0000 WvSSLStream now setattrs peer certificate when connection established. We can now get peer certificates out of WvSSLStream via getattr("peercert"). This is great. A few changes to the way WvSSLStream calls underlying SSL API functions were made, namely, the server /always/ requests certs from the client now, whether vcb is set or not. commit 81f2a1746f907018e3efccda17392c63cb8f7fb1 Author: Lukasz Kosewski Date: Wed Aug 13 05:20:52 2008 +0000 Added 'setattr' to WvStream and 'getattr' to WvStreamClone. commit 803aeaa25503d14df0523e00402fccc215cf729e Author: Lukasz Kosewski Date: Wed Aug 13 02:45:19 2008 +0000 WvDBusServer bugfix; need to release() on removing from all_conns(). commit 90739db30317f014cf8df4bde1e1fea0488abdbe Author: Lukasz Kosewski Date: Tue Aug 12 13:38:15 2008 -0400 Changed global_vcb in WvSSLStream. global_vcb, previously, was to be a function which returned a bool and accepted a WvX509 * as a parameter. I've extended it so that it also takes a WvSSLStream *; this will be the stream which currently triggered the callback. That's just too useful. commit 74fa031e45a202f0305087abe0ca8c0f2609d5e3 Author: Lukasz Kosewski Date: Thu Aug 7 17:51:34 2008 -0400 Added public static verifier callback for WvSSLStreams. No more problems creating WvSSLStreams via monikers with no verifier callback! Now, a solution exists; you can set a verifier callback which will happily solve the problem for you. Best of all, it's public, so you can set it without being the stream itself, and none of that pesky constructor business. This turns out simplify callbacks a fair bit. commit 660d21e3bfcf5e375dc9f705e148aa9a04a26d67 Author: Lukasz Kosewski Date: Thu Aug 7 20:25:02 2008 +0000 WvMonikerRegistry needs 'override' flag to add monikers which exist. On apenwarr's advice, adding new monikers to replace existing ones shouldn't be a very common operation, and is often unwise and unwanted. An 'override' flag is now implemented, which must be set to true on WvMoniker instantiation to permit this moniker from overriding previous ones. commit f6cbef63474d69210afd895dc55c29d9e5931adc Author: Lukasz Kosewski Date: Thu Aug 7 20:23:56 2008 +0000 One-liner cleanup of WvMoniker. commit 7c2292ea9a8e6753b4a598106a89409f34953312 Author: Lukasz Kosewski Date: Thu Aug 7 15:55:54 2008 -0400 Modified WvMonikerRegistry to allow multiple instances of a moniker. Allowed moniker overriding by changing the backing store of a WvMonikerRegistry to a linked-list, instead of a hashtable, and doing linear searches for a moniker, prepending new (overriding) ones to the beginning. It's not /perfect/ in that you can do strange things and remove incorrect monikers (ie. not the ones that you actually want) this way, but you'd have to be doing very silly stuff. commit 7c74067f70111c0dd2b892fbb045350ee634f16c Author: Lukasz Kosewski Date: Thu Aug 7 15:53:46 2008 -0400 Updated a line of documentation which was wrong in WvLinkList. commit 80b35af92d0970e89f493b4cbaf4ced7a30d8fcb Author: Lukasz Kosewski Date: Tue Aug 5 17:41:53 2008 -0400 Added a comment to explain use of WvDelayedCallback in wvdbusserver.cc commit ab3f21ad2bf96f2de7100d44ae80acd3fd965d93 Author: Lukasz Kosewski Date: Tue Aug 5 16:32:32 2008 -0400 Added sslcert listener to wvsslstream. We can now create a listener with a tcl_encode()d SSL certificate, private RSA key, and listening moniker. Yay! This is fun! commit 0cf043c0e686f834f87dc804c2191429fc90539a Author: Lukasz Kosewski Date: Tue Aug 5 16:29:44 2008 -0400 Fixed wvsslstream unit test which was never testing the sslcert moniker. commit 29727bed08e53834a31af668561ca3ef2f016e89 Merge: 21433d6... f326bcd... Author: Lukasz Kosewski Date: Tue Aug 5 15:33:43 2008 +0000 Merge branch 'master' of ssh://192.168.1.95/home/lkosewsk/versabanq/versabuild/wv/wvstreams commit f326bcd30e4756fdf72ab832a15b2c676cb71091 Author: Lukasz Kosewski Date: Fri Aug 1 19:51:42 2008 -0400 Added sslcert moniker to WvSSLStream. Now, as a client needing to pass a certificate into SSL, I can do so, via this handy moniker which takes a WvTclString as an argument. Given an SSL certificate in PEM format, and an RSA key, as well as a connection moniker, we create an SSL stream which uses a WvX509Mgr with the cert and RSA key, connected to the given moniker. commit 21433d6d0df1ba09bdb798180d8a807202be3b9b Author: William Lachance Date: Fri Aug 1 13:30:22 2008 -0300 Remove a stray '}' commit 7f2a748c01d7bbcb0994f75155ced582f0ef29b2 Merge: 662830b... d1a51f6... Author: William Lachance Date: Fri Aug 1 11:13:33 2008 -0300 Merge branch 'master' of ssh://repo.or.cz/srv/git/wvstreams commit 662830b6fc2e937abf47d273942a85c9ab46b56a Author: William Lachance Date: Thu Jul 31 20:51:28 2008 -0300 Don't create wvxplc pkg-config file, that was an artifact of the (no longer present) built-in XPLC. commit 683d1389d9124fc1369bb6bd9bfa7fce6e32c91e Author: William Lachance Date: Thu Jul 31 20:44:56 2008 -0300 wvdbus is really rather self-explanatory, just takes out its (totally outdated) descriptive comment and let the source be its own documentation. commit d63755e4aee04ade971dede6a9d82e8c4bbad6bd Author: William Lachance Date: Thu Jul 31 20:19:27 2008 -0300 if (foo) delete foo --> WVDELETE(foo) commit a6b5aecc2a780265e03f0c7aa0f5911f37f4ca76 Author: William Lachance Date: Thu Jul 31 20:16:26 2008 -0300 Make sure transaction generator really ignores key sets with trailing slashes, like all the other generators. It was just creating these keys but not setting any value for them. Also add a unit test to the uniconfgen sanity tester to make sure this doesn't happen for any other generators. Patch based on a problem description from Theodore Opeiko (topeiko@ca.ibm.com). commit 4d9dbeb6c291d39f852cd29e7a475e056ec69d63 Author: Lukasz Kosewski Date: Thu Jul 31 17:37:40 2008 -0400 Added 'fingerprint' grabbing to WvX509. Unbeknownst to me until today, openssl has a way of grabbing the 'fingerprint' of an SSL certificate. Since this is a fairly good way of figuring out whether we have the certificate we're looking for, it's handy to get this value out of WvX509. Done, via get_fingerprint(mode), where mode will determine whether we get a SHA-1 or MD5 cert. commit d1a51f6196902f7843ebfce2a1221bdb7f30c918 Author: Avery Pennarun Date: Wed Jul 30 21:30:06 2008 -0400 Don't try to build ipstreams/tests/wsd on win32. commit 156d607824d471d846db50096b764af0bb59c22b Author: Avery Pennarun Date: Wed Jul 30 21:20:24 2008 -0400 dbus/wvdbusserver.cc: fix a warning. commit 6d5c8234f6f58a0bfa8133cc94778c48a2faa6ed Author: Avery Pennarun Date: Wed Jul 30 21:17:59 2008 -0400 win32/wvautoconf.h was zero-length and not used for anything. Delete. commit 4f2c5147a03589bc28c798cfeb723c79ebdfc027 Author: Peter McCurdy Date: Wed Jul 30 19:11:09 2008 -0400 Atomically create/update files generated by gen-cc. Running make -j2 would sometimes cause gen-cc to be run twice at once. Since gen-cc removed the existing target file before rewriting it, the second gen-cc instance would remove the file while the Makefiles were trying to use it. Now we write to a temp file, and atomically move it on top of the target file. commit cc1c00b9c14211dfd99e9e6bc6d59848f0e33797 Author: Lukasz Kosewski Date: Mon Jul 28 20:41:51 2008 +0000 Reordering functions in wvstreams.h header. The end of the wvstreams.h header was polluted immesurably by a bunch of variables and functions intertwined with public/private/ protected macros. This has been slightly rearranged and beautified... of course, nobody /actually/ surfs wvstream.h without ctags. commit af1eaec7311661de98d340c26842ec8cbea167d4 Author: Lukasz Kosewski Date: Mon Jul 28 20:26:03 2008 +0000 Changed .*PACKAGE.* defines to .*WVPACKAGE.*. Apparently, PACKAGE macros generated by autoconf occasionally caused conflicts for us. That's no big surprise, given that the macros are always PACKAGE_* for many variables for every project that uses autoconf. Since we assign the variables into variables of our own name in config.mk, I changed those into WVPACKAGE variables, and added back a little 'sed' stub at the end of config.ac to substitute variable names in wvautoconf.h. commit b0e47c0e95c104d73b9b64f577687c72eb80b670 Author: Lukasz Kosewski Date: Mon Jul 28 19:13:07 2008 +0000 WvAttr get no longer returns "" but an empty WvString if no key. commit bcd54aba01801f85b3cacbc892127f569ad2219d Author: Lukasz Kosewski Date: Mon Jul 28 13:33:23 2008 -0400 Cleanup of WvAttrs. Changed getattr/setattr to get/set. commit 24ed89f3e1e24778153441bb23081173e031aea4 Author: Lukasz Kosewski Date: Mon Jul 28 16:55:00 2008 +0000 Added a WvAttrs object with getattr/setattr functions. Soon-to-be incorporated into WvStreams and WvListeners near you! A framework for setting key, value pairs and retrieving the values. Performance isn't great (don't overuse it!), but minimal overhead (2 bytes per key/value pair + sizeof(key + value)). Unit testing also added. commit 9b81ffd48bc5bbcbd3718d3d5465011e082964de Author: Lukasz Kosewski Date: Sat Jul 26 16:40:35 2008 +0000 Removed lines that broke build from configure.ac. The very end of the file had a bunch of lines (which were never executed), which I fixed to 'work properly.' Basically, they stripped 'PACKAGE_*' variables from wvautoconf.h. When they executed, though, we couldn't build. Huh. I've just removed them entirely. commit 6c4d3e91371a87b20b191b2cc14535c31d241166 Author: Lukasz Kosewski Date: Sat Jul 26 16:39:47 2008 +0000 Change wvdbusd.so and wvdbus/wvdbusd build order. Oops. We really shouldn't be building programs without the library they need to link against. Changed build order. commit 5afa02833b7189df866fb367f7db0c3cca113c49 Author: Lukasz Kosewski Date: Sat Jul 26 16:11:29 2008 +0000 Fixed building of ipstreams/tests/wsd. The convoluted logic of our Makefile for this program was strange... in order to ensure that we were building it with readline, we ripped it out of 'TESTS' and it used a custom build rule which didn't work. Fixed by adding 'ipstreams/tests/wsd-LIBS+=-lreadline'. commit 8b55abe8a3f5f031998ea1d2a674fc84aa5f96c8 Merge: 7d623f6... 05f1298... Author: Avery Pennarun Date: Sat Jul 26 02:27:37 2008 -0400 Merge branch 'build-system-rebase' This sequence completely rearranges the WvStreams Makefile system. It's way cleaner now. Hopefully I haven't introduced any major/unfixable problems. install.mk still contains some old "make install" related stuff that needs to be put somewhere and/or cleaned up, but most people never make install wvstreams anyway, so it's not obvious exactly what we should do with it. * build-system-rebase: UniRegistryGen unit test shouldn't use a global variable for no reason. Fix building in win32, much much cleaner this time. Fix ridiculous file layout in Win32WvStreams folder. Change the %: %.in rule to %.subst to avoid conflicts with config.mk.in. Use modern gcc's dependency generation (-MMD -MP -MF). wvcc compiler macros now generate explicit CC and CXX scripts. Make unit tests compile again. Forget all those old .a files, just make a big libwvstatic.a. Got rid of now-unused aclocal.m4 crap. Saner handling if config.mk doesn't exist: use a default config.defaults.mk. Remove redundant wvlink_ar declaration, and more Makefile cleaning. Make the DEBUG_* flag stuff actually work as intended. Merged most of the tiny crap Makefile fragments into Makefile. commit 7d623f6ddec367bb3b31d6dd058ae1e13cb0c5a1 Merge: bbe084d... 4834436... Author: Avery Pennarun Date: Sat Jul 26 02:26:42 2008 -0400 A selection of relatively minor problems in the build system. I found these while doing more major surgery, but these fixes should be harmless by themselves. * build-system-bugs: Oops, wvdbusd.cc depended on WVSTREAMS_RELEASE define. Fix compiler warnings in wvcallback.t.cc. configure: remove code for generating 'reconfigure' script. .gitignore for uniconf/daemon directory. svn2cl is obviously no longer needed, since we're using git now. Remove obsolete bindings/ directory. commit 05f129887aea4bd6bded5ecf22a7eed4199153b8 Author: Avery Pennarun Date: Fri Jul 25 21:58:20 2008 -0400 UniRegistryGen unit test shouldn't use a global variable for no reason. commit 96e378df80f00b9ca739e16b95052957425f0617 Author: Avery Pennarun Date: Sat Jul 26 01:26:01 2008 -0400 Fix building in win32, much much cleaner this time. No more need for stupid Makefile-win32, yay! commit b7d0d0e7a1a258e842231bb5610d0b09aa5eb0a5 Author: Avery Pennarun Date: Fri Jul 25 15:24:49 2008 -0400 Fix ridiculous file layout in Win32WvStreams folder. commit c010ace31984a84bdc48f83dfd35e9be127b913e Author: Avery Pennarun Date: Sat Jul 26 01:19:10 2008 -0400 Change the %: %.in rule to %.subst to avoid conflicts with config.mk.in. Otherwise it "cleverly" auto-substitutes the file when it doesn't exist, causing insanity. commit 5f978df5b8266b33efd292e41ca0d8f28e2ba5d6 Author: Avery Pennarun Date: Fri Jul 25 23:53:14 2008 -0400 Use modern gcc's dependency generation (-MMD -MP -MF). This lets us finally avoid the stupid two-step dependency file generation, so things can go a lot faster now. fixdep.pl is no longer needed. commit 4b5ef910a56fcc86f29ba9b2b3e02b48a4ad8e4c Author: Avery Pennarun Date: Fri Jul 25 23:40:38 2008 -0400 wvcc compiler macros now generate explicit CC and CXX scripts. This gets rid of the need for "make VERBOSE=1", at least for the compilation stage if not the linking stage. The commands look like a simple "CC -c filename", and if you run that from the prompt, it'll do exactly the same thing as when make does it. Borrowed this idea (but not implementation) from djb's Makefiles. commit e75f6ec25691a5594ef4692454a24c3551dfd47c Author: Avery Pennarun Date: Fri Jul 25 21:05:32 2008 -0400 Make unit tests compile again. Plus fix dependencies of various test programs. Improvements to "make clean", and fixed a few typos. commit 9e313eb26a3a466c98b94e3e215002eb6d466e9e Author: Avery Pennarun Date: Fri Jul 25 18:02:15 2008 -0400 Forget all those old .a files, just make a big libwvstatic.a. As a bonus, moved a bunch of related stuff together so Makefile actually makes sense now. commit 4767557b37a88e0d93a084503f0a8abec4a16066 Author: Avery Pennarun Date: Fri Jul 25 17:32:43 2008 -0400 Got rid of now-unused aclocal.m4 crap. That's right! We no longer need aclocal at all when building WvStreams! Death to automake! commit ad01fb037322a529f79a34c8a8c4b74698e60ee4 Author: Avery Pennarun Date: Fri Jul 25 17:28:36 2008 -0400 Saner handling if config.mk doesn't exist: use a default config.defaults.mk. Stole this idea from git. Basically, if you don't run configure, you might still be able to compile, but maybe not. And you can run ./configure if it doesn't work. commit 37d75045a11b6c0578bbf496f4bcf235180c5e20 Author: Avery Pennarun Date: Fri Jul 25 17:02:18 2008 -0400 Remove redundant wvlink_ar declaration, and more Makefile cleaning. commit 6ad49c0f6bf7a44a53fe84127321c792d6a20df6 Author: Avery Pennarun Date: Fri Jul 25 17:02:18 2008 -0400 Make the DEBUG_* flag stuff actually work as intended. I don't know who intended it, but it didn't really work. commit a7eee5bd5f8d726ebb1197204d6f93a36f180157 Author: Avery Pennarun Date: Fri Jul 25 13:49:23 2008 -0400 Merged most of the tiny crap Makefile fragments into Makefile. But left a few behind in crap*, to be cleaned up later. Basically those are the unit tests, which don't work for the moment. Remove weird support for building xplc as part of wvstreams. Remove old msvc build stuff. I'm not sure anybody *ever* used it, but I'm sure it's broken now, and it would have to be totally redone anyway. I *really* don't want to know why Makefile was setting VPATH. commit 4834436344c0ca17fd587f7ee24e91fa0da7fa87 Author: Avery Pennarun Date: Fri Jul 25 23:43:50 2008 -0400 Oops, wvdbusd.cc depended on WVSTREAMS_RELEASE define. Use PACKAGE_VERSION from wvautoconf.h instead. commit e40626a415d12f3b932c6c864db12f74c5ee5629 Author: Avery Pennarun Date: Fri Jul 25 21:58:55 2008 -0400 Fix compiler warnings in wvcallback.t.cc. commit 220f9eb8a6b5f820adbef7bfe59501bebd7f2587 Author: Avery Pennarun Date: Fri Jul 25 21:23:13 2008 -0400 configure: remove code for generating 'reconfigure' script. Newer autoconf is insane and breaks it in a way I can't see how to resolve. God, I hate these people. commit c4d5b7792e86bd0d8f373d37fdd94ac6e5837cf8 Author: Avery Pennarun Date: Fri Jul 25 21:05:12 2008 -0400 .gitignore for uniconf/daemon directory. commit 011ad14480f7e316bd890cb99127cf31332007cb Author: Avery Pennarun Date: Fri Jul 25 15:20:31 2008 -0400 svn2cl is obviously no longer needed, since we're using git now. commit 4b22c1f02fc4b0d7db4d87d3fe5e21ad0952c30a Author: Avery Pennarun Date: Fri Jul 25 13:49:42 2008 -0400 Remove obsolete bindings/ directory. commit bbe084d4039538adfc9eb7db37be92e31f5f9d5e Author: Avery Pennarun Date: Fri Jul 25 13:23:11 2008 -0400 Fix missing library when linking libwvqt. commit 161dcc3dbdbfaec5440937a6f7811bf9f511b90c Author: Lukasz Kosewski Date: Mon Jul 21 20:45:47 2008 +0000 Modified wvdbusserver unit test to work with DBusServer fixes. The wvdbusserver unit test began failing because of two things: a) It called 'delete' instead of WVRELEASE(...) on the DBusServer object -> no good! b) It didn't run the globallist anymore once the last connection was dead, never invoking the callback which would remove it (it's a delayed callback now), thus 'leaking memory' in Valgrind's humble opinion. Fixed. commit 2388599c2aba70fc081945fd251afebe1500f094 Author: Lukasz Kosewski Date: Mon Jul 21 20:41:43 2008 +0000 WvDBusServer no longer causes segfault when connection dies. WvDBusServer had a wonderful little glitch in it. If a connection died, a callback was invoked to remove it from the linked list of all connections in the server. This is fine, except one of the places a connection could die was while we were in a 'broadcast' loop running an iterator over all the connections. Once we removed a connection from the list in this loop, the poop hit the fan, of course, as the iterator we were on was no longer meaningful. Solution? WvDelayedCallback for removal! Some other changes had to be made, to refcount the connection (so that it doesn't get deleted until we tell it to in the callback), as well as for the DBusServer object itself (so that the delayed callback never runs on a deleted DBusServer, trying to remove connections from its instance variables). commit b2fbaa6207463d6b1eb235a009cf79e4c6a78fc6 Author: Lukasz Kosewski Date: Fri Jul 18 20:24:57 2008 +0000 Fixed wvdelayedcallback unit test. Based on recent changes to WvDelayedCallback, deleting a wvdelayedcallback doesn't actually kill the stream inside it. As such, the test where a wvdelayedcallback is killed, globallist.runonce() is executed, and the value of a variable updated by the contained stream was expected to remain unchanged, will now actually change. Unit test updated. commit bc50c39c7c2132c48e07c91bfd51cb20b0c7687c Author: Lukasz Kosewski Date: Fri Jul 18 20:28:03 2008 +0000 Wvdelayedcallback no longer resets callback of stream within. When we kill a wvdelayedcallback, this no longer resets the callback of the stream contained within to (0), had it been triggered. We want this behaviour so that we can assign delayedcallbacks to the 'setclosecallback' function, which immediately deletes the callback after triggering (which, previously, meant that the stream contained in a wvdelayedcallback would never go off if the callback was assigned to setclosecallback). commit 0ad83ca27a79e75e2b1ae69a28b0073c7f50b103 Author: Avery Pennarun Date: Thu Jul 17 19:13:28 2008 -0400 The callback should be called on a stream even if !isok(). This set of bugs was causing trouble with WvDelayedCallback, and probably other things. It probably was causing a rare crash bug in WvHttpPool too. Basically, we would never call pre_select() or post_select() if !isok(), which was unnecessarily "too safe." It's their job to decide if they don't want to do stuff because they're not isok(), and they were doing pretty much fine at that job, so removing the checks was harmless. However, removing the checks changed the behaviour of the IWvStreamList::sure_thing list subtly, revealing that we forgot to addRef() a stream upon adding it to that list. In rare conditions where a stream would auto-remove itself from a streamlist in the middle of a select() sequence, the stream would be deleted but still in sure_thing, causing weird bugs. So now we addRef() before adding a stream to sure_thing, where we now set auto_free=true so it will release() automatically. We also have to addRef() when taking it *out* of sure_thing to call it (since we've always deliberately removed the stream from sure_thing *before* using it to avoid other weird race conditions) and release() it when we're done. Added new unit tests that verify that alarm() will still work even after a stream is close()d. But only once, of course, since the stream is dropped out of the list after that. commit 7b8ee9d9418d8f7a972cac3ac7a1650add2a54e6 Author: William Lachance Date: Mon Jul 14 16:12:56 2008 -0300 Handle blank lockfiles correctly, don't think we're locked when we're not. commit 58df272ef57c61d10b93663fc0f5d015416235b1 Author: Avery Pennarun Date: Sun Jul 13 21:33:45 2008 +0000 Added missing -lz to libwvstreams.so. This was revealed by the earlier patch that adds -Wl,defs to the linker. commit 319035e4fa62fa2e9830a83f44ae1c8948f6b3f2 Author: Avery Pennarun Date: Sun Jul 13 21:36:54 2008 +0000 Link with -Wl,defs to detect any undefined symbols right away. commit 7e68fbc8ef3e866e8fcf40c335356952782427bd Author: Avery Pennarun Date: Sun Jul 13 20:12:49 2008 +0000 Fix compilation with old g++ 3.3.5 and debian-sarge. A few too many things were private in unihashtree.h. wvdbusserver.h depended on . commit 1c625871a8b6f0db415e069c16d9d14030a03628 Author: Avery Pennarun Date: Sun Jul 13 21:36:36 2008 +0000 Autodetect whether __libc_stack_end is available or not. It's apparently not in Debian-sarge's libc, at least not if you're building a shared library. (For some reason, it *does* link okay if you're building a normal binary.) commit 9b2b76f8767c6888b518f597d8b57abcba1df6a3 Author: Avery Pennarun Date: Thu Jul 10 00:10:37 2008 -0400 Add wv::delayed(), an auto-typing alternative for WvDelayedCallback. Works more like wv::bind(), in that you don't have to specify the template type explicitly. You can just say wv::delayed(func) and it'll work, instead of WvDelayedCallback(func). commit 053e40ea2676650f1493fc94d43d31f1caa58c5c Merge: a7b8906... d1b842c... Author: Lukasz Kosewski Date: Sat Jul 5 00:51:40 2008 +0000 Merge branch 'master' of git+ssh://repo.or.cz/srv/git/wvstreams Conflicts: streams/t/wvlog.t.cc commit a7b89066bb3c0345fed028bccdfbd4735d73d1a2 Author: Lukasz Kosewski Date: Sat Jul 5 00:41:06 2008 +0000 Fixed wvargs.t.cc - Removed a stupid ifdef that checked if the "HAVE_POPT" flag was set (we don't use this flag anymore, so it was never set). - Fixed it so that it doesn't spew a million warnings with -Werr using gcc 4.2.x. - Used it to track down errors in the standalone argp library we now use for Windows. commit 73b29a98adc8176bf1254599753683c62e0bf243 Author: Lukasz Kosewski Date: Wed Jul 2 03:06:07 2008 +0000 Make win32 builds use argp-standalone Make the configure scripts have a '--with-argp' argument for building ie. on Windows (without argp in libc). commit d1b842c8e370264a679c6f5808a233e80f4fc7d5 Author: Peter McCurdy Date: Mon Jun 30 15:06:03 2008 -0400 Fix the build on Unix, by hiding an incompatible call only needed for win32. commit 6602a48116ce0feb4fbfd45f190bae173456bae1 Author: Lukasz Kosewski Date: Sat Jun 28 02:19:20 2008 +0000 Removed gnulib entirely from wvstreams. Wvstreams no longer has gnulib. It builds fine on Linux (as any modern glibc has argp built in, which is the only function we used out of gnulib), but of course will not build for Windows now. Fixing that. commit 801df016d4f8e6cb0d407bb9eb624b4819c15319 Author: Lukasz Kosewski Date: Sat Jun 28 02:16:49 2008 +0000 Fixed 'mkdir' call to be 'wvmkdir' (and thus accept one parameter). commit 375cb8a0b0c8c6ef75a464ebc2949faab359581d Author: Avery Pennarun Date: Fri Jun 27 20:38:53 2008 -0400 wvrsa.t.cc: split a test into two parts for easier debugging. commit 69b7133df32f931240bfdaedc0cce5e3842ebbe3 Author: Avery Pennarun Date: Fri Jun 27 19:47:58 2008 -0400 Fix problem with running wvlog.t.cc on win32. commit 98f1301adf5ba6defa23cdde0637792251f90cb3 Author: Peter McCurdy Date: Fri Jun 27 17:46:26 2008 -0400 Fix a typo in a debug log message. commit 168049f7ba1de4d43ca3c78032342af7055c4e4c Author: Peter McCurdy Date: Thu Jun 26 16:12:55 2008 -0400 Fix the wvstreamsdaemon.t.cc unit tests. These tests had been mis-updated to the new WvListener API. commit 19736e97ce35c702160f6c6c4d34fafbff1866b0 Author: Peter McCurdy Date: Thu Jun 26 16:11:56 2008 -0400 Yet more char* const-correctness fixes for gcc 4.2. This is the last round, I promise; WvStreams now builds cleanly with -Werr on gcc 4.2.3. commit f99c1e1d86148a01239eccdb81f7a5ee06b5a4f1 Author: Peter McCurdy Date: Thu Jun 26 03:38:57 2008 -0400 Fix WvDBus unit tests. Previously, we were passing a unix: moniker to WvDBusServer. However, WvDBusServer didn't actually used to take a moniker, it would just pass the string directly to a WvTCPListener, which interpreted it as an IP address, and defaulted to 0.0.0.0 when given an obviously-not-an-IP-address string like a unix: moniker. WvDBusServer::listen() now takes a proper moniker, but this exposes the fact that WvDBusServer::get_addr() only works for tcp: connections. Oops. So the quick fix is to just specify a tcp:0.0.0.0 moniker off the bat, as it's what we've always been using anyway. commit 30de1bf87ad93b6fa105593a27cb26b1c67c1e80 Author: Peter McCurdy Date: Thu Jun 26 03:15:48 2008 -0400 Update .gitignore entry for the wsd binary. commit 2cfc2224afbc7e427f4d7d585f5bd67b4b36beca Author: Peter McCurdy Date: Thu Jun 26 03:12:07 2008 -0400 Placate gcc 4.2 with more char* const correctness fixes. This round is from the standalone test programs. commit e0225f05b14216d62f28598936fd8f880bfa8d23 Author: Peter McCurdy Date: Thu Jun 26 03:02:59 2008 -0400 Suppress the usual round of Valgrind problems from libc 2.7. commit 0d998e288421f8251dc5fd8ee93b3371b3305067 Author: Lukasz Kosewski Date: Thu Jun 12 00:24:30 2008 -0400 Fixed a bunch of wvstreams tests for 64-bit Linux. (sizeof(long) == sizeof(void *) under 64-bit; sizeof(int) != sizeof(void *), so it would be hard to case void *'s to ints). commit ea126abbb2b16148a6281e92ceba6bcb9185ee3d Merge: d3ede7b... e92261e... Author: Lukasz Kosewski Date: Wed Jun 11 21:19:07 2008 +0000 Merge branch 'master' of http://repo.or.cz/r/wvstreams commit d3ede7b3d4e66e6ac36c1dd030d881203f80fd98 Author: Lukasz Kosewski Date: Wed Jun 11 21:01:16 2008 +0000 Changes to the configure script and wvargs.cc to make sure that we don't end up redefining "error_t" if it's already defined. commit e92261ef850d7b5389e1a9720ad4ae621f9f5e88 Author: Avery Pennarun Date: Wed Jun 11 02:21:51 2008 -0400 Add missing .gitignore entries for various test programs and data files. commit 49710dd0ffb28cbdfacee447fa99822b6bd4e60b Author: Avery Pennarun Date: Wed Jun 11 02:22:18 2008 -0400 Fix various test programs that stopped compiling with recent WvListener changes. Oops; I guess I wasn't running "make test" enough. In fact, "make test" still doesn't pass, as I seem to have completely broken something in the dbus tests awhile ago. But at least it compiles now. commit 22adfe81a7193729c4600d9bc7ac2185f2e7d1bb Author: Avery Pennarun Date: Wed Jun 11 01:52:17 2008 -0400 Get rid of some warnings produced by newer autoconf versions. Based on suggestions found in: http://www.nabble.com/new-AC_USE_SYSTEM_EXTENSIONS-breaks-Interix--td13297455.html Hopefully this doesn't break *older* autoconf versions. Perhaps we should upgrade gnulib. commit 0dc65b47b18e17ce7f195601815a084446d262ed Author: Avery Pennarun Date: Wed Jun 11 01:36:13 2008 -0400 Always compile with -fPIC. Avoids problems on x64 platforms, as discovered by George Washburn. commit 16acd050e7da35c9014fc8bcd6d43dee340d3fc1 Author: Avery Pennarun Date: Wed Jun 11 01:29:07 2008 -0400 configure: properly find libdbus.a if it isn't in /usr/lib. Based on input from George Washburn. commit 4b5e4ea4c6f08fd11c45880faf653ae137c4b735 Author: Peter McCurdy Date: Wed May 21 14:53:02 2008 -0400 Add some undefined overrides to prevent accidental WvString misuse. Recent changes to make some WvStreams functions take const char*s as id parameters means that they now silently accept WvStrings due to WvString's automatic const char* cast. This is undesirable (and the original reason why the id parameters were non-const char*s in the first place), as the functions keep a long-term reference to the string, which doesn't agree with WvString's reference counting. These overrides ensure that users can't accidentally send a WvString to these functions. commit dc55b909bf6274a7e6f5d24bb17b6ff805ea1e4a Author: Peter McCurdy Date: Wed May 21 14:44:59 2008 -0400 More char* const correctness fixes to keep GCC 4.2 from spewing warnings. commit 41a7fbc5c6d7e52fe7bf8dac455d0afb3da34ba0 Author: Peter McCurdy Date: Thu May 15 16:54:56 2008 -0400 Fix the build for 32/64-bit multilib systems. Problem and patch originally reported by Axel Bergerhoff to wvstreams-devel@googlegroups.com. commit 1c153171833ab8e4983f914793c036a5f7465392 Author: Peter McCurdy Date: Thu May 15 16:51:34 2008 -0400 Fix more const char* warnings from GCC 4.2. Make some variables const char* where possible, so they can be assigned string constants. Where not possible, cast string constants to non-const char*s. Remove an overload from WvIStreamList, as it already had a basically identical overload that took a const char* instead of a char*. commit 6a913a644f615dc32b7b31834fce73610b48e837 Author: Peter McCurdy Date: Thu May 15 15:39:01 2008 -0400 Fix building the unit tests. They still don't quite run yet though. commit b4611b9810411ceb413ad6dcd8114d8c6be460fc Author: Peter McCurdy Date: Thu May 15 15:32:52 2008 -0400 Fix some warnings from GCC 4.2. GCC 4.2 complains when you assign a string constant to a char* variable. Change some char*s to const char* to get it to calm down a bit. commit ea8d8f63d96eb6827dcd559d5961a7843fe71e44 Author: Peter McCurdy Date: Thu May 15 15:29:18 2008 -0400 Fix the build when using Valgrind 3.3. Valgrind 3.3 removed some macros that were apparently deprecated in version 3.2. Update to the new macros, which work in version 3.2 and up, but also maintain compatibility for 3.1 and before. commit ba02fb931b260dcf8d20869edc570e5c1dab5566 Author: Avery Pennarun Date: Fri Mar 21 15:31:14 2008 -0400 Fix building on win32. commit 92d309b41faab2c60544253251470a82080bb1ad Author: Avery Pennarun Date: Thu Mar 6 00:56:47 2008 -0500 WvUnixListener, WvListener "wrapper" support, and SSL listeners. WvDBusServer and UniConfDaemon can now listen on any number of arbitrary listen sockets, and can wrap in SSL, etc, automatically if you give them the right moniker. Also fixed some problems with wvdbusd and the new php-dbus client. PWvStream now gives more useful error messages if a moniker can't be constructed. Fix a bug in wvargs multiple required arguments support. commit 5bf67800a856cac0e7ec1d9d506874b9842efed5 Author: Avery Pennarun Date: Wed Mar 5 20:34:36 2008 -0500 More .gitignore files. commit 7bbf488141df9bf5d5ad44fdc8d216459b25ffff Author: Avery Pennarun Date: Wed Mar 5 19:57:44 2008 -0500 .gitignore commit 19f4e9b225477309486a3b3fdcd012cc05ff40fe Author: apenwarr Date: Thu Jan 31 02:12:00 2008 +0000 WvDBusMsg::is_reply() had an unnecessary hack for message #1. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11863 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 04842e4ad13fa19b7083e61ffa2926dab0a41493 Author: apenwarr Date: Tue Jan 29 02:09:29 2008 +0000 In win32, don't link uniconfd.cc into libwvwin32.a. It results in multiple _main() functions. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11861 6619c942-59fa-0310-bf43-a07aaa81d9ac commit cf618adac3caab65c2882e389fe488f4a984c2a3 Author: apenwarr Date: Sat Jan 26 01:18:59 2008 +0000 WvDBus: better error reporting. When printing REPLY DBus messages, print ERR#xx instead of REPLY#xx if it's an error message. In WvDBusServer, don't mark a message as "handled" if there's no matching connection for a service; return false and let another handler try to handle it. When everything has failed, send back a NameHasNoOwner error instead of just failing silently; this way clients can recover gracefully. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11859 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 200db1b966224de75e57498a1f20ce0d09bd6351 Author: apenwarr Date: Fri Jan 25 15:27:20 2008 +0000 andrei@versabanq.com: wvdbusd: handle *all* messages addressed to o.f.D. Before, wvdbusd would forward unrecognized methods onward to be proxied, which was probably a security hole and also resulted in the strange "no destination for service org.freedesktop.DBus" when it really meant "unrecognized method xxx". Now we handle *all* messages addressed to our service, and never try to proxy them. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11857 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 7c9635abc81fc730f1c82196b324698c483e94f0 Author: apenwarr Date: Fri Jan 25 15:14:23 2008 +0000 andrei@versabanq.com: wvdbusd: implement GetNameOwner call. This is needed for dbus-python support. With this change, python seems able to talk to versaplexd over wvdbusd. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11855 6619c942-59fa-0310-bf43-a07aaa81d9ac commit bf6c4069e8f86c1c67c230aad0492545bd67e921 Author: apenwarr Date: Fri Jan 25 15:13:36 2008 +0000 andrei@versabanq.com: wvdbusd: name connections :%s.0 instead of :%s. This fixes some problems connecting to wvdbusd from python, which seems to want to parse the opaque connection name string for some reason. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11854 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 1d324757252931bcfe70bb8558e64bab4cd5865d Author: apenwarr Date: Thu Jan 24 20:48:37 2008 +0000 Fix wvuid.cc compilation under Linux (of course). git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11852 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 7ca84c33d882662ad575452be27400b030cf327c Author: apenwarr Date: Thu Jan 24 20:35:35 2008 +0000 Fix uid portability. WvDBus's new unix uid/username stuff was not portable to Windows. Add new wvuid.h/wvuid.cc to make the API the same across Windows and Unix, but didn't really implement it in Windows yet. (Eventually, perhaps we should do it by using SIDs, which are apparently strings, but the stub functions make wvdbusd compile and work, at least.) git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11851 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 0047a21c721b12f328ad5999c61082223a88b7b8 Author: apenwarr Date: Thu Jan 24 19:20:00 2008 +0000 Fixup a comment in wvdbusmarshal.cc. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11850 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 96e3038eee8da27850211e4bb592c0dc958b888b Author: apenwarr Date: Thu Jan 24 19:17:08 2008 +0000 GetConnectionUnixUser unit tests were misusing WvDBusConn callbacks. Sometimes they would respond to the wrong message, failing randomly. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11849 6619c942-59fa-0310-bf43-a07aaa81d9ac commit d80a58c169022f2e8c2be867d80357fadba4c9b2 Author: apenwarr Date: Thu Jan 24 17:50:35 2008 +0000 Like in win32 build, wvdbus and wvdbusd should be built in unix automatically. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11848 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 8f612657fe1971987fa383232b4dd163adeb2f45 Author: pmccurdy Date: Thu Jan 24 02:21:34 2008 +0000 Add an extension to the GetConnectionUnixUser method on the org.freedesktop.DBus object, GetConnectionUnixUserName. This just returns the name of the unix user id associated with a given connection. Also implemented some basic unit tests for both methods. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11847 6619c942-59fa-0310-bf43-a07aaa81d9ac commit b13048b7d0b128df30917b6733552d341d8426a3 Author: pmccurdy Date: Sun Jan 13 07:01:32 2008 +0000 Implement the GetConnectionUnixUser method on the message bus. In keeping with the spirit of the rest of the authentication code, it can charitably be described as "liberal" in terms of the values it accepts from clients. If it proves to be too difficult to make robust, we may want to take it out later. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11846 6619c942-59fa-0310-bf43-a07aaa81d9ac commit ecf29168ee3637ae444584dc38dd775c23eace6c Author: pmccurdy Date: Thu Jan 10 00:34:48 2008 +0000 The DBus bus has the responsibility of setting the sender of a message when bridging a message to its recipient (not the sender's DBus implementation, as one might think). Do this in WvDbusServer so recipients can know who's talking to them. Also added some basic unit test checks to ensure that the sender is at least set to something, and renamed a variable that was shadowing another. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11845 6619c942-59fa-0310-bf43-a07aaa81d9ac commit ba1333816cf091217cf505b4c30905de8a8f5213 Author: pmccurdy Date: Thu Jan 10 00:21:34 2008 +0000 Update the Valgrind suppressions file to account for the (totally depressing number of) Valgrind warnings and errors that come out of a Ubuntu 7.10 installation. In particular, suppress some errors in zlib, ld, and getgrnam(), and tell Valgrind to ignore some static members in WvHashTable and UniConfKey that make it spam "possibly lost" messages to the log file when running the unit tests. This cuts the size of the valgrind log file from 1.1 MB to 222 KB when running the full test suite. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11844 6619c942-59fa-0310-bf43-a07aaa81d9ac commit b4601208343dcc5adfa13ba4d6242976ea0a16cf Author: apenwarr Date: Wed Jan 9 20:01:03 2008 +0000 Via andrei@versabanq.com: make WvStreams-win32 compile with the latest mingw32 in Ubuntu-gutsy. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11843 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 50ab57cb99c2d6f664fa883035220e3c419fcc9e Author: pmccurdy Date: Thu Dec 20 07:31:56 2007 +0000 WvTest now checks the WVTEST_DISABLE_TIMEOUT environment variable. If it is set (and not set to "0"), then the standard 40 second test timeout value is ignored, and tests are free to hang indefinitely. This is helpful when you want to run gdb on a hanging test, but don't want to recompile WvStreams. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11839 6619c942-59fa-0310-bf43-a07aaa81d9ac commit fbf18c7da0cb6d3672b87d35f6052d7eed4a6c52 Author: pmccurdy Date: Thu Dec 20 07:02:35 2007 +0000 Support double values in WvDBusMsg, through an explicit get_double() method, the conversion operators, and get_str() too. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11838 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 4177eff16813d4a6cefff9013fdd52d0e3f1921a Author: pmccurdy Date: Wed Nov 14 07:12:36 2007 +0000 Fix a memory leak if DBus authorization failed. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11837 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 8d8036626c6549ae5feec313c864a5c5e571f045 Author: pmccurdy Date: Fri Nov 2 18:47:41 2007 +0000 Add signed and unsigned 64-bit integer overloads to WvDBusMsg's append() method, so you can send 64 bit numbers in addition to receiving them. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11836 6619c942-59fa-0310-bf43-a07aaa81d9ac commit dccccbdd9872e86b763919fd6ff397d2f016f51c Author: pmccurdy Date: Fri Nov 2 02:42:00 2007 +0000 Fix a typo in a unit test. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11835 6619c942-59fa-0310-bf43-a07aaa81d9ac commit cbfa7617e7a01281e100c2d5f67aa10f31f73ff9 Author: pmccurdy Date: Fri Nov 2 01:31:42 2007 +0000 Fix WvDBusMsg's behaviour with append()ing unsigned chars. DBus defines a BYTE field to be an unsigned char, but append() was only accepting a signed char. This meant that calling append() on a variable of type unsigned char would use append(int), which confused DBus. Now there are overloads for both types of char, so both will get sent as a single byte. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11834 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 0c29878984d4a22da823deef7861891b6bdfce0f Author: pphaneuf Date: Sat Oct 13 21:19:42 2007 +0000 Removed the --enable-exception and --enable-rtti options, and let the compiler use its default settings. The default of disabling RTTI didn't even compile (with the arrival of PWvStream), and this is the kind of stuff that people who worry about such things can just pass 'CXXFLAGS="-fno-rtti -fno-exception'" on the command-line of the configure script. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/wvstreams-ng@11823 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 8cde7b7e21965ccac0fe90d1de2f9d34ca41be79 Author: apenwarr Date: Wed Oct 10 16:46:49 2007 +0000 Don't let configure add "-L/usr/lib" to the compiler command line due to qt, because then wvdial can't build if you have an old wvstreams-dev in /usr/lib. "-L/usr/lib" is implicit, but it's implicitly *last*, which is what we want. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11818 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 5f3adc4b557d4dedd26466e164a5ef4e41113795 Author: apenwarr Date: Wed Oct 10 16:44:57 2007 +0000 Added boost 1.34.1 (just the headers, not the other 80% of the crap, which turns out to be bloaty VC++ project files) to wvports. Changed a couple of minor things to make the win32 build work again and pass unit tests. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11817 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 923c85b10c1eebb369af88290b83ec7c01da97b4 Author: apenwarr Date: Tue Oct 9 04:54:00 2007 +0000 Merged in everything from the dbus-win32 branch using this command: svn merge svn+ssh://svn.alumnit.ca/svn/branches/{death_to_wvcallback@11813,dbus-win32@11815} The dbus-win32 branch is now obsolete. This branch is now the basis for what we hope will be WvStreams 5. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11816 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 9d9121ff49435b4f65e2b5fb1226ae6b4ac6d13a Author: apenwarr Date: Tue Oct 9 04:49:28 2007 +0000 Makefile-win32 didn't run until you had run ./configure. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11814 6619c942-59fa-0310-bf43-a07aaa81d9ac commit dd9499548956e23f8429e2bd584155e1d77ff82e Author: pphaneuf Date: Mon Oct 8 05:04:58 2007 +0000 Simplified UniHashTree and friends a little bit, making more members of UniHashTreeBase private, removing "void *userdata" from a comparator function, removing a template parameter that was always being used the same way. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11813 6619c942-59fa-0310-bf43-a07aaa81d9ac commit debaaa45fa98b8e1d90ff077fc127624a87778c2 Author: pphaneuf Date: Mon Oct 8 03:58:31 2007 +0000 Switched a usage of WvList to, well, uh, an std::set. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11812 6619c942-59fa-0310-bf43-a07aaa81d9ac commit f8a584780c074d32bf0e09c1a02f29880f01333d Author: pphaneuf Date: Mon Oct 8 03:11:59 2007 +0000 Removed WvMap, fixed up some unit tests to use std::map instead. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11811 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 4bd88d0316267ec9be5f83096126c2adbecfceb0 Author: pphaneuf Date: Mon Oct 8 01:40:27 2007 +0000 Oops, left the #include for wvhashtable.h in wvstreamsdebugger.h... git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11809 6619c942-59fa-0310-bf43-a07aaa81d9ac commit ab81459ad92429fd8bcf8bffe760a70b3f2f299d Author: pphaneuf Date: Mon Oct 8 01:33:14 2007 +0000 Switched UniCallbackGen from WvMap to std::map. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11808 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 9218d84cd6e7739633ab2765ed6adc97cab8d648 Author: pphaneuf Date: Mon Oct 8 01:15:18 2007 +0000 Switched WvStreamsDebugger from WvMap to std::map. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11807 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 0c077ea9ba7fd9c0f29d42a101be56a602e6f38d Author: pphaneuf Date: Mon Oct 8 00:28:32 2007 +0000 Replaced WvMap with std::map in wvstream.cc. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11806 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 0eaa08c931c6ef5c526185a952e510057e4d5c22 Author: pphaneuf Date: Mon Oct 8 00:00:34 2007 +0000 Forgot to remove the now unneeded wvhashtable.h from wvstream.h, this being rather essential to the cutting down of recompiles. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11805 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 3287a26359fd5b0a956c1417fc7ba6eda9f1f0a5 Author: pphaneuf Date: Sun Oct 7 23:57:45 2007 +0000 Hiding your private parts is good policy. *And* it reduces recompilations too! git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11804 6619c942-59fa-0310-bf43-a07aaa81d9ac commit bebd2adbac3c375789f0459a61ca771c356fd1af Author: pphaneuf Date: Sun Oct 7 23:35:29 2007 +0000 WvStreamsDebugger was using a very weird combination of putting a pointer in a WvMap, without using auto_free, while the data pointed at had perfectly cromulent value semantics (a small struct with three wv::function in it). Desincomplexifigulated it. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11803 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 317337f127cfbea507160d5cd48936223bdc82ee Author: pphaneuf Date: Sun Oct 7 23:13:25 2007 +0000 Removed the auto_free feature of WvMap, in preparation for replacing it with std::map. Replaced the one use of it in uniconfd.cc with a combination of std::map and shared_ptr. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11802 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 6d883dfb5a226fa46f21e458dc7ebc4bbd6eb5b1 Author: pphaneuf Date: Sun Oct 7 21:58:24 2007 +0000 Hmm, looks like I forgot to commit a few files! git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11801 6619c942-59fa-0310-bf43-a07aaa81d9ac commit a95ee1ca0b9159cf658850f0563edf67f1066bf8 Author: pphaneuf Date: Sun Oct 7 21:42:39 2007 +0000 Added shared_ptr to wvtr1.h. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11800 6619c942-59fa-0310-bf43-a07aaa81d9ac commit ea7ab38124ff4f3da3f1e2b2d47d1f3b32df813c Author: pphaneuf Date: Sun Oct 7 18:23:48 2007 +0000 Renamed wvcallback.{h,cc} to wvtr1.{h,cc}, as it will be used for more than just callbacks. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11799 6619c942-59fa-0310-bf43-a07aaa81d9ac commit cac80b9f151ee31cbb872915a181a8033ad6c613 Author: pphaneuf Date: Sun Oct 7 06:48:46 2007 +0000 Added autoconf test for TR1 and Boost, and put in a check in wvcallback.h that gives priority to TR1. Usage of binding placeholders changed, no need for the namespace prefix anymore, just _1 is sufficient (and by that, I mean that wv::_1 doesn't work anymore!). git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11796 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 05af0005936bfa4a3bbc371df9f60dca864e6c08 Author: pphaneuf Date: Fri Oct 5 15:06:30 2007 +0000 Merged /branches/modern-cxx@11779. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11786 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 45822ca2b1ea99fa3d38ed1eba8b33166277198e Author: pphaneuf Date: Sun Sep 30 23:13:07 2007 +0000 Merged revisions 11760-11767 via svnmerge from svn+ssh://svn.alumnit.ca/svn/trunk ........ r11767 | pphaneuf | 2007-09-30 19:05:28 -0400 (Sun, 30 Sep 2007) | 2 lines This fixes the build for me, but I must be getting old, since I don't really understand this piece of makefile. Or, rather, I know what it does, I just don't know WHY it wants to do that! ........ git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11769 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 9e97b47a049dd991d10927bb01d0b5ab768f32bc Author: pphaneuf Date: Sun Sep 30 17:49:10 2007 +0000 Changed a number of wv::function typedefs (WvStream and WvDaemon related) to not take any parameters, letting people rely on wv::bind instead. No more "void *userdata"! git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11764 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 91d289c3c2e16ad3e752bc0734c2da62d978c32f Author: pphaneuf Date: Thu Sep 27 20:44:12 2007 +0000 Had forgotten one typedef in wvqthook, fixed. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11763 6619c942-59fa-0310-bf43-a07aaa81d9ac commit e8b594560ba938c83e5e37cbb62d4aa0a3409955 Author: pphaneuf Date: Wed Sep 26 03:03:36 2007 +0000 Removed WvCallback, replaced it with aliases to std::tr1::function. Also pulled in a few other things, like std::tr1::bind to replace WvBoundCallback (which is much simpler to use and powerful). Lacking autoconf detection of std::tr1 and fallback to Boost. git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11761 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 935ed423b484336566feab5b5fa295ff58ba213a Author: pphaneuf Date: Mon Sep 24 00:50:14 2007 +0000 Merged revisions 11755-11759 via svnmerge from svn+ssh://svn.alumnit.ca/svn/trunk ........ r11757 | pmccurdy | 2007-09-12 02:11:42 -0400 (Wed, 12 Sep 2007) | 5 lines Add Portugese, French, and Spanish translations. Separate the label used for the toolbar button from the menu entries, as the toolbar button text often needs to be shortened in non-English languages. Update install.rdf a bit. ........ r11758 | pmccurdy | 2007-09-12 03:31:21 -0400 (Wed, 12 Sep 2007) | 2 lines Add a todo list, as there's not enough problems to warrant a bug tracker. ........ r11759 | pphaneuf | 2007-09-23 20:39:00 -0400 (Sun, 23 Sep 2007) | 2 lines Fixed a conflict in some unit tests with the inclusion of math.h. ........ git-svn-id: file:///home/apenwarr/alumnit-svn/public/branches/death_to_wvcallback@11760 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 5ef054a4c6e11775f62a1380add060f919bfc42d Author: wlach Date: Thu Aug 30 03:10:25 2007 +0000 Update debian packaging. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11753 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 158a46abdc6834f5b9a3e3dad536fd212d12264a Author: wlach Date: Thu Aug 30 03:07:37 2007 +0000 Rename suppressions.wv to wvstreams.supp, to be consistent with other valgrind suppressions.x git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11752 6619c942-59fa-0310-bf43-a07aaa81d9ac commit e198b2ac854833f5acabdd6699707a1139451619 Author: wlach Date: Thu Aug 30 02:46:40 2007 +0000 Install wvtesthelper stuff into /usr/bin, so people can run unit tests with all the graphical goodness of the tcl out-of-tree. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11751 6619c942-59fa-0310-bf43-a07aaa81d9ac commit a55cd59c38ba79062ede3ce0bc49763dd8b03f20 Author: apenwarr Date: Fri Aug 17 01:26:31 2007 +0000 Numerous changes to bring /trunk/wvstreams up to date with /branches/wvstreams-win32-2007 (r11726). That branch has already had wvstreams-win32 and eithoneydew merged into it, so all three should now be mostly safe to discard. Unit tests pass in both win32-mingw32 and Linux (although some unit tests are disabled in windows right now, mostly because they use fork()). See the changelog in /branches/wvstreams-win32-2007 for more details. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11727 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 8c04c7e24624e3b0b84d75199a00d55b00120c01 Author: wlach Date: Fri Jul 20 16:40:38 2007 +0000 Tweak wvrsa's encode methods to be const as well. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11661 6619c942-59fa-0310-bf43-a07aaa81d9ac commit a317ded78fe9c73801448cfada4ddba67b77b961 Author: wlach Date: Fri Jul 20 16:39:16 2007 +0000 Some final tweaks to the crypto stuff: make WvCRL handle blank (null) CRLs better, tweak WvCRL's API for const correctness, a few more unit tests for wvcrl. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11660 6619c942-59fa-0310-bf43-a07aaa81d9ac commit adacb69970e9b4eea2fbe1fe32b3eace5693d0e8 Author: wlach Date: Fri Jul 20 16:38:19 2007 +0000 Pull out redhat packaging from dist target. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11659 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 9783ef6752a4f83391243c4a221789ee30b281eb Author: wlach Date: Fri Jul 20 16:37:52 2007 +0000 Updated debian packaging stuff for WvStreams 4.4. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11658 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 2b0777a6753ad3a6b3db567303a4dcfbcd2eae2f Author: wlach Date: Fri Jul 20 16:32:44 2007 +0000 Fix a warning in the uniconfgen sanitytest. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11657 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 2b7b1e3cc0421a2a07638502cb2210bd8cf2c6d5 Author: wlach Date: Fri Jul 20 16:32:17 2007 +0000 Remove a few more unused files/dirs in wvstreams. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11656 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 8ae3efb9bcc0b0d30527f34a5632c0276fee8444 Author: wlach Date: Fri Jul 20 16:31:27 2007 +0000 Remove redhat packaging for wvstreams. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11655 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 3bfadddd9875a4be76d7d80f5243b1c30ccfc453 Author: wlach Date: Thu Jul 19 21:28:23 2007 +0000 Merge the crypto_refactoring branch into trunk, adding a ton of new X509 certificate management features, better CRL support, and lots of other goodies. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11651 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 6ecd5e5afa0537fc0d26db63cdbf6901cc55f257 Author: wlach Date: Thu Jul 19 20:17:49 2007 +0000 Merge in inversion changes from 'wvstreams_inversion_2': pre_select now returns void. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11646 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 475536e6fd8fe32d4a7c638317546429d7c2bd3b Author: wlach Date: Mon Jul 2 20:27:31 2007 +0000 Apply sstasyuk's patch to make wvcrash.cc compile on 64bit machines. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11639 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 73894e1958b453b9195f2effd12310f3027ebfc8 Author: pphaneuf Date: Sun May 13 10:49:25 2007 +0000 There was still traces of the OpenSLP support, which prevented me from building. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11624 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 3c3ce67459e6ee9d0c61b25cb2428b038fb37b69 Author: pmccurdy Date: Sat May 12 16:57:56 2007 +0000 GCC 4.1 compatibility fix taken from RedHat's wvstreams package. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11622 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 28190f0e96b53391e012dec1eb26cedcedb60f86 Author: pmccurdy Date: Sat May 12 16:55:35 2007 +0000 Patch from RedHat's wvstreams packages to make multiarch support work. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11621 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 5639b669715e90e90ad4f8f781a4606c6a5cfb45 Author: pmccurdy Date: Sat May 12 16:54:38 2007 +0000 Compiler compatibility fixes taken from RedHat's wvstreams package. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11620 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 5befa4a1e48c404a985a7ae3c806411b7296dbd7 Author: pmccurdy Date: Sat May 12 16:44:32 2007 +0000 Fix for GCC 4 compatibility: explicitly dereference this-> in a few places so that we create a more obvious dependency for the template. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11619 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 25ea2b27c0c52a62c6b172f3fa4e2edbc91bdf57 Author: wlach Date: Wed Apr 11 17:45:31 2007 +0000 Pull out more ondisk hash stuff I forgot to remove. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11609 6619c942-59fa-0310-bf43-a07aaa81d9ac commit fab2e41276820bffaee69570e2019ae0d75a5a9b Author: wlach Date: Wed Apr 11 04:19:20 2007 +0000 Remove one other artifact of the uniconf c bindings. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11608 6619c942-59fa-0310-bf43-a07aaa81d9ac commit ef1143772511d6f17d0163a39b42fafeb04e2d76 Author: wlach Date: Wed Apr 11 04:13:45 2007 +0000 Remove various bits of unfinished or otherwise deprecated code: bdb hash, slp code, telephony code, SWIG wrappers, and UniConf C bindings. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11607 6619c942-59fa-0310-bf43-a07aaa81d9ac commit bf7e42eb21bb059101e9062588cc088a8a65f81a Author: wlach Date: Wed Apr 11 03:42:50 2007 +0000 Add some suppressions for spurious valgrind errors in libdl and nss in modern Linux distributions. Add unit tests now pass. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11606 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 169e667bc459b27b973d6981cbe31e4ff31e7a33 Author: wlach Date: Wed Apr 11 03:40:07 2007 +0000 Nuke wvhttp class, which is sort of broken and deprecated by wvhttppool. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11605 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 70eb95f6cb33187f4a070faa1ce091400c28bb4f Author: wlach Date: Wed Mar 21 20:09:38 2007 +0000 Manually merge in wvstreams_inversion_preselect (it wasn't branched from freesw, so this was unfortunately necessary). git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11588 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 166d3883578142c7891eced19634a118abf0554c Author: wlach Date: Mon Mar 19 21:52:37 2007 +0000 Fix httptest. Sorry. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11585 6619c942-59fa-0310-bf43-a07aaa81d9ac commit bf3d7ff3a88ffdcfb192ea43501b0e653b3b457e Author: wlach Date: Mon Mar 19 19:22:22 2007 +0000 Fix weird code in WvHTTPStream (not to be confused with WvHttpStream, sigh) which dumped a backtrace of the stack every time it was closed or destroyed. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11578 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 66e2a17dc71150c5bfef3f2a47c235920424db2d Author: wlach Date: Mon Mar 19 19:13:07 2007 +0000 Oops, fix a warning in my most recent commit. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11577 6619c942-59fa-0310-bf43-a07aaa81d9ac commit a904e82b69ce15e8cf4cae38758bd8373038082b Author: wlach Date: Mon Mar 19 19:05:26 2007 +0000 wvhttpstream was completely broken. rewrite it and add a unit test that verifies that it actually works. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11576 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 12887530e8b6cc5aeb6e31f4bf3ed486d81c46a3 Author: wlach Date: Fri Mar 16 20:10:59 2007 +0000 RTTI should be enabled by default. I'm pretty sure this was a simple bug. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11569 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 291fecedf2e40cbf4322819f1787151bb7e729b6 Author: pphaneuf Date: Sun Mar 11 19:20:26 2007 +0000 No need to actually depend on libxplc-cxx.a, it doesn't change much. We still link with it, though. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11560 6619c942-59fa-0310-bf43-a07aaa81d9ac commit e418e4238a4720e7205b7920ad1850f2562d4cab Author: pphaneuf Date: Wed Mar 7 15:46:43 2007 +0000 Fixed README.TESTS, which was using $PATH instead of $LD_LIBRARY_PATH in one instance, and removed an extraneous step (there is no instance of PURIFY in the OpenSSL headers, it's all in the internals of the implementation). git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11549 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 873a0f4de955f24cb1a89444df7ac4c676125591 Author: pphaneuf Date: Tue Mar 6 22:57:47 2007 +0000 Merged from grapefruit. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11547 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 482ac649c7d68c24a432c88837b81ba7fc3f338c Author: pphaneuf Date: Sat Mar 3 12:09:32 2007 +0000 Merged in r11511, apparently the only change done to the wvstreams_4_3 branch. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11527 6619c942-59fa-0310-bf43-a07aaa81d9ac commit 17085388a723081806b2325557ec9a43841d02fc Author: wlach Date: Fri Mar 2 07:26:17 2007 +0000 Make uniconfd's argument handling identical to that of wvdaemon's. git-svn-id: file:///home/apenwarr/alumnit-svn/public/trunk@11510 6619c942-59fa-0310-bf43-a07aaa81d9ac wvstreams-4.6.1/pkgconfig/0000755000175000001440000000000011260431131014531 5ustar wlachuserswvstreams-4.6.1/pkgconfig/libwvutils.pc.in0000644000175000001440000000044111036722347017702 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: WvStreams utilities Description: WvStreams utility library Version: ${version} Requires: libwvbase = ${version} Libs: -L${libdir} -lwvutils Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libwvdbus.pc.in0000644000175000001440000000054111061257315017474 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: WvStreams D-Bus Description: WvStreams-style wrapper for D-Bus library Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${libdir} -lwvdbus Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libuniconf-uninstalled.pc.in0000644000175000001440000000044511036722347022152 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: UniConf Description: The One True Configuration System Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${top_builddir} -luniconf Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvqt-uninstalled.pc.in0000644000175000001440000000046111061257250021502 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams Qt Description: WvStreams and Qt event integration library Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${top_builddir} -lwvqt Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvtest-uninstalled.pc.in0000644000175000001440000000040411036722347022040 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams test Description: WvStreams test library Version: ${version} Requires: libwvbase = ${version} libwvutils = ${version} Libs: -L${top_builddir} -lwvtest Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvdbus-uninstalled.pc.in0000644000175000001440000000046511061257350022020 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams D-Bus Description: WvStreams-style wrapper for D-Bus library Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${top_builddir} -lwvdbus Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvstreams-uninstalled.pc.in0000644000175000001440000000044411061261027022532 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams Description: C++ network libraries for rapid application development Version: ${version} Requires: libwvbase = ${version}, libwvutils = ${version} Libs: -L${top_builddir} -lwvstreams Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvbase-uninstalled.pc.in0000644000175000001440000000033211077372756022005 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams Base Description: Basic subset of the WvStreams library Version: ${version} Libs: -L${top_builddir} -lwvbase Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libuniconf.pc.in0000644000175000001440000000052111036722347017625 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: UniConf Description: The One True Configuration System Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${libdir} -luniconf Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libwvtest.pc.in0000644000175000001440000000046011036722347017522 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: WvStreams test Description: WvStreams test library Version: ${version} Requires: libwvbase = ${version} libwvutils = ${version} Libs: -L${libdir} -lwvtest Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libwvbase.pc.in0000644000175000001440000000040611077372756017467 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: WvStreams Base Description: Basic subset of the WvStreams library Version: ${version} Libs: -L${libdir} -lwvbase Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libwvutils-uninstalled.pc.in0000644000175000001440000000036511036722347022227 0ustar wlachusersversion=@PACKAGE_VERSION@ top_builddir=@abs_top_builddir@ Name: WvStreams utilities Description: WvStreams utility library Version: ${version} Requires: libwvbase = ${version} Libs: -L${top_builddir} -lwvutils Cflags: -I${top_builddir}/include wvstreams-4.6.1/pkgconfig/libwvqt.pc.in0000644000175000001440000000053511061257231017163 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: WvStreams Qt Description: WvStreams and Qt event integration library Version: ${version} Requires: libwvbase = ${version}, libwvstreams = ${version}, libwvutils = ${version} Libs: -L${libdir} -lwvqt Cflags: -I${includedir}/wvstreams wvstreams-4.6.1/pkgconfig/libwvstreams.pc.in0000644000175000001440000000052011061261036020205 0ustar wlachusersversion=@PACKAGE_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/wvstreams Name: WvStreams Description: C++ network libraries for rapid application development Version: ${version} Requires: libwvbase = ${version}, libwvutils = ${version} Libs: -L${libdir} -lwvstreams Cflags: -I${includedir} wvstreams-4.6.1/wvrules.mk0000644000175000001440000001662411253746065014654 0ustar wlachusers# wvrules.mk # # Copyright (C) 1998-2007 by Avery Pennarun # and contributors. # Use, distribute, modify, and redistribute freely. (But if you're nice, # you'll send all your changes back to me.) # # This is a complicated-looking set of Makefile rules that should make your # own Makefiles simpler, by providing for several useful features (like # autodependencies and a 'clean' target) without any extra effort. # # It will only work with GNU make. # # we need a default rule, since the 'includes' below can cause trouble .PHONY: default all default: all all: CC CXX # if WVSTREAMS_SRC is set assume everything else is set. # For packages that use WvStreams use WVSTREAMS_SRC=. for distribution. ifneq ($(WVSTREAMS),) WVSTREAMS_SRC=$(WVSTREAMS) WVSTREAMS_LIB=$(WVSTREAMS) WVSTREAMS_INC=$(WVSTREAMS)/include WVSTREAMS_BIN=$(WVSTREAMS) endif export WVSTREAMS WVSTREAMS_SRC WVSTREAMS_LIB WVSTREAMS_INC WVSTREAMS_BIN SHELL=/bin/bash include $(WVSTREAMS_SRC)/config.defaults.mk -include $(WVSTREAMS_SRC)/config.mk -include $(WVSTREAMS_SRC)/config.overrides.mk -include $(WVSTREAMS_SRC)/local.mk ifeq (${OS},SOLARIS) _SOLARIS= _SOLARIS AR=gar endif ifeq (${OS},MACOS) _MACOS=_MACOS endif ifeq (${OS},WIN32) _WIN32=_WIN32 endif ifdef _WIN32 XPATH += $(WVSTREAMS)/win32 $(WVSTREAMS)/win32/cominclude AR=i586-mingw32msvc-ar LIBS += -lssl -lcrypto -lz -lole32 -lrpcrt4 -lwsock32 -lgdi32 -limagehlp \ -lstdc++ else CFLAGS += -fPIC CXXFLAGS += -fPIC endif include $(WVSTREAMS_SRC)/wvrules-$(COMPILER_STANDARD).mk ifeq (${WVTESTRUN},) WVTESTRUN=$(WVSTREAMS_BIN)/wvtestrun endif # macros that expand to the object files in the given directories objects=$(sort $(foreach type,c cc,$(call objects_$(type),$1))) objects_c=$(filter-out $(WV_EXCLUDES), \ $(patsubst %.c,%.o,$(wildcard $(addsuffix /*.c,$1)))) objects_cc=$(filter-out $(WV_EXCLUDES), \ $(patsubst %.cc,%.o,$(wildcard $(addsuffix /*.cc,$1)))) tests_cc=$(filter-out $(WV_EXCLUDES), \ $(patsubst %.cc,%,$(wildcard $(addsuffix /*.cc,$1)))) # default "test" rule does nothing... .PHONY: test runtests test: runtests: %/test: $(MAKE) -C $(dir $@) test INCFLAGS=$(addprefix -I,$(WVSTREAMS_INC) $(XPATH)) CPPFLAGS+=$(INCFLAGS) \ -D_BSD_SOURCE -D_GNU_SOURCE $(OSDEFINE) \ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \ -DUNSTABLE ifeq ($(VERBOSE),1) COMPILE_MSG := LINK_MSG := DEPEND_MSG := SYMLINK_MSG := else COMPILE_MSG = @echo compiling $@...; LINK_MSG = @echo linking $@...; #DEPEND_MSG = @echo " depending $@..."; DEPEND_MSG := @ SYMLINK_MSG := @ endif # any rule that depends on FORCE will always run .PHONY: FORCE FORCE: ifeq ($(LN_S),) LN_S := ln -s endif ifeq ($(LN),) LN := ln endif # Create symbolic links # usage: $(wvlns,source,dest) wvlns=$(SYMLINK_MSG)$(LN_S) -f $1 $2 # Create hard links # usage: $(wvln,source,dest) wvln=$(SYMLINK_MSG)$(LN) -f $1 $2 # usage: $(wvcc,outfile,infile,stem,extra_cflags,mode) # eg: $(wvcc,foo.o,foo.cc,foo,-fPIC,-c) define wvcc ./CC $(if $5,$5,-c) $3 $($1-CFLAGS) $($1-CPPFLAGS) $4 endef define wvcxx ./CXX $(if $5,$5,-c) $3 $($1-CXXFLAGS) $($1-CPPFLAGS) $4 endef %.so: SONAME=$@$(if $(SO_VERSION),.$(SO_VERSION)) wvsoname=$(if $($1-SONAME),$($1-SONAME),$(if $(SONAME),$(SONAME),$1)) ifdef _WIN32 define wvlink_so @echo "Skipping $@ on win32 (can't build shared libraries)" endef else ifdef _SOLARIS define wvlink_so $(LINK_MSG)$(WVLINK_CC) $(LDFLAGS) $($1-LDFLAGS) -shared -o $1 $(filter %.o %.a %.so,$2) $($1-LIBS) $(LIBS) $(XX_LIBS) endef else ifdef _MACOS define wvlink_so $(LINK_MSG)$(WVLINK_CC) $(LDFLAGS) $($1-LDFLAGS) -dynamiclib -o $1 $(filter %.o %.a %.so,$2) $($1-LIBS) $(LIBS) $(XX_LIBS) endef else define wvlink_so $(LINK_MSG)$(WVLINK_CC) $(LDFLAGS) $($1-LDFLAGS) -Wl,-z,defs -Wl,-soname,$(call wvsoname,$1) -shared -o $1 $(filter %.o %.a %.so,$2) $($1-LIBS) $(LIBS) $(XX_LIBS) $(if $(filter-out $(call wvsoname,$1),$1),$(call wvlns,$1,$(call wvsoname,$1))) endef endif ../%.so:; @echo "Shared library $@ does not exist!"; exit 1 ../%.a:; @echo "Library $@ does not exist!"; exit 1 ../%.o:; @echo "Object $@ does not exist!"; exit 1 /%.a:; @echo "Library $@ does not exist!"; exit 1 %.o: %.c; $(call wvcc ,$@,$<,$*) %.fpic.o: %.c; $(call wvcc ,$@,$<,$*,-fPIC) %.o: %.cc; $(call wvcxx,$@,$<,$*) %.fpic.o: %.cc; $(call wvcxx,$@,$<,$*,-fPIC) %.o: %.cpp; $(call wvcxx,$@,$<,$*) %.fpic.o:%.cpp; $(call wvcxx,$@,$<,$*,-fPIC) %.s: %.c; $(call wvcc ,$@,$<,$*,,-S) %.s: %.cc; $(call wvcxx,$@,$<,$*,,-S) %.s: %.cpp; $(call wvcxx,$@,$<,$*,,-S) %.E: %.c; $(call wvcc,$@,$<,$*,,-E) %.E: %.cc; $(call wvcxx,$@,$<,$*,,-E) %.E: %.cpp; $(call wvcxx,$@,$<,$*,,-E) %.moc: %.h; $(MOC) -o $@ $< %: %.o; $(call wvlink,$@,$^) %.t: %.t.o; $(call wvlink,$@,$(call reverse,$(filter %.o,$^)) $(filter-out %.o,$^) $(LIBWVTEST)) %.a %.libs:; $(call wvlink_ar,$@,$^) %.so:; $(call wvlink_so,$@,$^) # Force objects to be built before final binaries $(addsuffix .o,$(basename $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp))): %.gz: FORCE % @rm -f $@ gzip -f $* @ls -l $@ # # We automatically generate header dependencies for .c and .cc files. The # dependencies are stored in the file ".filename.d", and we include them # automatically here if they exist. # -include $(shell find . -name '.*.d') /dev/null # # A macro for compiling subdirectories listed in the SUBDIRS variable. # Tries to make the target ($@) in each subdir, unless the target is called # "subdirs" in which case it makes "all" in each subdir. # define subdirs_func +@OLDDIR="$$(pwd)"; set -e; \ for d in __fx__ $2; do \ if [ "$$d" = "__fx__" ]; then continue; fi; \ cd "$$d"; \ echo ; \ echo "--> Making $1 in $$(pwd)..."; \ $(MAKE) --no-print-directory $1 || exit 1; \ cd "$$OLDDIR"; \ done @echo @echo "--> Back in $$(pwd)..." endef subdirs = $(call subdirs_func,$(subst subdirs,all,$(if $1,$1,$@)),$(if $2,$2,$(SUBDIRS))) define shell_reverse revlist="" ; \ for word in $(1) ; do \ revlist="$${word} $${revlist}"; \ done ; \ echo "$${revlist}" endef reverse = $(shell $(call shell_reverse,$(1))) clean_subdirs = $(call subdirs,clean,$(call reverse,$(SUBDIRS)),keep) %: %/Makefile FORCE @cd "$@"; echo; echo "--> Making all in $$(pwd)..."; \ $(MAKE) --no-print-directory all subdirs: ${SUBDIRS} # # Auto-clean rule. Feel free to append to this in your own directory, by # defining your own "clean" and/or "distclean" rules. # .PHONY: clean _wvclean clean: _wvclean _wvclean: @echo '--> Cleaning $(shell pwd)...' @rm -f *~ *.tmp *.o *.a *.so *.so.* *.libs *.dll *.lib *.moc *.d .*.d .depend \ .\#* .tcl_paths pkgIndex.tcl gmon.out core build-stamp \ CC CXX \ wvtestmain @rm -f $(patsubst %.t.cc,%.t,$(wildcard *.t.cc) $(wildcard t/*.t.cc)) \ t/*.o t/*~ t/.*.d t/.\#* @rm -f valgrind.log.pid* @rm -f semantic.cache tags @rm -rf debian/tmp dist-hook: PKGDIR=$(WVPACKAGE_TARNAME)-$(WVPACKAGE_VERSION) dist: config.mk dist-hook @echo '--> Making dist in ../build/$(PKGDIR)...' @test -d ../build || mkdir ../build @rsync -a --delete --force '$(shell pwd)/' '../build/$(PKGDIR)' cd ../build/$(PKGDIR) && git clean -d -f -x cd ../build/$(PKGDIR) && git log > ChangeLog cd ../build/$(PKGDIR) && ./autogen.sh @find '../build/$(PKGDIR)' -name .git -type d -print0 | xargs -0 rm -rf -- @find '../build/$(PKGDIR)' -name .gitignore -type f -print0 | xargs -0 rm -f -- @rm -f '../build/$(PKGDIR).tar.gz' @cd ../build; tar -zcf '$(PKGDIR).tar.gz' '$(PKGDIR)' @echo '--> Created tarball in ../build/$(PKGDIR).tar.gz.' wvstreams-4.6.1/README.TESTS0000644000175000001440000000126511036722347014364 0ustar wlachusersNote that the unit tests (invoked through 'make test') will fail if WvStreams is linked against the default version of OpenSSL 0.9.8. To get around this, you need to use a version of OpenSSL built with the PURIFY define enabled (-DPURIFY). Instructions on doing this (working as of Tuesday January 16 2006 with OpenSSL 0.9.8d): - Build SSL seperately. - ./Configure -DPURIFY -shared linux-elf - make - Set your LD_LIBRARY_PATH environment variable so your version of OpenSSL is used (instead of the system one). - export LD_LIBRARY_PATH=$PATH_TO_OPENSSL:$LD_LIBRARY_PATH - Configure WvStreams to use the version of OpenSSL you built - ./configure --with-openssl=$PATH_TO_OPENSSL ... wvstreams-4.6.1/win32.mk0000644000175000001440000000611111077715733014077 0ustar wlachusers libwvstatic.a: $(call objects,win32) # object files that we replace completely for win32 OBJREPLACED=\ utils/wvtask.o \ # object files that we can't use in win32 for now, but which we should # definitely fix OBJFIXME=\ utils/wvsubprocqueue.o \ utils/wvsystem.o \ utils/wvregex.o \ utils/wvglob.o \ utils/wvglobdiriter.o \ utils/wvsubproc.o \ \ streams/wvatomicfile.o \ streams/wvlogrotator.o \ streams/wvpipe.o \ streams/wvwatcher.o \ \ ipstreams/wvunixsocket.o \ \ uniconf/unifilesystemgen.o \ # object files that we probably just shouldn't include in win32 libraries OBJSKIP=$(OBJREPLACED) $(OBJFIXME) \ utils/strcrypt.o \ utils/wvfork.o \ utils/wvmagiccircle.o \ utils/wvshmzone.o \ streams/wvprociter.o \ \ streams/wvlockdev.o \ streams/wvlockfile.o \ streams/wvmagicloopback.o \ streams/wvmodem.o \ streams/wvsyslog.o \ streams/wvsubprocqueuestream.o \ \ ipstreams/wvipraw.o \ ipstreams/wvunixdgsocket.o \ \ uniconf/unigenhack.o \ uniconf/daemon/uniconfd.o \ TOBJFIXME=\ utils/t/wvsubprocqueue.t.o \ utils/t/wvsystem.t.o \ utils/t/wvpushdir.t.o \ \ streams/t/wvatomicfile.t.o \ streams/t/wvstreamsdaemon.t.o \ streams/t/wvpipe.t.o \ \ uniconf/t/uniconfd.t.o \ uniconf/t/uniconfgen-sanitytest.o \ uniconf/t/unicachegen.t.o \ uniconf/t/uniinigen.t.o \ uniconf/t/unireplicategen.t.o \ uniconf/t/uniretrygen.t.o \ uniconf/t/uniclientgen.t.o \ uniconf/t/uniunwrapgen.t.o \ uniconf/t/unitransactiongen.t.o \ uniconf/t/unicallbackgen.t.o \ uniconf/t/unimountgen.t.o \ uniconf/t/unisubtreegen.t.o \ uniconf/t/unipermgen.t.o \ uniconf/t/unidefgen.t.o \ uniconf/t/unifastregetgen.t.o \ uniconf/t/unitempgen.t.o \ uniconf/t/unireadonlygen.t.o \ uniconf/t/uniautogen.t.o \ uniconf/t/unilistgen.t.o \ TOBJSKIP=$(TOBJFIXME) \ utils/t/strcrypt.t.o \ utils/t/wvondiskhash.t.o \ utils/t/wvregex.t.o \ utils/t/wvglob.t.o \ utils/t/wvglobdiriter.t.o \ streams/t/wvprociter.t.o \ \ streams/t/wvmagicloopback.t.o \ streams/t/wvlogrotator.t.o \ streams/t/wvsubprocqueuestream.t.o \ streams/t/wvlockfile.t.o \ \ ipstreams/t/wvunixdgsocket.t.o \ ipstreams/t/wvunixsocket.t.o \ \ linuxstreams/t/wvpty.t.o \ \ crypto/t/wvocsp.t.o \ \ uniconf/t/unitempgenvsdaemon.t.o \ PROGSKIP=\ ipstreams/tests/unixtest \ utils/tests/wvgrep \ utils/tests/wvegrep \ utils/tests/buffertest \ utils/tests/crashtest \ utils/tests/crashtest-nofd \ utils/tests/forktest \ utils/tests/magiccircletest \ utils/tests/proctest \ utils/tests/rateadjtest \ utils/tests/serializetest \ utils/tests/tasktest \ utils/tests/testtest \ streams/tests/logfiletest \ streams/tests/looptest \ streams/tests/modemtest \ streams/tests/pamtest \ streams/tests/pipetest \ streams/tests/syslogtest \ ipstreams/tests/iptest \ ipstreams/tests/ip2test \ ipstreams/tests/udglistentest \ ipstreams/tests/ulistentest \ ipstreams/tests/unixdgtest \ ipstreams/tests/xplctest \ ipstreams/tests/wsd \ crypto/tests/cryptotest \ linuxstreams/tests/aliastest \ linuxstreams/tests/ifctest \ linuxstreams/tests/routetest \ uniconf/tests/unimem \ WV_EXCLUDES += $(OBJSKIP) $(TOBJSKIP) $(PROGSKIP) wvstreams-4.6.1/config.mk.in0000644000175000001440000000253011202637334014776 0ustar wlachusersEXEEXT=@EXEEXT@ CC=@CC@ CFLAGS=@CFLAGS@ CPP=@CPP@ CPPFLAGS=@CPPFLAGS@ CXX=@CXX@ CXXCPP=@CXXCPP@ CXXFLAGS=@CXXFLAGS@ INSTALL=@INSTALL@ INSTALL_DATA=@INSTALL_DATA@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_SCRIPT=@INSTALL_SCRIPT@ LDFLAGS=@LDFLAGS@ LN_S=@LN_S@ LN=@LN@ MOC=@MOC@ VALGRIND=@VALGRIND@ WVPACKAGE_BUGREPORT=@PACKAGE_BUGREPORT@ WVPACKAGE_NAME=@PACKAGE_NAME@ WVPACKAGE_STRING=@PACKAGE_STRING@ WVPACKAGE_TARNAME=@PACKAGE_TARNAME@ WVPACKAGE_VERSION=@PACKAGE_VERSION@ COMPILER_STANDARD=@COMPILER_STANDARD@ SO_VERSION=@SO_VERSION@ USE_WVSTREAMS_ARGP=@USE_WVSTREAMS_ARGP@ target=@target@ OS=@OS@ ARCH_SUBDIRS=@ARCH_SUBDIRS@ LIBS=@LIBS@ LIBS_DBUS=@LIBS_DBUS@ LIBS_QT=@LIBS_QT@ LIBS_PAM=@LIBS_PAM@ LIBS_TCL=@LIBS_TCL@ prefix=@prefix@ datarootdir=@datarootdir@ datadir=@datadir@ includedir=@includedir@ infodir=@infodir@ localstatedir=@localstatedir@ mandir=@mandir@ sharedstatedir=@sharedstatedir@ sysconfdir=@sysconfdir@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ libexecdir=@libexecdir@ sbindir=@sbindir@ enable_debug=@enable_debug@ enable_optimization=@enable_optimization@ enable_resolver_fork=@enable_resolver_fork@ enable_warnings=@enable_warnings@ enable_testgui=@enable_testgui@ with_dbus=@with_dbus@ with_openssl=@with_openssl@ with_pam=@with_pam@ with_tcl=@with_tcl@ with_readline=@with_readline@ with_qt=@with_qt@ with_zlib=@with_zlib@ wvstreams-4.6.1/xplc/0000755000175000001440000000000011260431126013534 5ustar wlachuserswvstreams-4.6.1/xplc/moduleloader.cc0000644000175000001440000000665311077715530016543 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * Copyright (C) 2002-2004, Stéphane Lajoie * * 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 "moduleloader.h" #include "loader.h" UUID_MAP_BEGIN(ModuleLoader) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IModuleLoader) UUID_MAP_END UUID_MAP_BEGIN(Module) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IServiceHandler) UUID_MAP_ENTRY(IModule) UUID_MAP_END IModule* ModuleLoader::loadModule(const char* modulename) { return Module::loadModule(modulename); } Module* Module::loadModule(const char* modulename) { XPLC_ModuleInfo* moduleinfo = 0; void* dlh; const char* err; err = loaderOpen(modulename, &dlh); if(err) return NULL; void* symbol; err = loaderSymbol(dlh, "XPLC_Module", &symbol); moduleinfo = reinterpret_cast(symbol); if(err || !moduleinfo || moduleinfo->magic != XPLC_MODULE_MAGIC) { loaderClose(dlh); return NULL; } switch(moduleinfo->version_major) { #ifdef UNSTABLE case -1: /* nothing to do */ break; #endif default: loaderClose(dlh); return NULL; }; return new Module(dlh, moduleinfo); } Module::Module(void* aHandle, const XPLC_ModuleInfo* aModuleInfo): handle(aHandle), moduleinfo(aModuleInfo) { assert(moduleinfo); if(moduleinfo->categories) { IServiceManager* servmgr; IObject* obj; ICategoryManager* catmgr; const XPLC_CategoryEntry* entry; servmgr = XPLC_getServiceManager(); assert(servmgr); obj = servmgr->getObject(XPLC_categoryManager); assert(obj); servmgr->release(); catmgr = mutate(obj); assert(catmgr); entry = moduleinfo->categories; while(entry->category != UUID_null && entry->uuid != UUID_null) { catmgr->registerComponent(entry->category, entry->uuid, entry->string); ++entry; } catmgr->release(); } } IObject* Module::getObject(const UUID& cid) { const XPLC_ComponentEntry* entry = moduleinfo->components; IObject* obj = 0; if(!entry) return NULL; while(!obj && entry->uuid != UUID_null) { if(entry->uuid == cid) obj = entry->getObject(); ++entry; } return obj; } Module::~Module() { /* * FIXME: Adding the conditional here is for future expansion, where * this class could be used for a non-dynamically loaded module. But * for some reason, the size of this file increases in an odd way * when it is added. This should be investigated. */ if(handle) loaderClose(handle); } wvstreams-4.6.1/xplc/category.cc0000644000175000001440000000265311077372756015711 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Net Integration Technologies, Inc. * * 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 "category.h" #include "catiter.h" UUID_MAP_BEGIN(Category) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(ICategory) UUID_MAP_END Category::Category(ICategoryManager* aMgr, CategoryEntryNode* aEntries): mgr(aMgr), entries(aEntries) { /* * Prevent the category manager from dying (which would free the * list). */ mgr->addRef(); } ICategoryIterator* Category::getIterator() { return new CategoryIterator(this, entries); } Category::~Category() { mgr->release(); } wvstreams-4.6.1/xplc/catmgr.h0000644000175000001440000000264711077376047015213 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Net Integration Technologies, Inc. * Copyright (C) 2003, Pierre Phaneuf * * 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 __XPLC_CATMGR_H__ #define __XPLC_CATMGR_H__ #include #include "categorynode.h" class CategoryManager: public ICategoryManager { IMPLEMENT_IOBJECT(CategoryManager); private: CategoryNode* categories; public: CategoryManager(); virtual ~CategoryManager(); /* ICategoryManager */ virtual void registerComponent(const UUID&, const UUID&, const char*); virtual ICategory* getCategory(const UUID&); }; #endif /* __XPLC_CATMGR_H__ */ wvstreams-4.6.1/xplc/category.h0000644000175000001440000000252111077376047015542 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Net Integration Technologies, Inc. * * 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 __XPLC_CATEGORY_H__ #define __XPLC_CATEGORY_H__ #include #include "categorynode.h" class Category: public ICategory { IMPLEMENT_IOBJECT(Category); private: ICategoryManager* mgr; CategoryEntryNode* entries; public: Category(ICategoryManager*, CategoryEntryNode*); /* ICategory */ virtual ICategoryIterator* getIterator(); virtual ~Category(); }; #endif /* __XPLC_CATEGORY_H__ */ wvstreams-4.6.1/xplc/moduleloader.h0000644000175000001440000000316511077402715016376 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * * 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 __XPLC_MODULELOADER_H__ #define __XPLC_MODULELOADER_H__ #include #include #include class ModuleLoader: public IModuleLoader { IMPLEMENT_IOBJECT(ModuleLoader); public: virtual IModule* loadModule(const char* modulename); virtual ~ModuleLoader() {} }; class Module: public IModule { IMPLEMENT_IOBJECT(Module); private: void *handle; const XPLC_ModuleInfo* moduleinfo; public: Module(void* aHandle, const XPLC_ModuleInfo* aModuleInfo); static Module* loadModule(const char* modulename); virtual IObject* getObject(const UUID& cid); virtual ~Module(); }; #endif /* __XPLC_MODULELOADER_H__ */ wvstreams-4.6.1/xplc/objectnode.h0000644000175000001440000000254111077376047016043 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000, Pierre Phaneuf * * 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 __XPLC_OBJECTNODE_H__ #define __XPLC_OBJECTNODE_H__ #include class ObjectNode { public: ObjectNode* next; UUID uuid; IObject* obj; ObjectNode(const UUID& aUuid, IObject* aObj, ObjectNode* aNext): next(aNext), uuid(aUuid), obj(aObj) { obj->addRef(); } ~ObjectNode() { obj->release(); } }; #endif /* __XPLC_OBJECTNODE_H__ */ wvstreams-4.6.1/xplc/monikernode.h0000644000175000001440000000251611077376047016243 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_MONIKERNODE_H__ #define __XPLC_MONIKERNODE_H__ #include #include class MonikerNode { public: MonikerNode* next; char* name; UUID uuid; MonikerNode(const char* aName, const UUID& aUuid, MonikerNode* aNext): next(aNext), name(strdup(aName)), uuid(aUuid) { } ~MonikerNode() { if(name) free(name); } }; #endif /* __XPLC_MONIKERNODE_H__ */ wvstreams-4.6.1/xplc/config.h0000644000175000001440000000223611077376317015175 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * * 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 __XPLC_CONFIG_H__ #define __XPLC_CONFIG_H__ /* * Platforms that do not support Autoconf should skip including that * file. */ #if !defined(WIN32) #include "wvautoconf.h" #else #ifdef WIN32 #define ENABLE_LOADER #endif #endif #endif /* __XPLC_CONFIG_H__ */ wvstreams-4.6.1/xplc/loader.h0000644000175000001440000000236311077376047015177 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 __XPLC_LOADER_H__ #define __XPLC_LOADER_H__ const char* loaderOpen(const char* aFilename, void** aHandle); const char* loaderSymbol(void* aHandle, const char* aSymbol, void** aPointer); bool loaderClose(void*& aHandle); #endif /* __XPLC_LOADER_H__ */ wvstreams-4.6.1/xplc/servmgr.h0000644000175000001440000000313111077376047015410 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * Copyright (C) 2001, Stéphane Lajoie * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * * 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 __XPLC_SERVMGR_H__ #define __XPLC_SERVMGR_H__ #include #include "handlernode.h" class ServiceManager: public IServiceManager { IMPLEMENT_IOBJECT(ServiceManager); private: HandlerNode* handlers; public: ServiceManager(): handlers(0) { } virtual ~ServiceManager(); /* IServiceManager */ virtual void addHandler(IServiceHandler*); virtual void addFirstHandler(IServiceHandler*); virtual void addLastHandler(IServiceHandler*); virtual void removeHandler(IServiceHandler*); virtual IObject* getObject(const UUID&); }; #endif /* __XPLC_SERVMGR_H__ */ wvstreams-4.6.1/xplc/new.cc0000644000175000001440000000326211077372756014662 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 "new.h" UUID_MAP_BEGIN(NewMoniker) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IMoniker) UUID_MAP_END NewMoniker::~NewMoniker() { } IObject* NewMoniker::resolve(const char* aName) { IServiceManager* servmgr; IMoniker* monikers; IFactory* factory; IObject* obj = 0; servmgr = XPLC_getServiceManager(); if(servmgr) { monikers = mutate(servmgr->getObject(XPLC_monikers)); if(monikers) { factory = mutate(monikers->resolve(aName)); if(factory) { obj = factory->createObject(); factory->release(); } monikers->release(); } servmgr->release(); } return obj; } wvstreams-4.6.1/xplc/catiter.cc0000644000175000001440000000344211077372756015524 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2004, Net Integration Technologies, Inc. * * 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 "catiter.h" UUID_MAP_BEGIN(CategoryIterator) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(ICategoryIterator) UUID_MAP_END CategoryIterator::CategoryIterator(ICategory* aCategory, CategoryEntryNode* aEntries): category(aCategory), current(aEntries) { /* * Prevent the category from dying, which in turn prevents the * category manager from dying (which would free the list). */ category->addRef(); } const UUID& CategoryIterator::getUuid() { if(current) return current->entry; return UUID_null; } const char* CategoryIterator::getString() { if(current) return current->str; return 0; } void CategoryIterator::next() { if(current) current = current->next; } bool CategoryIterator::done() { return current == 0; } CategoryIterator::~CategoryIterator() { category->release(); } wvstreams-4.6.1/xplc/monikers.h0000644000175000001440000000267511077376047015566 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2003, Pierre Phaneuf * * 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 __XPLC_MONIKERS_H__ #define __XPLC_MONIKERS_H__ #include #include "monikernode.h" class MonikerService: public IMonikerService { IMPLEMENT_IOBJECT(MonikerService); private: MonikerNode* monikers; public: MonikerService(): monikers(0) { } virtual ~MonikerService(); /* IMoniker */ virtual IObject* resolve(const char*); /* IMonikerService */ virtual void registerObject(const char*, const UUID&); }; #endif /* __XPLC_MONIKERS_H__ */ wvstreams-4.6.1/xplc/handlernode.h0000644000175000001440000000265311077376047016216 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2002, Pierre Phaneuf * * 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 __XPLC_HANDLERNODE_H__ #define __XPLC_HANDLERNODE_H__ #include class HandlerNode { public: HandlerNode* next; IServiceHandler* handler; bool intercept; HandlerNode(IServiceHandler* aHandler, HandlerNode* aNext, bool aIntercept): next(aNext), handler(aHandler), intercept(aIntercept) { handler->addRef(); } ~HandlerNode() { handler->release(); } }; #endif /* __XPLC_HANDLERNODE_H__ */ wvstreams-4.6.1/xplc/monikers.cc0000644000175000001440000000524211077372756015720 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2002-2003, Pierre Phaneuf * * 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 "monikers.h" #define MONIKER_SEPARATOR_CHAR ':' UUID_MAP_BEGIN(MonikerService) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IMoniker) UUID_MAP_ENTRY(IMonikerService) UUID_MAP_END MonikerService::~MonikerService() { MonikerNode* node; MonikerNode* ptr; node = monikers; while(node) { ptr = node; node = node->next; delete ptr; } monikers = 0; } IObject* MonikerService::resolve(const char* aName) { MonikerNode* node; IServiceManager* servmgr; IObject* obj = 0; IMoniker* moniker; char* name = strdup(aName); char* rest = strchr(name, MONIKER_SEPARATOR_CHAR); node = monikers; if(rest) { *rest = 0; ++rest; } while(node) { if(strcmp(name, node->name) == 0) { servmgr = XPLC_getServiceManager(); if(!servmgr) break; obj = servmgr->getObject(node->uuid); servmgr->release(); if(rest) { moniker = mutate(obj); if(moniker) { obj = moniker->resolve(rest); moniker->release(); } else obj = 0; } break; } node = node->next; } free(name); return obj; } void MonikerService::registerObject(const char* aName, const UUID& aUuid) { MonikerNode* node; /* * FIXME: we should do something about registering a name that * contains the separator character. */ node = monikers; while(node) { if(strcmp(aName, node->name) == 0) break; node = node->next; } /* * FIXME: maybe add a "replace" bool parameter? Or would this * encourage moniker hijacking too much? */ if(node) return; node = new MonikerNode(aName, aUuid, monikers); monikers = node; } wvstreams-4.6.1/xplc/modulemgr.h0000644000175000001440000000325711077402665015723 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * * 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 __XPLC_MODULEMGR_H__ #define __XPLC_MODULEMGR_H__ #include #include class ModuleManagerFactory: public IModuleManagerFactory { IMPLEMENT_IOBJECT(ModuleManagerFactory); private: public: static ModuleManagerFactory* create() { return new ModuleManagerFactory; } virtual IServiceHandler* createModuleManager(const char* directory); virtual ~ModuleManagerFactory() {} }; struct ModuleNode; class ModuleManager: public IServiceHandler { IMPLEMENT_IOBJECT(ModuleManager); private: ModuleNode* modules; public: ModuleManager(ModuleNode* aModules); virtual IObject* getObject(const UUID& cid); virtual ~ModuleManager(); }; #endif /* __XPLC_MODULEMGR_H__ */ wvstreams-4.6.1/xplc/statichandler.h0000644000175000001440000000273611077376047016562 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * * 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 __XPLC_STATICHANDLER_H__ #define __XPLC_STATICHANDLER_H__ #include #include "objectnode.h" class StaticServiceHandler: public IStaticServiceHandler { IMPLEMENT_IOBJECT(StaticServiceHandler); private: ObjectNode* objects; public: StaticServiceHandler(): objects(0) { } virtual ~StaticServiceHandler(); /* IServiceHandler */ virtual IObject* getObject(const UUID&); /* IStaticServiceHandler */ virtual void addObject(const UUID&, IObject*); virtual void removeObject(const UUID&); }; #endif /* __XPLC_STATICHANDLER_H__ */ wvstreams-4.6.1/xplc/new.h0000644000175000001440000000233111077376047014515 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2003, Pierre Phaneuf * Copyright (C) 2004, Net Integration Technologies, Inc. * * 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 __XPLC_NEW_H__ #define __XPLC_NEW_H__ #include class NewMoniker: public IMoniker { IMPLEMENT_IOBJECT(NewMoniker); public: /* IMoniker */ virtual IObject* resolve(const char*); virtual ~NewMoniker(); }; #endif /* __XPLC_NEW_H__ */ wvstreams-4.6.1/xplc/servmgr.cc0000644000175000001440000001143711077372756015561 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2004, Pierre Phaneuf * Copyright (C) 2000, Stéphane Lajoie * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * * 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 "servmgr.h" #include "catmgr.h" #include "statichandler.h" #include "moduleloader.h" #include "monikers.h" #include "new.h" #include "modulemgr.h" UUID_MAP_BEGIN(ServiceManager) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IServiceManager) UUID_MAP_END static ServiceManager* singleton; IServiceManager* XPLC_getServiceManager() { if(singleton) singleton->addRef(); else { IStaticServiceHandler* handler; IStaticServiceHandler* handler2; IMonikerService* monikers; IObject* obj; singleton = new ServiceManager; if(!singleton) return 0; handler = new StaticServiceHandler; if(!handler) { singleton->release(); return 0; } /* * Populate the static service handler. */ handler2 = new StaticServiceHandler; if(handler2) { handler->addObject(XPLC_staticServiceHandler, handler2); singleton->addHandler(handler2); handler2->release(); } else { singleton->release(); return 0; } obj = new NewMoniker; if(obj) { handler->addObject(XPLC_newMoniker, obj); obj->release(); } obj = new CategoryManager; if(obj) { handler->addObject(XPLC_categoryManager, obj); obj->release(); } obj = new ModuleLoader; if(obj) { handler->addObject(XPLC_moduleLoader, obj); obj->release(); } obj = new ModuleManagerFactory; if(obj) { handler->addObject(XPLC_moduleManagerFactory, obj); obj->release(); } monikers = new MonikerService; if(monikers) { monikers->registerObject("new", XPLC_newMoniker); handler->addObject(XPLC_monikers, monikers); monikers->release(); } singleton->addHandler(handler); handler->release(); } return singleton; } ServiceManager::~ServiceManager() { HandlerNode* next; while(handlers) { next = handlers->next; delete handlers; handlers = next; } if(singleton == this) singleton = 0; } void ServiceManager::addHandler(IServiceHandler* aHandler) { HandlerNode* node; HandlerNode** ptr; ptr = &handlers; node = *ptr; while(node) { if(node->handler == aHandler) break; if(node->intercept) { ptr = &node->next; } node = node->next; } /* * The handler is already there. */ if(node) return; node = new HandlerNode(aHandler, *ptr, false); *ptr = node; } void ServiceManager::addFirstHandler(IServiceHandler* aHandler) { HandlerNode* node; node = handlers; while(node) { if(node->handler == aHandler) break; node = node->next; } /* * The handler is already there. */ if(node) return; node = new HandlerNode(aHandler, handlers, true); handlers = node; } void ServiceManager::addLastHandler(IServiceHandler* aHandler) { HandlerNode* node; HandlerNode** ptr; ptr = &handlers; node = *ptr; while(node) { if(node->handler == aHandler) break; ptr = &node->next; node = *ptr; } /* * The handler is already there. */ if(node) return; node = new HandlerNode(aHandler, *ptr, false); *ptr = node; } void ServiceManager::removeHandler(IServiceHandler* aHandler) { HandlerNode* node; HandlerNode** ptr; node = handlers; ptr = &handlers; while(node) { if(node->handler == aHandler) { *ptr = node->next; delete node; break; } ptr = &node->next; node = *ptr; } } IObject* ServiceManager::getObject(const UUID& aUuid) { IObject* obj; HandlerNode* handler; handler = handlers; while(handler) { obj = handler->handler->getObject(aUuid); /* * No need to addRef the object, the handler does it for us. */ if(obj) return obj; handler = handler->next; } return 0; } wvstreams-4.6.1/xplc/catmgr.cc0000644000175000001440000000426611077372756015353 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Net Integration Technologies, Inc. * Copyright (C) 2003, Pierre Phaneuf * * 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 "catmgr.h" #include "category.h" UUID_MAP_BEGIN(CategoryManager) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(ICategoryManager) UUID_MAP_END CategoryManager::CategoryManager(): categories(0) { } CategoryManager::~CategoryManager() { if(categories) delete categories; } void CategoryManager::registerComponent(const UUID& aCatid, const UUID& aUuid, const char* aString) { CategoryNode* cat; CategoryEntryNode* entry; for(cat = categories; cat; cat = cat->next) { if(cat->category == aCatid) break; } if(!cat) { cat = new CategoryNode(aCatid, categories); categories = cat; } assert(cat); for(entry = cat->entries; entry; entry = entry->next) { if(entry->entry == aUuid) return; } entry = new CategoryEntryNode(aUuid, aString, cat->entries); assert(entry); cat->entries = entry; } ICategory* CategoryManager::getCategory(const UUID& aUuid) { CategoryNode* cat; for(cat = categories; cat; cat = cat->next) { if(cat->category == aUuid) return new Category(this, cat->entries); } return new Category(this, NULL); } wvstreams-4.6.1/xplc/loader.cc0000644000175000001440000001203111077432051015312 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * Copyright (C) 2002-2004, Stéphane Lajoie * * 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 "config.h" #include "loader.h" #ifdef HAVE_DLFCN_H #include #endif #ifdef HAVE_MACH_O_DYLD_H #include #endif #if defined(WITH_DLOPEN) && defined(ENABLE_LOADER) const char* loaderOpen(const char* aFilename, void** aHandle) { const char* rv = 0; /* clear out dl error */ static_cast(dlerror()); *aHandle = dlopen(aFilename, RTLD_NOW); if(!*aHandle) rv = dlerror(); return rv; } const char* loaderSymbol(void* aHandle, const char* aSymbol, void** aPointer) { /* clear out dl error */ static_cast(dlerror()); *aPointer = dlsym(aHandle, aSymbol); return dlerror(); } bool loaderClose(void*& aHandle) { bool rv; rv = dlclose(aHandle) == 0; aHandle = 0; return rv; } #elif defined(WITH_DYLD) && defined(ENABLE_LOADER) const char* loaderOpen(const char* aFilename, void** aHandle) { NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; ofirc = NSCreateObjectFileImageFromFile(aFilename, &ofi); switch(ofirc) { case NSObjectFileImageSuccess: *aHandle = NSLinkModule(ofi, aFilename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(ofi); break; case NSObjectFileImageInappropriateFile: *aHandle = const_cast(reinterpret_cast(NSAddImage(aFilename, NSADDIMAGE_OPTION_RETURN_ON_ERROR))); break; default: return "could not open dynamic library"; break; } return 0; } const char* loaderSymbol(void* aHandle, const char* aSymbol, void** aPointer) { int len = strlen(aSymbol); char* sym = static_cast(malloc(len + 2)); NSSymbol* nssym = 0; snprintf(sym, len + 2, "_%s", aSymbol); /* Check for both possible magic numbers depending on x86/ppc byte order */ if ((((struct mach_header *)aHandle)->magic == MH_MAGIC) || (((struct mach_header *)aHandle)->magic == MH_CIGAM)) { if (NSIsSymbolNameDefinedInImage((struct mach_header *)aHandle, sym)) { nssym = (NSModule *)NSLookupSymbolInImage((struct mach_header *)aHandle, sym, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); } } else { nssym = (NSModule *)NSLookupSymbolInModule(aHandle, sym); } free(sym); if(!nssym) { *aPointer = 0; return "symbol not found"; } return 0; } bool loaderClose(void*& aHandle) { aHandle = 0; return false; } #elif defined(WIN32) #include const char* getErrorMessage() { static char error[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, error, sizeof(error), 0); return error; } const char* loaderOpen(const char* aFilename, void** aHandle) { const char* rv = 0; UINT oldErrorMode = SetErrorMode(0); SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS); *aHandle = LoadLibrary(aFilename); SetErrorMode(oldErrorMode); if(!*aHandle) rv = getErrorMessage(); return rv; } const char* loaderSymbol(void* aHandle, const char* aSymbol, void** aPointer) { const char* rv = 0; *aPointer = (void *)GetProcAddress(static_cast(aHandle), aSymbol); if(!aPointer) rv = getErrorMessage(); return rv; } bool loaderClose(void*& aHandle) { bool rv; rv = FreeLibrary(static_cast(aHandle)) != 0; aHandle = 0; return rv; } #else const char* loaderOpen(const char* aFilename, void** aHandle) { *aHandle = 0; return "dynamic loading not supported on this platform"; } const char* loaderSymbol(void* aHandle, const char* aSymbol, void** aPointer) { *aPointer = 0; return "dynamic loading not supported on this platform"; } bool loaderClose(void*& aHandle) { aHandle = 0; return false; } #endif wvstreams-4.6.1/xplc/catiter.h0000644000175000001440000000270011077376047015357 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2004, Net Integration Technologies, Inc. * * 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 __XPLC_CATITER_H__ #define __XPLC_CATEITER_H__ #include #include #include "categorynode.h" class CategoryIterator: public ICategoryIterator { IMPLEMENT_IOBJECT(CategoryIterator); private: ICategory* category; CategoryEntryNode* current; public: CategoryIterator(ICategory*, CategoryEntryNode*); virtual const UUID& getUuid(); virtual const char* getString(); virtual void next(); virtual bool done(); virtual ~CategoryIterator(); }; #endif /* __XPLC_CATEITER_H__ */ wvstreams-4.6.1/xplc/modulemgr.cc0000644000175000001440000001036211202637334016045 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2002-2004, Pierre Phaneuf * * 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 "modulemgr.h" #include #include "config.h" #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_LIMITS_H # include #endif #if !defined(WIN32) # if HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) # else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif # endif #else # include #endif #include UUID_MAP_BEGIN(ModuleManagerFactory) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IModuleManagerFactory) UUID_MAP_END UUID_MAP_BEGIN(ModuleManager) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IServiceHandler) UUID_MAP_END struct ModuleNode { ModuleNode* next; IModule* module; ModuleNode(IModule* aModule, ModuleNode* aNext): next(aNext), module(aModule) { assert(module); } ~ModuleNode() { if(module) module->release(); } }; #if defined(SOLARIS) || defined(MACOS) #define PATH_MAX 4096 #endif IServiceHandler* ModuleManagerFactory::createModuleManager(const char* directory) { #if !defined(WIN32) DIR* dir; struct dirent* ent; char fname[PATH_MAX]; IServiceManager* servmgr = XPLC_getServiceManager(); IModuleLoader* loader; ModuleNode* modules = 0; if(!servmgr) return 0; loader = mutate(servmgr->getObject(XPLC_moduleLoader)); servmgr->release(); if(!loader) return 0; dir = opendir(directory); if(!dir) { loader->release(); return 0; } rewinddir(dir); while((ent = readdir(dir))) { IModule* module; snprintf(fname, PATH_MAX, "%s/%s", directory, ent->d_name); module = loader->loadModule(fname); if(module) { ModuleNode* node = new ModuleNode(module, modules); if(node) modules = node; } } loader->release(); closedir(dir); return new ModuleManager(modules); #else intptr_t dir; _finddata_t ent; char fname[4096]; char pattern[4096]; IServiceManager* servmgr = XPLC_getServiceManager(); IModuleLoader* loader; ModuleNode* modules = 0; if(!servmgr) return 0; loader = mutate(servmgr->getObject(XPLC_moduleLoader)); servmgr->release(); if(!loader) return 0; snprintf(pattern, sizeof(pattern), "%s/*.*", directory); dir = _findfirst(pattern, &ent); if(!dir) { loader->release(); return 0; } do { IModule* module; _snprintf(fname, sizeof(fname), "%s/%s", directory, ent.name); module = loader->loadModule(fname); if(module) { ModuleNode* node = new ModuleNode(module, modules); if(node) modules = node; } } while(_findnext(dir, &ent) == 0); loader->release(); _findclose(dir); return new ModuleManager(modules); #endif } ModuleManager::ModuleManager(ModuleNode* aModules): modules(aModules) { } IObject* ModuleManager::getObject(const UUID& cid) { ModuleNode* node = modules; while(node) { IObject* obj = node->module->getObject(cid); if(obj) return obj; node = node->next; } return 0; } ModuleManager::~ModuleManager() { ModuleNode* node = modules; while(node) { ModuleNode* next = node->next; delete node; node = next; } } wvstreams-4.6.1/xplc/categorynode.h0000644000175000001440000000356211077376047016416 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000, Pierre Phaneuf * * 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 __XPLC_CATEGORYNODE_H__ #define __XPLC_CATEGORYNODE_H__ #include #include class CategoryEntryNode { public: CategoryEntryNode* next; UUID entry; char* str; CategoryEntryNode(const UUID& aUuid, const char* aStr, CategoryEntryNode* aNext): next(aNext), entry(aUuid), str(aStr ? strdup(aStr) : 0) { } ~CategoryEntryNode() { if(next) delete next; if(str) free(str); } }; class CategoryNode { public: CategoryNode* next; UUID category; CategoryEntryNode* entries; CategoryNode(const UUID& aUuid, CategoryNode* aNext): next(aNext), category(aUuid), entries(0) { } ~CategoryNode() { if(entries) delete entries; if(next) delete next; } }; #endif /* __XPLC_CATEGORYNODE_H__ */ wvstreams-4.6.1/xplc/statichandler.cc0000644000175000001440000000466611077372756016727 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2000-2003, Pierre Phaneuf * Copyright (C) 2002, Net Integration Technologies, Inc. * * 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 "statichandler.h" UUID_MAP_BEGIN(StaticServiceHandler) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IServiceHandler) UUID_MAP_ENTRY(IStaticServiceHandler) UUID_MAP_END StaticServiceHandler::~StaticServiceHandler() { ObjectNode* node; ObjectNode* ptr; node = objects; while(node) { ptr = node; node = node->next; delete ptr; } objects = 0; } IObject* StaticServiceHandler::getObject(const UUID& aUuid) { ObjectNode* node; node = objects; while(node) { if(node->uuid == aUuid) { node->obj->addRef(); return node->obj; } node = node->next; } /* * No match was found, we return empty-handed. */ return 0; } void StaticServiceHandler::addObject(const UUID& aUuid, IObject* aObj) { ObjectNode* node; /* No object given? */ if(!aObj) return; node = objects; while(node) { if(node->uuid == aUuid) break; node = node->next; } /* * FIXME: maybe add a "replace" bool parameter? Or would this * encourage UUID hijacking too much? */ if(node) return; node = new ObjectNode(aUuid, aObj, objects); objects = node; } void StaticServiceHandler::removeObject(const UUID& aUuid) { ObjectNode* node; ObjectNode** ptr; node = objects; ptr = &objects; while(node) { if(node->uuid == aUuid) { *ptr = node->next; delete node; break; } ptr = &node->next; node = *ptr; } } wvstreams-4.6.1/README0000644000175000001440000000031511036722347013456 0ustar wlachusers This is wvstreams, a nominally platform-independent networking and utilities library for C++. Some documentation is in the Docs/ directory. If that looks empty, try doing "make doxygen" to generate it. wvstreams-4.6.1/git-grafts-setup0000755000175000001440000000125011254003232015713 0ustar wlachusers#!/bin/sh # # If you have a git checkout of the wvstreams project, some of the ancient # history will be a bit confused because of the way we originally imported # it from svn. You can fix it by running this script, which reattaches some # of the history. # # FIXME: someone who's feeling energetic might have a good time by attaching # all the old svn merges to each other, but that sounds a bit painful. # touch .git/info/grafts ( cat .git/info/grafts - <<-EOF 17085388a723081806b2325557ec9a43841d02fc 6e9e756361a92fe17ff39e5f3d686ac20c436e95 EOF ) | sort | uniq >.git/info/grafts.new && mv .git/info/grafts.new .git/info/grafts && echo ".git/info/grafts file configured." wvstreams-4.6.1/autom4te.cache/0000755000175000001440000000000011260431127015373 5ustar wlachuserswvstreams-4.6.1/autom4te.cache/requests0000644000175000001440000000530511260431130017166 0ustar wlachusers# This file was generated. # It contains the lists of macros which have been traced. # It can be safely removed. @request = ( bless( [ '0', 1, [ '/usr/share/autoconf' ], [ '/usr/share/autoconf/autoconf/autoconf.m4f', 'configure.ac' ], { 'AM_PROG_F77_C_O' => 1, '_LT_AC_TAGCONFIG' => 1, 'm4_pattern_forbid' => 1, 'AC_INIT' => 1, 'AC_CANONICAL_TARGET' => 1, '_AM_COND_IF' => 1, 'AC_CONFIG_LIBOBJ_DIR' => 1, 'AC_SUBST' => 1, 'AC_CANONICAL_HOST' => 1, 'AC_FC_SRCEXT' => 1, 'AC_PROG_LIBTOOL' => 1, 'AM_INIT_AUTOMAKE' => 1, 'AC_CONFIG_SUBDIRS' => 1, 'AM_AUTOMAKE_VERSION' => 1, 'LT_CONFIG_LTDL_DIR' => 1, 'AC_CONFIG_LINKS' => 1, 'AC_REQUIRE_AUX_FILE' => 1, 'LT_SUPPORTED_TAG' => 1, 'm4_sinclude' => 1, 'AM_MAINTAINER_MODE' => 1, 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1, '_m4_warn' => 1, 'AM_PROG_CXX_C_O' => 1, '_AM_COND_ENDIF' => 1, 'AM_ENABLE_MULTILIB' => 1, 'AC_CONFIG_FILES' => 1, 'include' => 1, 'LT_INIT' => 1, 'AM_GNU_GETTEXT' => 1, 'AC_LIBSOURCE' => 1, 'AM_PROG_FC_C_O' => 1, 'AC_CANONICAL_BUILD' => 1, 'AC_FC_FREEFORM' => 1, 'AH_OUTPUT' => 1, 'AC_CONFIG_AUX_DIR' => 1, '_AM_SUBST_NOTMAKE' => 1, 'm4_pattern_allow' => 1, 'AM_PROG_CC_C_O' => 1, 'sinclude' => 1, 'AM_CONDITIONAL' => 1, 'AC_CANONICAL_SYSTEM' => 1, 'AC_CONFIG_HEADERS' => 1, 'AC_DEFINE_TRACE_LITERAL' => 1, 'm4_include' => 1, '_AM_COND_ELSE' => 1, 'AC_SUBST_TRACE' => 1 } ], 'Autom4te::Request' ) ); wvstreams-4.6.1/autom4te.cache/traces.00000644000175000001440000012377311260431127016752 0ustar wlachusersm4trace:configure.ac:2: -1- AC_INIT([WvStreams], [4.6.1], [wvstreams-devel@googlegroups.com], [wvstreams]) m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?A[CHUM]_]) m4trace:configure.ac:2: -1- m4_pattern_forbid([_AC_]) m4trace:configure.ac:2: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) m4trace:configure.ac:2: -1- m4_pattern_allow([^AS_FLAGS$]) m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?m4_]) m4trace:configure.ac:2: -1- m4_pattern_forbid([^dnl$]) m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?AS_]) m4trace:configure.ac:2: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([SHELL]) m4trace:configure.ac:2: -1- m4_pattern_allow([^SHELL$]) m4trace:configure.ac:2: -1- AC_SUBST([PATH_SEPARATOR]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PATH_SEPARATOR]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PATH_SEPARATOR$]) m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_NAME]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_TARNAME]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_VERSION]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_STRING]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:2: -1- AC_SUBST([exec_prefix], [NONE]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([exec_prefix]) m4trace:configure.ac:2: -1- m4_pattern_allow([^exec_prefix$]) m4trace:configure.ac:2: -1- AC_SUBST([prefix], [NONE]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([prefix]) m4trace:configure.ac:2: -1- m4_pattern_allow([^prefix$]) m4trace:configure.ac:2: -1- AC_SUBST([program_transform_name], [s,x,x,]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([program_transform_name]) m4trace:configure.ac:2: -1- m4_pattern_allow([^program_transform_name$]) m4trace:configure.ac:2: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([bindir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^bindir$]) m4trace:configure.ac:2: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sbindir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^sbindir$]) m4trace:configure.ac:2: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libexecdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^libexecdir$]) m4trace:configure.ac:2: -1- AC_SUBST([datarootdir], ['${prefix}/share']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datarootdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^datarootdir$]) m4trace:configure.ac:2: -1- AC_SUBST([datadir], ['${datarootdir}']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datadir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^datadir$]) m4trace:configure.ac:2: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sysconfdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^sysconfdir$]) m4trace:configure.ac:2: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sharedstatedir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^sharedstatedir$]) m4trace:configure.ac:2: -1- AC_SUBST([localstatedir], ['${prefix}/var']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localstatedir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^localstatedir$]) m4trace:configure.ac:2: -1- AC_SUBST([includedir], ['${prefix}/include']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([includedir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^includedir$]) m4trace:configure.ac:2: -1- AC_SUBST([oldincludedir], ['/usr/include']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([oldincludedir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^oldincludedir$]) m4trace:configure.ac:2: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], ['${datarootdir}/doc/${PACKAGE_TARNAME}'], ['${datarootdir}/doc/${PACKAGE}'])]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([docdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^docdir$]) m4trace:configure.ac:2: -1- AC_SUBST([infodir], ['${datarootdir}/info']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([infodir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^infodir$]) m4trace:configure.ac:2: -1- AC_SUBST([htmldir], ['${docdir}']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([htmldir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^htmldir$]) m4trace:configure.ac:2: -1- AC_SUBST([dvidir], ['${docdir}']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([dvidir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^dvidir$]) m4trace:configure.ac:2: -1- AC_SUBST([pdfdir], ['${docdir}']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([pdfdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^pdfdir$]) m4trace:configure.ac:2: -1- AC_SUBST([psdir], ['${docdir}']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([psdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^psdir$]) m4trace:configure.ac:2: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libdir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^libdir$]) m4trace:configure.ac:2: -1- AC_SUBST([localedir], ['${datarootdir}/locale']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localedir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^localedir$]) m4trace:configure.ac:2: -1- AC_SUBST([mandir], ['${datarootdir}/man']) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([mandir]) m4trace:configure.ac:2: -1- m4_pattern_allow([^mandir$]) m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ #undef PACKAGE_NAME]) m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME]) m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ #undef PACKAGE_VERSION]) m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ #undef PACKAGE_STRING]) m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT]) m4trace:configure.ac:2: -1- AC_SUBST([DEFS]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([DEFS]) m4trace:configure.ac:2: -1- m4_pattern_allow([^DEFS$]) m4trace:configure.ac:2: -1- AC_SUBST([ECHO_C]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_C]) m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_C$]) m4trace:configure.ac:2: -1- AC_SUBST([ECHO_N]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_N]) m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_N$]) m4trace:configure.ac:2: -1- AC_SUBST([ECHO_T]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_T]) m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_T$]) m4trace:configure.ac:2: -1- AC_SUBST([LIBS]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:2: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:2: -1- AC_SUBST([build_alias]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([build_alias]) m4trace:configure.ac:2: -1- m4_pattern_allow([^build_alias$]) m4trace:configure.ac:2: -1- AC_SUBST([host_alias]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([host_alias]) m4trace:configure.ac:2: -1- m4_pattern_allow([^host_alias$]) m4trace:configure.ac:2: -1- AC_SUBST([target_alias]) m4trace:configure.ac:2: -1- AC_SUBST_TRACE([target_alias]) m4trace:configure.ac:2: -1- m4_pattern_allow([^target_alias$]) m4trace:configure.ac:33: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:33: the top level]) m4trace:configure.ac:37: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:37: the top level]) m4trace:configure.ac:41: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:41: the top level]) m4trace:configure.ac:45: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:45: the top level]) m4trace:configure.ac:49: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:49: the top level]) m4trace:configure.ac:53: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:53: the top level]) m4trace:configure.ac:57: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:57: the top level]) m4trace:configure.ac:60: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:60: the top level]) m4trace:configure.ac:61: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:61: the top level]) m4trace:configure.ac:62: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:62: the top level]) m4trace:configure.ac:63: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:63: the top level]) m4trace:configure.ac:64: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:64: the top level]) m4trace:configure.ac:65: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:65: the top level]) m4trace:configure.ac:66: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:209: AC_HELP_STRING is expanded from... configure.ac:66: the top level]) m4trace:configure.ac:68: -1- AC_SUBST([MOC]) m4trace:configure.ac:68: -1- AC_SUBST_TRACE([MOC]) m4trace:configure.ac:68: -1- m4_pattern_allow([^MOC$]) m4trace:configure.ac:69: -1- AC_SUBST([WEAVER_BUILD_INFO]) m4trace:configure.ac:69: -1- AC_SUBST_TRACE([WEAVER_BUILD_INFO]) m4trace:configure.ac:69: -1- m4_pattern_allow([^WEAVER_BUILD_INFO$]) m4trace:configure.ac:75: -1- AC_SUBST([CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:75: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:75: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:75: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:75: -1- AC_SUBST([LIBS]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:75: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:75: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:75: -1- AC_SUBST([CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:75: -1- AC_SUBST([CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:75: -1- AC_SUBST([CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:75: -1- AC_SUBST([CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:75: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:75: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:75: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([EXEEXT]) m4trace:configure.ac:75: -1- m4_pattern_allow([^EXEEXT$]) m4trace:configure.ac:75: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) m4trace:configure.ac:75: -1- AC_SUBST_TRACE([OBJEXT]) m4trace:configure.ac:75: -1- m4_pattern_allow([^OBJEXT$]) m4trace:configure.ac:76: -1- AC_SUBST([CXX]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([CXX]) m4trace:configure.ac:76: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:76: -1- AC_SUBST([CXXFLAGS]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([CXXFLAGS]) m4trace:configure.ac:76: -1- m4_pattern_allow([^CXXFLAGS$]) m4trace:configure.ac:76: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:76: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:76: -1- AC_SUBST([LIBS]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:76: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:76: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:76: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:76: -1- AC_SUBST([CXX]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([CXX]) m4trace:configure.ac:76: -1- m4_pattern_allow([^CXX$]) m4trace:configure.ac:76: -1- AC_SUBST([ac_ct_CXX]) m4trace:configure.ac:76: -1- AC_SUBST_TRACE([ac_ct_CXX]) m4trace:configure.ac:76: -1- m4_pattern_allow([^ac_ct_CXX$]) m4trace:configure.ac:77: -1- AC_SUBST([CPP]) m4trace:configure.ac:77: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:77: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:77: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:77: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:77: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:77: -1- AC_SUBST([CPP]) m4trace:configure.ac:77: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:77: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:78: -1- AC_SUBST([CXXCPP]) m4trace:configure.ac:78: -1- AC_SUBST_TRACE([CXXCPP]) m4trace:configure.ac:78: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:78: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:78: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:78: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:78: -1- AC_SUBST([CXXCPP]) m4trace:configure.ac:78: -1- AC_SUBST_TRACE([CXXCPP]) m4trace:configure.ac:78: -1- m4_pattern_allow([^CXXCPP$]) m4trace:configure.ac:79: -1- AC_REQUIRE_AUX_FILE([install-sh]) m4trace:configure.ac:79: -1- AC_SUBST([INSTALL_PROGRAM]) m4trace:configure.ac:79: -1- AC_SUBST_TRACE([INSTALL_PROGRAM]) m4trace:configure.ac:79: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) m4trace:configure.ac:79: -1- AC_SUBST([INSTALL_SCRIPT]) m4trace:configure.ac:79: -1- AC_SUBST_TRACE([INSTALL_SCRIPT]) m4trace:configure.ac:79: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) m4trace:configure.ac:79: -1- AC_SUBST([INSTALL_DATA]) m4trace:configure.ac:79: -1- AC_SUBST_TRACE([INSTALL_DATA]) m4trace:configure.ac:79: -1- m4_pattern_allow([^INSTALL_DATA$]) m4trace:configure.ac:80: -1- AC_SUBST([LN_S], [$as_ln_s]) m4trace:configure.ac:80: -1- AC_SUBST_TRACE([LN_S]) m4trace:configure.ac:80: -1- m4_pattern_allow([^LN_S$]) m4trace:configure.ac:81: -1- AC_SUBST([SET_MAKE]) m4trace:configure.ac:81: -1- AC_SUBST_TRACE([SET_MAKE]) m4trace:configure.ac:81: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:82: -1- AC_SUBST([RANLIB]) m4trace:configure.ac:82: -1- AC_SUBST_TRACE([RANLIB]) m4trace:configure.ac:82: -1- m4_pattern_allow([^RANLIB$]) m4trace:configure.ac:85: -1- AC_CANONICAL_TARGET m4trace:configure.ac:85: -1- AC_CANONICAL_HOST m4trace:configure.ac:85: -1- AC_CANONICAL_BUILD m4trace:configure.ac:85: -1- AC_REQUIRE_AUX_FILE([config.sub]) m4trace:configure.ac:85: -1- AC_REQUIRE_AUX_FILE([config.guess]) m4trace:configure.ac:85: -1- AC_SUBST([build], [$ac_cv_build]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([build]) m4trace:configure.ac:85: -1- m4_pattern_allow([^build$]) m4trace:configure.ac:85: -1- AC_SUBST([build_cpu], [$[1]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([build_cpu]) m4trace:configure.ac:85: -1- m4_pattern_allow([^build_cpu$]) m4trace:configure.ac:85: -1- AC_SUBST([build_vendor], [$[2]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([build_vendor]) m4trace:configure.ac:85: -1- m4_pattern_allow([^build_vendor$]) m4trace:configure.ac:85: -1- AC_SUBST([build_os]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([build_os]) m4trace:configure.ac:85: -1- m4_pattern_allow([^build_os$]) m4trace:configure.ac:85: -1- AC_SUBST([host], [$ac_cv_host]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([host]) m4trace:configure.ac:85: -1- m4_pattern_allow([^host$]) m4trace:configure.ac:85: -1- AC_SUBST([host_cpu], [$[1]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([host_cpu]) m4trace:configure.ac:85: -1- m4_pattern_allow([^host_cpu$]) m4trace:configure.ac:85: -1- AC_SUBST([host_vendor], [$[2]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([host_vendor]) m4trace:configure.ac:85: -1- m4_pattern_allow([^host_vendor$]) m4trace:configure.ac:85: -1- AC_SUBST([host_os]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([host_os]) m4trace:configure.ac:85: -1- m4_pattern_allow([^host_os$]) m4trace:configure.ac:85: -1- AC_SUBST([target], [$ac_cv_target]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([target]) m4trace:configure.ac:85: -1- m4_pattern_allow([^target$]) m4trace:configure.ac:85: -1- AC_SUBST([target_cpu], [$[1]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([target_cpu]) m4trace:configure.ac:85: -1- m4_pattern_allow([^target_cpu$]) m4trace:configure.ac:85: -1- AC_SUBST([target_vendor], [$[2]]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([target_vendor]) m4trace:configure.ac:85: -1- m4_pattern_allow([^target_vendor$]) m4trace:configure.ac:85: -1- AC_SUBST([target_os]) m4trace:configure.ac:85: -1- AC_SUBST_TRACE([target_os]) m4trace:configure.ac:85: -1- m4_pattern_allow([^target_os$]) m4trace:configure.ac:110: -1- AC_SUBST([target]) m4trace:configure.ac:110: -1- AC_SUBST_TRACE([target]) m4trace:configure.ac:110: -1- m4_pattern_allow([^target$]) m4trace:configure.ac:111: -1- AC_SUBST([ARCH_SUBDIRS]) m4trace:configure.ac:111: -1- AC_SUBST_TRACE([ARCH_SUBDIRS]) m4trace:configure.ac:111: -1- m4_pattern_allow([^ARCH_SUBDIRS$]) m4trace:configure.ac:112: -1- AC_SUBST([OS]) m4trace:configure.ac:112: -1- AC_SUBST_TRACE([OS]) m4trace:configure.ac:112: -1- m4_pattern_allow([^OS$]) m4trace:configure.ac:115: -1- AH_OUTPUT([WORDS_BIGENDIAN], [/* 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]) m4trace:configure.ac:115: -1- AC_SUBST([GREP]) m4trace:configure.ac:115: -1- AC_SUBST_TRACE([GREP]) m4trace:configure.ac:115: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:115: -1- AC_SUBST([EGREP]) m4trace:configure.ac:115: -1- AC_SUBST_TRACE([EGREP]) m4trace:configure.ac:115: -1- m4_pattern_allow([^EGREP$]) m4trace:configure.ac:115: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) m4trace:configure.ac:115: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:115: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRING_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H]) m4trace:configure.ac:115: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H]) m4trace:configure.ac:115: -1- AC_DEFINE_TRACE_LITERAL([WORDS_BIGENDIAN]) m4trace:configure.ac:115: -1- m4_pattern_allow([^WORDS_BIGENDIAN$]) m4trace:configure.ac:115: -1- AC_DEFINE_TRACE_LITERAL([AC_APPLE_UNIVERSAL_BUILD]) m4trace:configure.ac:115: -1- m4_pattern_allow([^AC_APPLE_UNIVERSAL_BUILD$]) m4trace:configure.ac:115: -1- AH_OUTPUT([AC_APPLE_UNIVERSAL_BUILD], [/* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD]) m4trace:configure.ac:121: -1- AC_DEFINE_TRACE_LITERAL([ATTR_DEPRECATED]) m4trace:configure.ac:121: -1- m4_pattern_allow([^ATTR_DEPRECATED$]) m4trace:configure.ac:121: -1- AH_OUTPUT([ATTR_DEPRECATED], [/* Compiler warning on deprecated functions */ #undef ATTR_DEPRECATED]) m4trace:configure.ac:121: -1- AC_DEFINE_TRACE_LITERAL([ATTR_DEPRECATED]) m4trace:configure.ac:121: -1- m4_pattern_allow([^ATTR_DEPRECATED$]) m4trace:configure.ac:121: -1- AH_OUTPUT([ATTR_DEPRECATED], [/* Compiler warning on deprecated functions */ #undef ATTR_DEPRECATED]) m4trace:configure.ac:144: -1- AH_OUTPUT([HAVE_ARGP_H], [/* Define to 1 if you have the header file. */ #undef HAVE_ARGP_H]) m4trace:configure.ac:160: -1- AH_OUTPUT([HAVE_DIRENT_H], [/* Define to 1 if you have the header file, and it defines `DIR\'. */ #undef HAVE_DIRENT_H]) m4trace:configure.ac:160: -1- AH_OUTPUT([HAVE_SYS_NDIR_H], [/* Define to 1 if you have the header file, and it defines `DIR\'. */ #undef HAVE_SYS_NDIR_H]) m4trace:configure.ac:160: -1- AH_OUTPUT([HAVE_SYS_DIR_H], [/* Define to 1 if you have the header file, and it defines `DIR\'. */ #undef HAVE_SYS_DIR_H]) m4trace:configure.ac:160: -1- AH_OUTPUT([HAVE_NDIR_H], [/* Define to 1 if you have the header file, and it defines `DIR\'. */ #undef HAVE_NDIR_H]) m4trace:configure.ac:162: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ALLOCA_H]) m4trace:configure.ac:162: -1- m4_pattern_allow([^HAVE_ALLOCA_H$]) m4trace:configure.ac:162: -1- AH_OUTPUT([HAVE_ALLOCA_H], [/* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H]) m4trace:configure.ac:162: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ALLOCA]) m4trace:configure.ac:162: -1- m4_pattern_allow([^HAVE_ALLOCA$]) m4trace:configure.ac:162: -1- AH_OUTPUT([HAVE_ALLOCA], [/* Define to 1 if you have `alloca\', as a function or macro. */ #undef HAVE_ALLOCA]) m4trace:configure.ac:162: -1- AC_LIBSOURCE([alloca.c]) m4trace:configure.ac:162: -1- AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext]) m4trace:configure.ac:162: -1- AC_SUBST_TRACE([ALLOCA]) m4trace:configure.ac:162: -1- m4_pattern_allow([^ALLOCA$]) m4trace:configure.ac:162: -1- AC_DEFINE_TRACE_LITERAL([C_ALLOCA]) m4trace:configure.ac:162: -1- m4_pattern_allow([^C_ALLOCA$]) m4trace:configure.ac:162: -1- AH_OUTPUT([C_ALLOCA], [/* Define to 1 if using `alloca.c\'. */ #undef C_ALLOCA]) m4trace:configure.ac:162: -1- AC_DEFINE_TRACE_LITERAL([CRAY_STACKSEG_END]) m4trace:configure.ac:162: -1- m4_pattern_allow([^CRAY_STACKSEG_END$]) m4trace:configure.ac:162: -1- AH_OUTPUT([CRAY_STACKSEG_END], [/* 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]) m4trace:configure.ac:162: -1- AH_OUTPUT([STACK_DIRECTION], [/* 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]) m4trace:configure.ac:162: -1- AC_DEFINE_TRACE_LITERAL([STACK_DIRECTION]) m4trace:configure.ac:162: -1- m4_pattern_allow([^STACK_DIRECTION$]) m4trace:configure.ac:164: -1- AH_OUTPUT([HAVE_EXECINFO_H], [/* Define to 1 if you have the header file. */ #undef HAVE_EXECINFO_H]) m4trace:configure.ac:167: -1- AH_OUTPUT([HAVE_ARGZ_H], [/* Define to 1 if you have the header file. */ #undef HAVE_ARGZ_H]) m4trace:configure.ac:167: -1- AH_OUTPUT([HAVE_ERRNO_H], [/* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H]) m4trace:configure.ac:168: -1- AC_DEFINE_TRACE_LITERAL([error_t]) m4trace:configure.ac:168: -1- m4_pattern_allow([^error_t$]) m4trace:configure.ac:168: -1- AH_OUTPUT([error_t], [/* Define to a type to use for `error_t\' if it is not otherwise available. */ #undef error_t]) m4trace:configure.ac:168: -1- AC_DEFINE_TRACE_LITERAL([__error_t_defined]) m4trace:configure.ac:168: -1- m4_pattern_allow([^__error_t_defined$]) m4trace:configure.ac:168: -1- AH_OUTPUT([__error_t_defined], [/* Define so that glibc/gnulib argp.h does not typedef error_t. */ #undef __error_t_defined]) m4trace:configure.ac:181: -1- AH_OUTPUT([HAVE_SYS_SOCKET_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H]) m4trace:configure.ac:182: -1- AH_OUTPUT([HAVE_NET_IF_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H]) m4trace:configure.ac:196: -1- AH_OUTPUT([HAVE_NET_ETHERNET_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NET_ETHERNET_H]) m4trace:configure.ac:210: -1- AH_OUTPUT([HAVE_NETINET_IF_ETHER_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H]) m4trace:configure.ac:229: -3- AC_DEFINE_TRACE_LITERAL([ETHER_ADDR_LEN]) m4trace:configure.ac:229: -3- m4_pattern_allow([^ETHER_ADDR_LEN$]) m4trace:configure.ac:229: -3- AH_OUTPUT([ETHER_ADDR_LEN], [/* Size of ethernet address */ #undef ETHER_ADDR_LEN]) m4trace:configure.ac:231: -3- AC_DEFINE_TRACE_LITERAL([ETHER_ADDR_LEN]) m4trace:configure.ac:231: -3- m4_pattern_allow([^ETHER_ADDR_LEN$]) m4trace:configure.ac:284: -1- AH_OUTPUT([HAVE_NETDB_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H]) m4trace:configure.ac:285: -1- AH_OUTPUT([HAVE_NETINET_IN_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H]) m4trace:configure.ac:286: -1- AH_OUTPUT([HAVE_NETINET_IN_SYSTM_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_SYSTM_H]) m4trace:configure.ac:287: -1- AH_OUTPUT([HAVE_NETINET_IP_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IP_H]) m4trace:configure.ac:307: -1- AH_OUTPUT([HAVE_NETINET_TCP_H], [/* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H]) m4trace:configure.ac:310: -1- AH_OUTPUT([HAVE_LINUX_SERIAL_H], [/* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SERIAL_H]) m4trace:configure.ac:311: -1- AH_OUTPUT([HAVE_CFMAKERAW], [/* Define to 1 if you have the `cfmakeraw\' function. */ #undef HAVE_CFMAKERAW]) m4trace:configure.ac:325: -1- AC_SUBST([LN]) m4trace:configure.ac:325: -1- AC_SUBST_TRACE([LN]) m4trace:configure.ac:325: -1- m4_pattern_allow([^LN$]) m4trace:configure.ac:333: -1- AH_OUTPUT([HAVE_LIBC_STACK_END], [/* Whether libc supports __libc_stack_end */ #undef HAVE_LIBC_STACK_END]) m4trace:configure.ac:337: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2527: AC_TRY_LINK is expanded from... configure.ac:337: the top level]) m4trace:configure.ac:341: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBC_STACK_END]) m4trace:configure.ac:341: -1- m4_pattern_allow([^HAVE_LIBC_STACK_END$]) m4trace:configure.ac:347: -1- AC_SUBST([PKGCONFIG]) m4trace:configure.ac:347: -1- AC_SUBST_TRACE([PKGCONFIG]) m4trace:configure.ac:347: -1- m4_pattern_allow([^PKGCONFIG$]) m4trace:configure.ac:353: -1- AC_DEFINE_TRACE_LITERAL([VER_STRING_EXTRA]) m4trace:configure.ac:353: -1- m4_pattern_allow([^VER_STRING_EXTRA$]) m4trace:configure.ac:353: -1- AH_OUTPUT([VER_STRING_EXTRA], [/* Extra version string. */ #undef VER_STRING_EXTRA]) m4trace:configure.ac:358: -1- AC_DEFINE_TRACE_LITERAL([WVRESOLVER_SKIP_FORK]) m4trace:configure.ac:358: -1- m4_pattern_allow([^WVRESOLVER_SKIP_FORK$]) m4trace:configure.ac:358: -1- AH_OUTPUT([WVRESOLVER_SKIP_FORK], [/* Define to disable WvResolver forking for debugging with gdb. */ #undef WVRESOLVER_SKIP_FORK]) m4trace:configure.ac:364: -1- AC_DEFINE_TRACE_LITERAL([ENABLE_DELETE_DETECTOR]) m4trace:configure.ac:364: -1- m4_pattern_allow([^ENABLE_DELETE_DETECTOR$]) m4trace:configure.ac:364: -1- AH_OUTPUT([ENABLE_DELETE_DETECTOR], [/* Define to enable the XPLC delete detector. */ #undef ENABLE_DELETE_DETECTOR]) m4trace:configure.ac:394: -1- AH_OUTPUT([HAVE_DBUS_DBUS_H], [/* Define to 1 if you have the header file. */ #undef HAVE_DBUS_DBUS_H]) m4trace:configure.ac:396: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2527: AC_TRY_LINK is expanded from... configure.ac:396: the top level]) m4trace:configure.ac:403: -1- AC_DEFINE_TRACE_LITERAL([WITH_DBUS]) m4trace:configure.ac:403: -1- m4_pattern_allow([^WITH_DBUS$]) m4trace:configure.ac:403: -1- AH_OUTPUT([WITH_DBUS], [/* Define to enable DBUS support. */ #undef WITH_DBUS]) m4trace:configure.ac:409: -1- AH_OUTPUT([HAVE_LIBSOCKET], [/* Define to 1 if you have the `socket\' library (-lsocket). */ #undef HAVE_LIBSOCKET]) m4trace:configure.ac:409: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSOCKET]) m4trace:configure.ac:409: -1- m4_pattern_allow([^HAVE_LIBSOCKET$]) m4trace:configure.ac:417: -1- AH_OUTPUT([HAVE_OPENSSL_SSL_H], [/* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H]) m4trace:configure.ac:420: -1- AH_OUTPUT([HAVE_LIBCRYPTO], [/* Define to 1 if you have the `crypto\' library (-lcrypto). */ #undef HAVE_LIBCRYPTO]) m4trace:configure.ac:420: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBCRYPTO]) m4trace:configure.ac:420: -1- m4_pattern_allow([^HAVE_LIBCRYPTO$]) m4trace:configure.ac:421: -1- AH_OUTPUT([HAVE_LIBSSL], [/* Define to 1 if you have the `ssl\' library (-lssl). */ #undef HAVE_LIBSSL]) m4trace:configure.ac:421: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSSL]) m4trace:configure.ac:421: -1- m4_pattern_allow([^HAVE_LIBSSL$]) m4trace:configure.ac:422: -1- AH_OUTPUT([HAVE_LIBSSL], [/* Define to 1 if you have the `ssl\' library (-lssl). */ #undef HAVE_LIBSSL]) m4trace:configure.ac:422: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSSL]) m4trace:configure.ac:422: -1- m4_pattern_allow([^HAVE_LIBSSL$]) m4trace:configure.ac:424: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OPENSSL_POLICY_MAPPING]) m4trace:configure.ac:424: -1- m4_pattern_allow([^HAVE_OPENSSL_POLICY_MAPPING$]) m4trace:configure.ac:424: -1- AH_OUTPUT([HAVE_OPENSSL_POLICY_MAPPING], [/* Whether libssl has the POLICY_MAPPING features (0.9.8 and up) */ #undef HAVE_OPENSSL_POLICY_MAPPING]) m4trace:configure.ac:435: -1- AH_OUTPUT([HAVE_READLINE_READLINE_H], [/* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H]) m4trace:configure.ac:436: -1- AH_OUTPUT([HAVE_LIBREADLINE], [/* Define to 1 if you have the `readline\' library (-lreadline). */ #undef HAVE_LIBREADLINE]) m4trace:configure.ac:436: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBREADLINE]) m4trace:configure.ac:436: -1- m4_pattern_allow([^HAVE_LIBREADLINE$]) m4trace:configure.ac:441: -1- AH_OUTPUT([HAVE_SECURITY_PAM_APPL_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_H]) m4trace:configure.ac:443: -1- AH_OUTPUT([HAVE_LIBPAM], [/* Define to 1 if you have the `pam\' library (-lpam). */ #undef HAVE_LIBPAM]) m4trace:configure.ac:443: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBPAM]) m4trace:configure.ac:443: -1- m4_pattern_allow([^HAVE_LIBPAM$]) m4trace:configure.ac:445: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BROKEN_PAM]) m4trace:configure.ac:445: -1- m4_pattern_allow([^HAVE_BROKEN_PAM$]) m4trace:configure.ac:445: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BROKEN_PAM]) m4trace:configure.ac:445: -1- m4_pattern_allow([^HAVE_BROKEN_PAM$]) m4trace:configure.ac:445: -1- AH_OUTPUT([HAVE_BROKEN_PAM], [/* Solaris has a broken PAM implementation */ #undef HAVE_BROKEN_PAM]) m4trace:configure.ac:481: -1- AH_OUTPUT([HAVE_TCL_H], [/* Define to 1 if you have the header file. */ #undef HAVE_TCL_H]) m4trace:configure.ac:483: -1- AH_OUTPUT([HAVE_LIBTCL8_3], [/* Define to 1 if you have the `tcl8.3\' library (-ltcl8.3). */ #undef HAVE_LIBTCL8_3]) m4trace:configure.ac:483: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBTCL8_3]) m4trace:configure.ac:483: -1- m4_pattern_allow([^HAVE_LIBTCL8_3$]) m4trace:configure.ac:494: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2527: AC_TRY_LINK is expanded from... ../../lib/m4sugar/m4sh.m4:505: AS_IF is expanded from... ../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from... ../../lib/autoconf/general.m4:1994: AC_CACHE_CHECK is expanded from... configure.ac:494: the top level]) m4trace:configure.ac:521: -1- AC_SUBST([MOC]) m4trace:configure.ac:521: -1- AC_SUBST_TRACE([MOC]) m4trace:configure.ac:521: -1- m4_pattern_allow([^MOC$]) m4trace:configure.ac:526: -1- AC_SUBST([VALGRIND]) m4trace:configure.ac:526: -1- AC_SUBST_TRACE([VALGRIND]) m4trace:configure.ac:526: -1- m4_pattern_allow([^VALGRIND$]) m4trace:configure.ac:527: -1- AH_OUTPUT([HAVE_VALGRIND_MEMCHECK_H], [/* Define to 1 if you have the header file. */ #undef HAVE_VALGRIND_MEMCHECK_H]) m4trace:configure.ac:532: -1- AH_OUTPUT([HAVE_ZLIB_H], [/* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H]) m4trace:configure.ac:533: -1- AH_OUTPUT([HAVE_LIBZ], [/* Define to 1 if you have the `z\' library (-lz). */ #undef HAVE_LIBZ]) m4trace:configure.ac:533: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBZ]) m4trace:configure.ac:533: -1- m4_pattern_allow([^HAVE_LIBZ$]) m4trace:configure.ac:537: -1- AH_OUTPUT([HAVE_TR1_FUNCTIONAL], [/* Define to 1 if you have the header file. */ #undef HAVE_TR1_FUNCTIONAL]) m4trace:configure.ac:538: -1- AH_OUTPUT([HAVE_BOOST_FUNCTION_HPP], [/* Define to 1 if you have the header file. */ #undef HAVE_BOOST_FUNCTION_HPP]) m4trace:configure.ac:542: -1- AH_OUTPUT([HAVE_BOOST_THROW_EXCEPTION_HPP], [/* Define to 1 if you have the header file. */ #undef HAVE_BOOST_THROW_EXCEPTION_HPP]) m4trace:configure.ac:596: -1- AC_SUBST([SO_VERSION]) m4trace:configure.ac:596: -1- AC_SUBST_TRACE([SO_VERSION]) m4trace:configure.ac:596: -1- m4_pattern_allow([^SO_VERSION$]) m4trace:configure.ac:598: -1- AC_SUBST([USE_WVSTREAMS_ARGP]) m4trace:configure.ac:598: -1- AC_SUBST_TRACE([USE_WVSTREAMS_ARGP]) m4trace:configure.ac:598: -1- m4_pattern_allow([^USE_WVSTREAMS_ARGP$]) m4trace:configure.ac:600: -1- AC_SUBST([enable_debug]) m4trace:configure.ac:600: -1- AC_SUBST_TRACE([enable_debug]) m4trace:configure.ac:600: -1- m4_pattern_allow([^enable_debug$]) m4trace:configure.ac:601: -1- AC_SUBST([enable_optimization]) m4trace:configure.ac:601: -1- AC_SUBST_TRACE([enable_optimization]) m4trace:configure.ac:601: -1- m4_pattern_allow([^enable_optimization$]) m4trace:configure.ac:602: -1- AC_SUBST([enable_resolver_fork]) m4trace:configure.ac:602: -1- AC_SUBST_TRACE([enable_resolver_fork]) m4trace:configure.ac:602: -1- m4_pattern_allow([^enable_resolver_fork$]) m4trace:configure.ac:603: -1- AC_SUBST([enable_delete_detector]) m4trace:configure.ac:603: -1- AC_SUBST_TRACE([enable_delete_detector]) m4trace:configure.ac:603: -1- m4_pattern_allow([^enable_delete_detector$]) m4trace:configure.ac:604: -1- AC_SUBST([enable_warnings]) m4trace:configure.ac:604: -1- AC_SUBST_TRACE([enable_warnings]) m4trace:configure.ac:604: -1- m4_pattern_allow([^enable_warnings$]) m4trace:configure.ac:605: -1- AC_SUBST([enable_testgui]) m4trace:configure.ac:605: -1- AC_SUBST_TRACE([enable_testgui]) m4trace:configure.ac:605: -1- m4_pattern_allow([^enable_testgui$]) m4trace:configure.ac:607: -1- AC_SUBST([with_dbus]) m4trace:configure.ac:607: -1- AC_SUBST_TRACE([with_dbus]) m4trace:configure.ac:607: -1- m4_pattern_allow([^with_dbus$]) m4trace:configure.ac:608: -1- AC_SUBST([with_openssl]) m4trace:configure.ac:608: -1- AC_SUBST_TRACE([with_openssl]) m4trace:configure.ac:608: -1- m4_pattern_allow([^with_openssl$]) m4trace:configure.ac:609: -1- AC_SUBST([with_openssl_policy_mapping]) m4trace:configure.ac:609: -1- AC_SUBST_TRACE([with_openssl_policy_mapping]) m4trace:configure.ac:609: -1- m4_pattern_allow([^with_openssl_policy_mapping$]) m4trace:configure.ac:610: -1- AC_SUBST([with_pam]) m4trace:configure.ac:610: -1- AC_SUBST_TRACE([with_pam]) m4trace:configure.ac:610: -1- m4_pattern_allow([^with_pam$]) m4trace:configure.ac:611: -1- AC_SUBST([with_readline]) m4trace:configure.ac:611: -1- AC_SUBST_TRACE([with_readline]) m4trace:configure.ac:611: -1- m4_pattern_allow([^with_readline$]) m4trace:configure.ac:612: -1- AC_SUBST([with_qt]) m4trace:configure.ac:612: -1- AC_SUBST_TRACE([with_qt]) m4trace:configure.ac:612: -1- m4_pattern_allow([^with_qt$]) m4trace:configure.ac:613: -1- AC_SUBST([with_tcl]) m4trace:configure.ac:613: -1- AC_SUBST_TRACE([with_tcl]) m4trace:configure.ac:613: -1- m4_pattern_allow([^with_tcl$]) m4trace:configure.ac:614: -1- AC_SUBST([with_zlib]) m4trace:configure.ac:614: -1- AC_SUBST_TRACE([with_zlib]) m4trace:configure.ac:614: -1- m4_pattern_allow([^with_zlib$]) m4trace:configure.ac:616: -1- AC_SUBST([LIBS_DBUS]) m4trace:configure.ac:616: -1- AC_SUBST_TRACE([LIBS_DBUS]) m4trace:configure.ac:616: -1- m4_pattern_allow([^LIBS_DBUS$]) m4trace:configure.ac:617: -1- AC_SUBST([LIBS_QT]) m4trace:configure.ac:617: -1- AC_SUBST_TRACE([LIBS_QT]) m4trace:configure.ac:617: -1- m4_pattern_allow([^LIBS_QT$]) m4trace:configure.ac:618: -1- AC_SUBST([LIBS_PAM]) m4trace:configure.ac:618: -1- AC_SUBST_TRACE([LIBS_PAM]) m4trace:configure.ac:618: -1- m4_pattern_allow([^LIBS_PAM$]) m4trace:configure.ac:619: -1- AC_SUBST([LIBS_TCL]) m4trace:configure.ac:619: -1- AC_SUBST_TRACE([LIBS_TCL]) m4trace:configure.ac:619: -1- m4_pattern_allow([^LIBS_TCL$]) m4trace:configure.ac:621: -1- AC_SUBST([ac_libs]) m4trace:configure.ac:621: -1- AC_SUBST_TRACE([ac_libs]) m4trace:configure.ac:621: -1- m4_pattern_allow([^ac_libs$]) m4trace:configure.ac:622: -1- AC_SUBST([COMPILER_STANDARD]) m4trace:configure.ac:622: -1- AC_SUBST_TRACE([COMPILER_STANDARD]) m4trace:configure.ac:622: -1- m4_pattern_allow([^COMPILER_STANDARD$]) m4trace:configure.ac:624: -1- AC_DEFINE_TRACE_LITERAL([VERBOSE_PACKAGE_VERSION]) m4trace:configure.ac:624: -1- m4_pattern_allow([^VERBOSE_PACKAGE_VERSION$]) m4trace:configure.ac:624: -1- AH_OUTPUT([VERBOSE_PACKAGE_VERSION], [/* Verbose package version */ #undef VERBOSE_PACKAGE_VERSION]) m4trace:configure.ac:626: -1- AC_CONFIG_FILES([config.mk]) m4trace:configure.ac:627: -1- AC_CONFIG_FILES([pkgconfig/libuniconf.pc pkgconfig/libuniconf-uninstalled.pc pkgconfig/libwvbase.pc pkgconfig/libwvbase-uninstalled.pc pkgconfig/libwvdbus.pc pkgconfig/libwvdbus-uninstalled.pc pkgconfig/libwvqt.pc pkgconfig/libwvqt-uninstalled.pc pkgconfig/libwvstreams.pc pkgconfig/libwvstreams-uninstalled.pc pkgconfig/libwvutils.pc pkgconfig/libwvutils-uninstalled.pc pkgconfig/libwvtest.pc pkgconfig/libwvtest-uninstalled.pc]) m4trace:configure.ac:642: -1- AC_CONFIG_HEADERS([include/wvautoconf.h]) m4trace:configure.ac:644: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([LIB@&t@OBJS]) m4trace:configure.ac:644: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:644: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([LTLIBOBJS]) m4trace:configure.ac:644: -1- m4_pattern_allow([^LTLIBOBJS$]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([top_builddir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([top_build_prefix]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([srcdir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([abs_srcdir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([top_srcdir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([abs_top_srcdir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([builddir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([abs_builddir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([abs_top_builddir]) m4trace:configure.ac:644: -1- AC_SUBST_TRACE([INSTALL]) wvstreams-4.6.1/autom4te.cache/output.00000644000175000001440000124440511260431127017026 0ustar wlachusers@%:@! /bin/sh @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.63 for WvStreams 4.6.1. @%:@ @%:@ Report bugs to . @%:@ @%:@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @%:@ 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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=. LIB@&t@OBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='WvStreams' PACKAGE_TARNAME='wvstreams' PACKAGE_VERSION='4.6.1' PACKAGE_STRING='WvStreams 4.6.1' PACKAGE_BUGREPORT='wvstreams-devel@googlegroups.com' ac_unique_file="streams/wvstream.cc" # 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 LIB@&t@OBJS COMPILER_STANDARD ac_libs LIBS_TCL LIBS_PAM LIBS_QT LIBS_DBUS with_zlib with_tcl with_qt with_readline with_pam with_openssl_policy_mapping with_openssl with_dbus enable_testgui enable_warnings enable_delete_detector enable_resolver_fork enable_optimization enable_debug USE_WVSTREAMS_ARGP SO_VERSION VALGRIND PKGCONFIG LN ALLOCA EGREP GREP OS ARCH_SUBDIRS target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build RANLIB SET_MAKE LN_S INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CXXCPP CPP ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC WEAVER_BUILD_INFO MOC 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_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug enable_fatal_warnings enable_optimization enable_resolver_fork enable_delete_detector enable_warnings enable_testgui with_dbus with_openssl with_pam with_tcl with_qt with_zlib with_valgrind ' ac_precious_vars='build_alias host_alias target_alias MOC WEAVER_BUILD_INFO CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP' # 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_TARNAME}' 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 WvStreams 4.6.1 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/wvstreams@:>@ --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of WvStreams 4.6.1:";; esac 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] --disable-debug strip debug information --enable-fatal-warnings turn warnings into errors --disable-optimization optimization options --disable-resolver-fork WvResolver background name resolution (debugging) --enable-delete-detector Delete detector (reference counting) --disable-warnings extra warnings --disable-testgui GUI for unit tests Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-dbus DBUS --with-openssl OpenSSL >= 0.9.7 (required) --with-pam PAM --with-tcl Tcl --with-qt Qt --with-zlib zlib (required) --with-valgrind Valgrind Some influential environment variables: MOC Qt meta object compiler WEAVER_BUILD_INFO Extra version info 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 CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP 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 . _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 WvStreams configure 4.6.1 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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 WvStreams $as_me 4.6.1, which was generated by GNU Autoconf 2.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # 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:$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= ;; #( *) $as_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'; { (exit 1); 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 # 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 # 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:$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:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 SO_VERSION=4.6 # append to a variable without introducing superfluous white space QT_SEARCH_PATH=" $prefix /usr $libdir/qt-3.1 $libdir/qt3 $libdir/qt $datadir/qt3 $datadir/qt /usr /usr/lib/qt3 /usr/lib/qt-3.1 /usr/share/qt3 /usr/lib/qt /usr/share/qt " @%:@ Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; fi @%:@ Check whether --enable-fatal-warnings was given. if test "${enable_fatal_warnings+set}" = set; then enableval=$enable_fatal_warnings; fi @%:@ Check whether --enable-optimization was given. if test "${enable_optimization+set}" = set; then enableval=$enable_optimization; fi @%:@ Check whether --enable-resolver-fork was given. if test "${enable_resolver_fork+set}" = set; then enableval=$enable_resolver_fork; fi @%:@ Check whether --enable-delete-detector was given. if test "${enable_delete_detector+set}" = set; then enableval=$enable_delete_detector; fi @%:@ Check whether --enable-warnings was given. if test "${enable_warnings+set}" = set; then enableval=$enable_warnings; fi @%:@ Check whether --enable-testgui was given. if test "${enable_testgui+set}" = set; then enableval=$enable_testgui; fi @%:@ Check whether --with-dbus was given. if test "${with_dbus+set}" = set; then withval=$with_dbus; fi @%:@ Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then withval=$with_openssl; fi @%:@ Check whether --with-pam was given. if test "${with_pam+set}" = set; then withval=$with_pam; fi @%:@ Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then withval=$with_tcl; fi @%:@ Check whether --with-qt was given. if test "${with_qt+set}" = set; then withval=$with_qt; fi @%:@ Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then withval=$with_zlib; fi @%:@ Check whether --with-valgrind was given. if test "${with_valgrind+set}" = set; then withval=$with_valgrind; fi # avoid autoconf's default values, but keep those the user might have given CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } 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:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # 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_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi 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 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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 ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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 ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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:$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:$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' { $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" 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:$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:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 # Detect target build environment # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 $as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 $as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 $as_echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 $as_echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:$LINENO: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if test "${ac_cv_target+set}" = set; then $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 $as_echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- case "$target" in *-linux*) ARCH_SUBDIRS="linuxstreams" OS="LINUX" ;; *-sunos*|*-solaris*) ARCH_SUBDIRS="" ac_libs="-lstdc++ -lgcc_s -ldl -lm -lc" OS="SOLARIS" ;; *-win*|*-mingw32*) ARCH_SUBDIRS="win32" OS="WIN32" ;; *-apple*) ARCH_SUBDIRS="" OS="MACOS" ;; *) ARCH_SUBDIRS="" OS="OTHER" ;; esac # Detect endianness { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF @%:@define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # Check for potential -arch flags. It is not universal unless # there are some -arch flags. Note that *ppc* also matches # ppc64. This check is also rather less than ideal. case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in #( *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to _BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no 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 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) cat >>confdefs.h <<\_ACEOF @%:@define WORDS_BIGENDIAN 1 _ACEOF ;; #( no) ;; #( universal) cat >>confdefs.h <<\_ACEOF @%:@define AC_APPLE_UNIVERSAL_BUILD 1 _ACEOF ;; #( *) { { $as_echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 $as_echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac # Look for __attribute__ ((deprecated)) CPPFLAGS_save="$CPPFLAGS" if test -z "$CPPFLAGS"; then CPPFLAGS="-Werror" else CPPFLAGS="$CPPFLAGS -Werror" fi { $as_echo "$as_me:$LINENO: checking for __attribute__ ((deprecated))" >&5 $as_echo_n "checking for __attribute__ ((deprecated))... " >&6; } cat >conftest.$ac_ext <<_ACEOF #include "confdefs.h" void f() __attribute__ ((deprecated)); void f() { } int main() { return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF @%:@define ATTR_DEPRECATED __attribute__ ((deprecated)) _ACEOF else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF @%:@define ATTR_DEPRECATED /**/ _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CPPFLAGS="$CPPFLAGS_save" # argp USE_WVSTREAMS_ARGP=0 for ac_header in argp.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking for argp_parse" >&5 $as_echo_n "checking for argp_parse... " >&6; } if test "${ac_cv_func_argp_parse+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define argp_parse to an innocuous variant, in case declares argp_parse. For example, HP-UX 11i declares gettimeofday. */ #define argp_parse innocuous_argp_parse /* System header to define __stub macros and hopefully few prototypes, which can conflict with char argp_parse (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef argp_parse /* 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 argp_parse (); /* 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_argp_parse || defined __stub___argp_parse choke me #endif int main () { return argp_parse (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_argp_parse=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_argp_parse=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_argp_parse" >&5 $as_echo "$ac_cv_func_argp_parse" >&6; } if test "$ac_cv_func_argp_parse" != yes \ -o "$ac_cv_header_argp_h" != yes ; then ( echo echo 'configuring argp...' cd argp ./configure --host=$host_cpu-$host_os || exit $? echo 'argp configured.' echo ) || exit $? USE_WVSTREAMS_ARGP=1 fi # Function checks ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:$LINENO: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if test "${ac_cv_search_opendir+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_search_opendir=$ac_res else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:$LINENO: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if test "${ac_cv_search_opendir+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_search_opendir=$ac_res else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_working_alloca_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF @%:@define HAVE_ALLOCA_H 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_alloca_works=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF @%:@define HAVE_ALLOCA 1 _ACEOF 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 cat >>confdefs.h <<\_ACEOF @%:@define C_ALLOCA 1 _ACEOF { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 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 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$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 for ac_header in execinfo.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Check for error_t for ac_header in argz.h errno.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking for error_t" >&5 $as_echo_n "checking for error_t... " >&6; } if test "${ac_cv_type_error_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_error_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_ARGZ_H # include #else # if HAVE_ERRNO_H # include # endif #endif int main () { if (sizeof (error_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_ARGZ_H # include #else # if HAVE_ERRNO_H # include # endif #endif int main () { if (sizeof ((error_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_error_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_error_t" >&5 $as_echo "$ac_cv_type_error_t" >&6; } if test "x$ac_cv_type_error_t" = x""yes; then : else cat >>confdefs.h <<\_ACEOF @%:@define error_t int _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define __error_t_defined 1 _ACEOF fi # Check for size of ethernet addresses for ac_header in sys/socket.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 net/if.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 net/ethernet.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/if_ether.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_IF_H # include #endif @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking whether ETHER_ADDR_LEN is declared" >&5 $as_echo_n "checking whether ETHER_ADDR_LEN is declared... " >&6; } if test "${ac_cv_have_decl_ETHER_ADDR_LEN+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { #ifndef ETHER_ADDR_LEN (void) ETHER_ADDR_LEN; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_ETHER_ADDR_LEN=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_ETHER_ADDR_LEN=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_ETHER_ADDR_LEN" >&5 $as_echo "$ac_cv_have_decl_ETHER_ADDR_LEN" >&6; } if test "x$ac_cv_have_decl_ETHER_ADDR_LEN" = x""yes; then : else { $as_echo "$as_me:$LINENO: checking for ether_addr_t" >&5 $as_echo_n "checking for ether_addr_t... " >&6; } if test "${ac_cv_type_ether_addr_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_ether_addr_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { if (sizeof (ether_addr_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { if (sizeof ((ether_addr_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_ether_addr_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_ether_addr_t" >&5 $as_echo "$ac_cv_type_ether_addr_t" >&6; } if test "x$ac_cv_type_ether_addr_t" = x""yes; then cat >>confdefs.h <<\_ACEOF @%:@define ETHER_ADDR_LEN sizeof(ether_addr_t) _ACEOF else cat >>confdefs.h <<\_ACEOF @%:@define ETHER_ADDR_LEN 6 _ACEOF fi fi # Check for basic Internet support for ac_header in netdb.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/in.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/in_systm.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/ip.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IN_SYSTM_H # include #endif @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Check for advanced Linux-style modem support for ac_header in linux/serial.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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_func in cfmakeraw do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 # Detect hard-linking based on LN_S's behaviour { $as_echo "$as_me:$LINENO: checking whether ln works..." >&5 $as_echo_n "checking whether ln works...... " >&6; } case "$LN_S" in ln*) LN='ln' { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } ;; *) LN="$LN_S" { $as_echo "$as_me:$LINENO: result: no, using $LN" >&5 $as_echo "no, using $LN" >&6; } ;; esac # Setting the default language to C++ means that CXX and CXXCPP will be # used for compile tests. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # __libc_stack_end isn't available to shared libraries with some libc versions { $as_echo "$as_me:$LINENO: checking whether __libc_stack_end is public" >&5 $as_echo_n "checking whether __libc_stack_end is public... " >&6; } LDFLAGS_save="$LDFLAGS" if test -z "$LDFLAGS"; then LDFLAGS="-Wl,-z,defs -shared" else LDFLAGS="$LDFLAGS -Wl,-z,defs -shared" fi HAVE_LIBC_STACK_END=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern const void *__libc_stack_end; int main () { volatile const void *x = __libc_stack_end; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then HAVE_LIBC_STACK_END=yes; else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test "$HAVE_LIBC_STACK_END" = "yes"; then cat >>confdefs.h <<\_ACEOF @%:@define HAVE_LIBC_STACK_END 1 _ACEOF fi { $as_echo "$as_me:$LINENO: result: $HAVE_LIBC_STACK_END" >&5 $as_echo "$HAVE_LIBC_STACK_END" >&6; } LDFLAGS="$LDFLAGS_save" # Detect pkg-config # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKGCONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. ;; *) 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_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKGCONFIG" && ac_cv_path_PKGCONFIG="no" ;; esac fi PKGCONFIG=$ac_cv_path_PKGCONFIG if test -n "$PKGCONFIG"; then { $as_echo "$as_me:$LINENO: result: $PKGCONFIG" >&5 $as_echo "$PKGCONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKGCONFIG" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: pkg-config is not installed" >&5 $as_echo "$as_me: WARNING: pkg-config is not installed" >&2;} fi if test "$enable_debug" != "no"; then cat >>confdefs.h <<_ACEOF @%:@define VER_STRING_EXTRA " (`whoami`@`hostname`$VER_STRING_EXTRA)" _ACEOF fi # resolver-fork if test "$enable_resolver_fork" = "no"; then cat >>confdefs.h <<\_ACEOF @%:@define WVRESOLVER_SKIP_FORK /**/ _ACEOF fi # xplc delete detector if test "$enable_delete_detector" = "yes"; then cat >>confdefs.h <<\_ACEOF @%:@define ENABLE_DELETE_DETECTOR /**/ _ACEOF fi # dbus if test "$with_dbus" != "no"; then if test "$with_dbus" = "" -o "$with_dbus" = "yes"; then { $as_echo "$as_me:$LINENO: checking Checking that D-Bus version greater than 1.2.14 installed." >&5 $as_echo_n "checking Checking that D-Bus version greater than 1.2.14 installed.... " >&6; } if pkg-config --atleast-version 1.2.14 dbus-1; then if test -z "$CPPFLAGS"; then CPPFLAGS="`pkg-config --cflags dbus-1`" else CPPFLAGS="$CPPFLAGS `pkg-config --cflags dbus-1`" fi if test -z "$LDFLAGS"; then LDFLAGS="`pkg-config --libs-only-L dbus-1`" else LDFLAGS="$LDFLAGS `pkg-config --libs-only-L dbus-1`" fi LIBS_DBUS=`pkg-config --libs-only-l dbus-1` { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else with_dbus=no { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi else # no version check when doing --with-dbus DBUS_LIBDIR=$with_dbus/dbus/.libs if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_dbus" else CPPFLAGS="$CPPFLAGS -I$with_dbus" fi if test -z "$LDFLAGS"; then LDFLAGS="-L$DBUS_LIBDIR" else LDFLAGS="$LDFLAGS -L$DBUS_LIBDIR" fi LIBS_DBUS=-ldbus-1 fi # ... but double check that we actually have D-Bus if test "$with_dbus" != "no"; then OLD_LIBS="$LIBS" if test -z "$LIBS"; then LIBS="$LIBS_DBUS" else LIBS="$LIBS $LIBS_DBUS" fi for ac_header in dbus/dbus.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_dbus=no fi done with_dbus=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern "C" void dbus_message_new(); int main () { dbus_message_new(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then with_dbus= else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$OLD_LIBS fi if test "$with_dbus" != "no"; then cat >>confdefs.h <<\_ACEOF @%:@define WITH_DBUS /**/ _ACEOF fi fi # BSD sockets, if you're on Solaris { $as_echo "$as_me:$LINENO: checking for bind in -lsocket" >&5 $as_echo_n "checking for bind in -lsocket... " >&6; } if test "${ac_cv_lib_socket_bind+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 bind (); int main () { return bind (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_bind=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_bind=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_bind" >&5 $as_echo "$ac_cv_lib_socket_bind" >&6; } if test "x$ac_cv_lib_socket_bind" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi # openssl if test "$with_openssl" != "no"; then if test "$with_openssl" != ""; then if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_openssl/include" else CPPFLAGS="$CPPFLAGS -I$with_openssl/include" fi if test -z "$LDFLAGS"; then LDFLAGS="-L$with_openssl" else LDFLAGS="$LDFLAGS -L$with_openssl" fi fi for ac_header in openssl/ssl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define OPENSSL_NO_KRB5 @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_openssl=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for X509_free in -lcrypto" >&5 $as_echo_n "checking for X509_free in -lcrypto... " >&6; } if test "${ac_cv_lib_crypto_X509_free+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 X509_free (); int main () { return X509_free (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_crypto_X509_free=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypto_X509_free=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_X509_free" >&5 $as_echo "$ac_cv_lib_crypto_X509_free" >&6; } if test "x$ac_cv_lib_crypto_X509_free" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" fi { $as_echo "$as_me:$LINENO: checking for SSL_has_matching_session_id in -lssl" >&5 $as_echo_n "checking for SSL_has_matching_session_id in -lssl... " >&6; } if test "${ac_cv_lib_ssl_SSL_has_matching_session_id+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 SSL_has_matching_session_id (); int main () { return SSL_has_matching_session_id (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ssl_SSL_has_matching_session_id=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ssl_SSL_has_matching_session_id=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_has_matching_session_id" >&5 $as_echo "$ac_cv_lib_ssl_SSL_has_matching_session_id" >&6; } if test "x$ac_cv_lib_ssl_SSL_has_matching_session_id" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else with_openssl=no fi { $as_echo "$as_me:$LINENO: checking for POLICY_MAPPING_new in -lssl" >&5 $as_echo_n "checking for POLICY_MAPPING_new in -lssl... " >&6; } if test "${ac_cv_lib_ssl_POLICY_MAPPING_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 POLICY_MAPPING_new (); int main () { return POLICY_MAPPING_new (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ssl_POLICY_MAPPING_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ssl_POLICY_MAPPING_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_POLICY_MAPPING_new" >&5 $as_echo "$ac_cv_lib_ssl_POLICY_MAPPING_new" >&6; } if test "x$ac_cv_lib_ssl_POLICY_MAPPING_new" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else with_openssl_policy_mapping=no fi if test "$with_openssl_policy_mapping" != "no"; then cat >>confdefs.h <<\_ACEOF @%:@define HAVE_OPENSSL_POLICY_MAPPING 1 _ACEOF fi LIBS="$LIBS_save" if test "$with_openssl" != "no"; then LIBS_SSL="-lcrypto -lssl" fi fi # readline if test "$with_readline" != "no"; then for ac_header in readline/readline.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_readline=no fi done { $as_echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 readline (); int main () { return readline (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_readline_readline=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" else with_readline=no fi fi # pam if test "$with_pam" != "no"; then for ac_header in security/pam_appl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_pam=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if test "${ac_cv_lib_pam_pam_start+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pam_pam_start=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pam_pam_start=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else with_pam=no fi { $as_echo "$as_me:$LINENO: checking for sane PAM implementation" >&5 $as_echo_n "checking for sane PAM implementation... " >&6; } cat >conftest.$ac_ext <<_ACEOF #include "confdefs.h" #if HAVE_SECURITY_PAM_APPL_H # include #endif /* noconv: null PAM conversation function */ int noconv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *userdata) { // if you need to ask things, it won't work return PAM_CONV_ERR; } int main() { struct pam_conv c; c.conv = noconv; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF @%:@define HAVE_BROKEN_PAM 0 _ACEOF else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF @%:@define HAVE_BROKEN_PAM 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext LIBS="$LIBS_save" if test "$with_pam" != "no" -a "$HAVE_BROKEN_PAM" != "1"; then LIBS_PAM=-lpam fi fi # tcl if test "$with_tcl" != "no"; then CPPFLAGS_save="$CPPFLAGS" if test -z "$CPPFLAGS"; then CPPFLAGS="-I/usr/include/tcl8.3" else CPPFLAGS="$CPPFLAGS -I/usr/include/tcl8.3" fi for ac_header in tcl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_tcl=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for TclInterpInit in -ltcl8.3" >&5 $as_echo_n "checking for TclInterpInit in -ltcl8.3... " >&6; } if test "${ac_cv_lib_tcl8_3_TclInterpInit+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltcl8.3 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 TclInterpInit (); int main () { return TclInterpInit (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_tcl8_3_TclInterpInit=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tcl8_3_TclInterpInit=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_tcl8_3_TclInterpInit" >&5 $as_echo "$ac_cv_lib_tcl8_3_TclInterpInit" >&6; } if test "x$ac_cv_lib_tcl8_3_TclInterpInit" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBTCL8_3 1 _ACEOF LIBS="-ltcl8.3 $LIBS" else with_tcl=no fi LIBS="$LIBS_save" if test "$with_tcl" != "no"; then CPPFLAGS="$CPPFLAGS_save" LIBS_TCL=-ltcl8.3 fi fi # qt if test "$with_qt" != "no"; then test "$with_qt" = yes && with_qt= { $as_echo "$as_me:$LINENO: checking for Qt" >&5 $as_echo_n "checking for Qt... " >&6; } if test "${wv_cv_with_qt+set}" = set; then $as_echo_n "(cached) " >&6 else wv_cv_with_qt=no CPPFLAGS_save="$CPPFLAGS" LDFLAGS_save="$LDFLAGS" LIBS_save="$LIBS" for wv_qtdir in $with_qt $QTDIR $QT_SEARCH_PATH $(pkg-config --variable=prefix qt-mt); do eval wv_qtdir="$wv_qtdir" CPPFLAGS="$CPPFLAGS_save -I$wv_qtdir/include -I$wv_qtdir/include/qt3" LDFLAGS="$LDFLAGS_save -L$wv_qtdir/lib" LIBS="$LIBS_save -lqt-mt" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { QString x("hello"); return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then wv_cv_with_qt=$wv_qtdir; break else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext done CPPFLAGS="$CPPFLAGS_save" LDFLAGS="$LDFLAGS_save" LIBS="$LIBS_save" fi { $as_echo "$as_me:$LINENO: result: $wv_cv_with_qt" >&5 $as_echo "$wv_cv_with_qt" >&6; } with_qt=$wv_cv_with_qt if test "$with_qt" != no; then if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_qt/include -I$with_qt/include/qt3" else CPPFLAGS="$CPPFLAGS -I$with_qt/include -I$with_qt/include/qt3" fi if test "$wv_qtdir" != "/usr" ; then # never explicitly include /usr/lib if test -z "$LDFLAGS"; then LDFLAGS="-L$with_qt/lib" else LDFLAGS="$LDFLAGS -L$with_qt/lib" fi fi if test -z "$LIBS_QT"; then LIBS_QT="-lqt-mt" else LIBS_QT="$LIBS_QT -lqt-mt" fi fi # Extract the first word of "moc", so it can be a program name with args. set dummy moc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MOC+set}" = set; then $as_echo_n "(cached) " >&6 else case $MOC in [\\/]* | ?:[\\/]*) ac_cv_path_MOC="$MOC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $with_qt/bin 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_path_MOC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MOC" && ac_cv_path_MOC="moc not found" ;; esac fi MOC=$ac_cv_path_MOC if test -n "$MOC"; then { $as_echo "$as_me:$LINENO: result: $MOC" >&5 $as_echo "$MOC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi # valgrind if test "$with_valgrind" != "no"; then # Extract the first word of "valgrind", so it can be a program name with args. set dummy valgrind; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_VALGRIND+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$VALGRIND"; then ac_cv_prog_VALGRIND="$VALGRIND" # 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_VALGRIND="valgrind" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi VALGRIND=$ac_cv_prog_VALGRIND if test -n "$VALGRIND"; then { $as_echo "$as_me:$LINENO: result: $VALGRIND" >&5 $as_echo "$VALGRIND" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi for ac_header in valgrind/memcheck.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 fi # zlib if test "$with_zlib" != "no"; then for ac_header in zlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_zlib=no fi done { $as_echo "$as_me:$LINENO: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } if test "${ac_cv_lib_z_compress+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 compress (); int main () { return compress (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_z_compress=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_compress=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } if test "x$ac_cv_lib_z_compress" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else with_zlib=no fi fi # Find out whether TR1 or Boost are available. for ac_header in tr1/functional do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 boost/function.hpp do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # When compiling with exceptions disabled and Boost, applications need # to provide an "exception handler", declared here. for ac_header in boost/throw_exception.hpp do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX @%:@@%:@ ----------------------------------------------- @%:@@%:@ @%:@@%:@ Report this to wvstreams-devel@googlegroups.com @%:@@%:@ @%:@@%:@ ----------------------------------------------- @%:@@%:@ _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # check for missing packages missing_required= missing_devel= if test "$with_dbus" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: DBUS is missing." >&5 $as_echo "$as_me: WARNING: DBUS is missing." >&2;} missing_devel=yes fi if test "$with_pam" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: PAM is missing." >&5 $as_echo "$as_me: WARNING: PAM is missing." >&2;} missing_devel=yes fi if test "$with_qt" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: Qt is missing." >&5 $as_echo "$as_me: WARNING: Qt is missing." >&2;} missing_devel=yes fi if test "$VALGRIND" = ""; then { $as_echo "$as_me:$LINENO: WARNING: Valgrind is missing." >&5 $as_echo "$as_me: WARNING: Valgrind is missing." >&2;} fi if test "$with_openssl" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: OpenSSL is missing." >&5 $as_echo "$as_me: WARNING: OpenSSL is missing." >&2;} missing_required="$missing_required OpenSSL>=0.9.7" fi if test "$with_readline" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: readline is missing." >&5 $as_echo "$as_me: WARNING: readline is missing." >&2;} fi if test "$with_zlib" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: zlib is missing." >&5 $as_echo "$as_me: WARNING: zlib is missing." >&2;} missing_required="$missing_required zlib" fi if test "$ac_cv_header_tr1_functional" != "yes" \ -a "$ac_cv_header_boost_function_hpp" != "yes"; then { $as_echo "$as_me:$LINENO: WARNING: both tr1/functional and boost/function.hpp are missing." >&5 $as_echo "$as_me: WARNING: both tr1/functional and boost/function.hpp are missing." >&2;} missing_required="$missing_required boost/function.hpp" fi if test -n "$missing_required"; then { { $as_echo "$as_me:$LINENO: error: Required dependencies missing:$missing_required" >&5 $as_echo "$as_me: error: Required dependencies missing:$missing_required" >&2;} { (exit 1); exit 1; }; } fi if test "$VALGRIND" != ""; then VALGRIND="valgrind --tool=memcheck --leak-check=yes --num-callers=10 --suppressions=\$(WVSTREAMS_SRC)/wvstreams.supp" if valgrind --help | grep log-file >/dev/null; then VALGRIND="$VALGRIND --log-file=valgrind.log" else VALGRIND="$VALGRIND --logfile=valgrind.log" fi fi # Compiler is always posix if invoking this configure script COMPILER_STANDARD=posix cat >>confdefs.h <<_ACEOF @%:@define VERBOSE_PACKAGE_VERSION "$PACKAGE_VERSION$WEAVER_BUILD_INFO" _ACEOF ac_config_files="$ac_config_files config.mk" ac_config_files="$ac_config_files pkgconfig/libuniconf.pc pkgconfig/libuniconf-uninstalled.pc pkgconfig/libwvbase.pc pkgconfig/libwvbase-uninstalled.pc pkgconfig/libwvdbus.pc pkgconfig/libwvdbus-uninstalled.pc pkgconfig/libwvqt.pc pkgconfig/libwvqt-uninstalled.pc pkgconfig/libwvstreams.pc pkgconfig/libwvstreams-uninstalled.pc pkgconfig/libwvutils.pc pkgconfig/libwvutils-uninstalled.pc pkgconfig/libwvtest.pc pkgconfig/libwvtest-uninstalled.pc" ac_config_headers="$ac_config_headers include/wvautoconf.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:$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= ;; #( *) $as_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:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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 : $LIB@&t@OBJS; 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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIB@&t@OBJS=$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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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 # 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 WvStreams $as_me 4.6.1, which was generated by GNU Autoconf 2.63. 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 from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ WvStreams config.status 4.6.1 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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 CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; "pkgconfig/libuniconf.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libuniconf.pc" ;; "pkgconfig/libuniconf-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libuniconf-uninstalled.pc" ;; "pkgconfig/libwvbase.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvbase.pc" ;; "pkgconfig/libwvbase-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvbase-uninstalled.pc" ;; "pkgconfig/libwvdbus.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvdbus.pc" ;; "pkgconfig/libwvdbus-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvdbus-uninstalled.pc" ;; "pkgconfig/libwvqt.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvqt.pc" ;; "pkgconfig/libwvqt-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvqt-uninstalled.pc" ;; "pkgconfig/libwvstreams.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvstreams.pc" ;; "pkgconfig/libwvstreams-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvstreams-uninstalled.pc" ;; "pkgconfig/libwvutils.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvutils.pc" ;; "pkgconfig/libwvutils-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvutils-uninstalled.pc" ;; "pkgconfig/libwvtest.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvtest.pc" ;; "pkgconfig/libwvtest-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvtest-uninstalled.pc" ;; "include/wvautoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS include/wvautoconf.h" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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 '{ (exit 1); 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_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _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_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } fi ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # Now convert PACKAGE_* macros into WVPACKAGE_* in include/wvautoconf.h sed 's,\(\#define.*\)PACKAGE,\1WVPACKAGE,' include/wvautoconf.h > include/wvautoconf.h.new if test "x$?" = "x0"; then if ! diff include/wvautoconf.h include/wvautoconf.h.new >/dev/null; then mv include/wvautoconf.h.new include/wvautoconf.h else rm include/wvautoconf.h.new fi fi wvstreams-4.6.1/ee0000755000175000001440000000030111036722347013110 0ustar wlachusers#!/bin/sh xjed $(find -type f \( -name '*.src' -o -name '*.pl' -o -name '*.pm' \ -o -name '*.aml' \ -o -name '*.cc' -o -name '*.c' -o -name '*.h' \) | fgrep -v .tmp.) \ include/wvstream.h & wvstreams-4.6.1/wvtestmain.cc0000644000175000001440000000302111036722347015303 0ustar wlachusers#include "wvtest.h" #include "wvcrash.h" #include "wvstring.h" #include #include #ifdef _WIN32 #include #include #else #include #include #endif static bool fd_is_valid(int fd) { #ifdef _WIN32 if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true; #endif int nfd = dup(fd); if (nfd >= 0) { close(nfd); return true; } return false; } static int fd_count(const char *when) { int count = 0; printf("fds open at %s:", when); for (int fd = 0; fd < 1024; fd++) { if (fd_is_valid(fd)) { count++; printf(" %d", fd); fflush(stdout); } } printf("\n"); return count; } int main(int argc, char **argv) { #ifdef _WIN32 setup_console_crash(); #endif // test wvtest itself. Not very thorough, but you have to draw the // line somewhere :) WVPASS(true); WVPASS(1); WVFAIL(false); WVFAIL(0); int startfd, endfd; char * const *prefixes = NULL; if (argc > 1) prefixes = argv + 1; startfd = fd_count("start"); int ret = WvTest::run_all(prefixes); if (ret == 0) // don't pollute the strace output if we failed anyway { endfd = fd_count("end"); WVPASS(startfd == endfd); #ifndef _WIN32 if (startfd != endfd) system(WvString("ls -l /proc/%s/fd", getpid())); #endif } // keep 'make' from aborting if this environment variable is set if (getenv("WVTEST_NO_FAIL")) return 0; else return ret; } wvstreams-4.6.1/gen-cc0000755000175000001440000000066211254003232013650 0ustar wlachusers#!/bin/sh +e OUTFILE=$1 EXT=$2 echo "* Generating $OUTFILE using $EXT" >&2 TEMPFILE=gencc-$$.tmp cat >$TEMPFILE <<-EOF #!/bin/sh set -e MODE=\$1 BASE=\$2 DIR=\`dirname \$BASE\` DEPFILE=\$DIR/.\`basename \$BASE .o\`.d shift shift $CC \$MODE -o \$BASE.o \$BASE.$EXT \\ -MMD -MF \$DEPFILE -MP -MQ \$BASE.o \\ $CPPFLAGS \\ $CFLAGS \\ "\$@" EOF chmod a+x $TEMPFILE mv $TEMPFILE $OUTFILE wvstreams-4.6.1/LICENSE0000644000175000001440000006126111061264424013605 0ustar wlachusers GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! wvstreams-4.6.1/urlget/0000755000175000001440000000000011260431126014070 5ustar wlachuserswvstreams-4.6.1/urlget/wvftpstream.cc0000644000175000001440000003560711036722347017005 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A fast, easy-to-use, parallelizing, pipelining HTTP/1.1 file retriever. * * See wvhttppool.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif #include #include #include "wvhttppool.h" #include "wvbufstream.h" #include "wvtcp.h" #include "wvsslstream.h" #include "strutils.h" #include // for alloca()... FIXME: which we shouldn't be using! WvFtpStream::WvFtpStream(const WvIPPortAddr &_remaddr, WvStringParm _username, WvStringParm _password) : WvUrlStream(_remaddr, _username, WvString("FTP %s", _remaddr)), cont(wv::bind(&WvFtpStream::real_execute, this, _1)) { data = NULL; logged_in = false; password = _password; last_request_time = time(0); alarm(60000); // timeout if no connection, or something goes wrong } void WvFtpStream::doneurl() { log("Done URL: %s\n", curl->url); curl->done(); curl = NULL; WVRELEASE(data); urls.unlink_first(); last_request_time = time(0); alarm(60000); request_next(); // We just processed the last url in the queue, // so go away. if (urls.isempty() && waiting_urls.isempty()) close(); } void WvFtpStream::request_next() { // don't do a request if we've done too many already or we have none // waiting. if (request_count >= max_requests || waiting_urls.isempty()) return; if (!urls.isempty()) return; // okay then, we really do want to send a new request. WvUrlRequest *url = waiting_urls.first(); waiting_urls.unlink_first(); request_count++; log("Request #%s: %s\n", request_count, url->url); urls.append(url, false, "request_url"); alarm(0); } void WvFtpStream::close() { if (isok()) log("Closing.\n"); WvStreamClone::close(); if (geterr()) { // if there was an error, count the first URL as done. This prevents // retrying indefinitely. if (!curl && !urls.isempty()) curl = urls.first(); if (!curl && !waiting_urls.isempty()) curl = waiting_urls.first(); if (curl) log("URL '%s' is FAILED\n", curl->url); if (curl) curl->done(); } if (curl) curl->done(); } char *WvFtpStream::get_important_line() { char *line; do { line = blocking_getline(-1); if (!line) return NULL; } while (line[3] == '-'); log(WvLog::Debug5, ">> %s\n", line); return line; } void WvFtpStream::pre_select(SelectInfo &si) { SelectRequest oldwant = si.wants; WvUrlStream::pre_select(si); if (data) data->pre_select(si); if (curl && curl->putstream) curl->putstream->pre_select(si); si.wants = oldwant; } bool WvFtpStream::post_select(SelectInfo &si) { SelectRequest oldwant = si.wants; if (WvUrlStream::post_select(si)) return true; if (data && data->post_select(si)) return true; if (curl && curl->putstream && curl->putstream->post_select(si)) return true; si.wants = oldwant; return false; } void *WvFtpStream::real_execute(void*) { WvString line; WvStreamClone::execute(); if (alarm_was_ticking && ((last_request_time + 60) <= time(0))) { log(WvLog::Debug4, "urls count: %s\n", urls.count()); if (urls.isempty()) close(); // timed out, but not really an error return 0; } if (!logged_in) { line = get_important_line(); if (!line) { seterr("Server not reachable: %s\n",strerror(errno)); return 0; } if (strncmp(line, "220", 3)) { log("Server rejected connection: %s\n", line); seterr("server rejected connection"); return 0; } print("USER %s\r\n", !target.username ? WvString("anonymous") : target.username); line = get_important_line(); if (!line) return 0; if (!strncmp(line, "230", 3)) { log(WvLog::Info, "Server doesn't need password.\n"); logged_in = true; // No password needed; } else if (!strncmp(line, "33", 2)) { print("PASS %s\r\n", !password ? DEFAULT_ANON_PW : password); line = get_important_line(); if (!line) return 0; if (line[0] == '2') { log(WvLog::Info, "Authenticated.\n"); logged_in = true; } else { log("Strange response to PASS command: %s\n", line); seterr("strange response to PASS command"); return 0; } } else { log("Strange response to USER command: %s\n", line); seterr("strange response to USER command"); return 0; } print("TYPE I\r\n"); log(WvLog::Debug5, "<< TYPE I\n"); line = get_important_line(); if (!line) return 0; if (strncmp(line, "200", 3)) { log("Strange response to TYPE I command: %s\n", line); seterr("strange response to TYPE I command"); return 0; } } if (!curl && !urls.isempty()) { curl = urls.first(); print("CWD %s\r\n", curl->url.getfile()); line = get_important_line(); if (!line) return 0; if (!strncmp(line, "250", 3)) { log(WvLog::Debug5, "This is a directory.\n"); curl->is_dir = true; } print("PASV\r\n"); line = get_important_line(); if (!line) return 0; WvIPPortAddr *dataip = parse_pasv_response(line.edit()); if (!dataip) return 0; log(WvLog::Debug4, "Data port is %s.\n", *dataip); // Open data connection. data = new WvTCPConn(*dataip); if (!data) { log("Can't open data connection.\n"); seterr("can't open data connection"); return 0; } if (curl->is_dir) { if (!curl->putstream) { print("LIST %s\r\n", curl->url.getfile()); if (curl->outstream) { WvString url_no_pw("ftp://%s%s%s%s", curl->url.getuser(), !!curl->url.getuser() ? "@" : "", curl->url.gethost(), curl->url.getfile()); curl->outstream->print("\n" "\n\n%s\n" "\n" "\n\n" "\n\n" "

Index of %s

\n" "
\n", url_no_pw, curl->url, url_no_pw ); } } else { log("Target is a directory.\n"); seterr("target is a directory"); doneurl(); return 0; } } else if (!curl->putstream) print("RETR %s\r\n", curl->url.getfile()); else { if (curl->create_dirs) { print("CWD %s\r\n", getdirname(curl->url.getfile())); line = get_important_line(); if (!line) return 0; if (strncmp(line, "250", 3)) { log("Path doesn't exist; creating directories...\n"); // create missing directories. WvString current_dir(""); WvStringList dirs; dirs.split(getdirname(curl->url.getfile()), "/"); WvStringList::Iter i(dirs); for (i.rewind(); i.next(); ) { current_dir.append(WvString("/%s", i())); print("MKD %s\r\n", current_dir); line = get_important_line(); if (!line) return 0; } } } print("STOR %s\r\n", curl->url.getfile()); } log(WvLog::Debug5, "Waiting for response to %s\n", curl->putstream ? "STOR" : curl->is_dir ? "LIST" : "RETR"); line = get_important_line(); if (!line) doneurl(); else if (strncmp(line, "150", 3)) { log("Strange response to %s command: %s\n", curl->putstream ? "STOR" : "RETR", line); seterr(WvString("strange response to %s command", curl->putstream ? "STOR" : "RETR")); doneurl(); } } if (curl) { if (curl->is_dir) { line = data->blocking_getline(-1); if (line && curl->outstream) { WvString output_line(parse_for_links(line.edit())); if (!!output_line) curl->outstream->write(output_line); else curl->outstream->write("Unknown format of LIST " "response\n"); } } else { char buf[1024]; if (curl->putstream) { while (curl->putstream->isreadable()) { int len = curl->putstream->read(buf, sizeof(buf)); log(WvLog::Debug5, "Read %s bytes.\n%s\n", len, hexdump_buffer(buf, len)); if (len) { int wrote = data->write(buf, len); log(WvLog::Debug5,"Wrote %s bytes\n", wrote); data->flush(0); } } curl->putstream->close(); } else { while (data->isreadable() && curl->outstream->isok()) { int len = data->read(buf, sizeof(buf)); log(WvLog::Debug5, "Read %s bytes from remote.\n", len); if (len && curl->outstream) { int wrote = curl->outstream->write(buf, len); log(WvLog::Debug5, "Wrote %s bytes to local.\n", wrote); } } } } if (!data->isok() || (curl->putstream && !curl->putstream->isok())) { log("OK, we should have finished writing!\n"); if (curl->putstream && data->isok()) data->close(); line = get_important_line(); if (!line) { doneurl(); return 0; } if (strncmp(line, "226", 3)) log("Unexpected message: %s\n", line); if (curl->is_dir) { if (curl->outstream) curl->outstream->write("

\n" "\n"); write("CWD /\r\n"); log(WvLog::Debug5, "Waiting for response to CWD /\n"); line = get_important_line(); if (!line) return 0; if (strncmp(line, "250", 3)) log("Strange resonse to \"CWD /\": %s\n", line); // Don't bother failing here. } doneurl(); } else { log("Why are we here??\n"); } } return 0; } void WvFtpStream::execute() { real_execute(0); } WvString WvFtpStream::parse_for_links(char *line) { WvString output_line(""); trim_string(line); if (curl->is_dir && curl->outstream) { struct ftpparse fp; int res = ftpparse(&fp, line, strlen(line)); if (res) { char *linkname = (char *)alloca(fp.namelen+1); int i; for (i = 0; i < fp.namelen; i++) { if (fp.name[i] >= 32) linkname[i] = fp.name[i]; else { linkname[i] = '?'; } } linkname[i] = 0; WvString linkurl(curl->url); if (linkurl.cstr()[linkurl.len()-1] != '/') linkurl.append("/"); linkurl.append(linkname); WvUrlLink *link = new WvUrlLink(linkname, linkurl); curl->outstream->links.append(link, true); output_line.append("\n"); output_line.append(WvString(" %s%s\n", linkname, fp.flagtrycwd ? "/" : "")); if (fp.flagtryretr) { if (!fp.sizetype) output_line.append(" ? bytes\n"); else output_line.append(WvString(" %s bytes\n", fp.size)); if (fp.mtimetype > 0) output_line.append(WvString(" %s\n", (fp.mtime))); else output_line.append(" ?\n"); } else output_line.append(" \n"); output_line.append("\n"); } } return output_line; } WvIPPortAddr *WvFtpStream::parse_pasv_response(char *line) { if (strncmp(line, "227 ", 4)) { log("Strange response to PASV command: %s\n", line); seterr("strange response to PASV command"); return NULL; } char *p = &line[3]; while (!isdigit(*p)) { if (*p == '\0' || *p == '\r' || *p == '\n') { log("Couldn't parse PASV response: %s\n", line); seterr("couldn't parse response to PASV command"); return NULL; } p++; } char *ipstart = p; for (int i = 0; i < 4; i++) { p = strchr(p, ','); if (!p) { log("Couldn't parse PASV IP: %s\n", line); seterr("couldn't parse PASV IP"); return NULL; } *p = '.'; } *p = '\0'; WvString pasvip(ipstart); p++; int pasvport; pasvport = atoi(p)*256; p = strchr(p, ','); if (!p) { log("Couldn't parse PASV IP port: %s\n", line); seterr("couldn't parse PASV IP port"); return NULL; } pasvport += atoi(++p); WvIPPortAddr *res = new WvIPPortAddr(pasvip.cstr(), pasvport); return res; } wvstreams-4.6.1/urlget/tests/0000755000175000001440000000000011260431126015232 5ustar wlachuserswvstreams-4.6.1/urlget/tests/http2test.in10000644000175000001440000000313111036722347017613 0ustar wlachusershttp://www.net-itech.com/america/index.htm http://www.net-itech.com/america/images/top_logo.gif http://www.net-itech.com/america/images/title.jpg http://www.net-itech.com/america/images/home_but2.gif http://www.net-itech.com/america/images/products_but1.gif http://www.net-itech.com/america/images/support_but1.gif http://www.net-itech.com/america/images/news_but1.gif http://www.net-itech.com/america/images/sub_but_contact.gif http://www.net-itech.com/america/images/sub_but_buy.gif http://www.net-itech.com/america/images/home_main_left.gif http://www.net-itech.com/america/images/home_main.jpg http://www.net-itech.com/america/images/home_news_title.gif http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/arrow.gif http://www.net-itech.com/america/images/arrow.gif http://www.net-itech.com/america/images/arrow.gif http://www.net-itech.com/america/images/arrow.gif http://www.net-itech.com/america/images/arrow.gif http://www.net-itech.com/america/images/home_news_footer.jpg http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/home_flash.jpg http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/home_how.jpg http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/home_about.jpg http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/home_reseller.jpg http://www.net-itech.com/america/images/dot.gif http://www.net-itech.com/america/images/border.jpg wvstreams-4.6.1/urlget/tests/http2test.in20000644000175000001440000000322711036722347017622 0ustar wlachusershttps://mars.net-itech.com/america/index.htm https://mars.net-itech.com/america/images/top_logo.gif https://mars.net-itech.com/america/images/title.jpg https://mars.net-itech.com/america/images/home_but2.gif https://mars.net-itech.com/america/images/products_but1.gif https://mars.net-itech.com/america/images/support_but1.gif https://mars.net-itech.com/america/images/news_but1.gif https://mars.net-itech.com/america/images/sub_but_contact.gif https://mars.net-itech.com/america/images/sub_but_buy.gif https://mars.net-itech.com/america/images/home_main_left.gif https://mars.net-itech.com/america/images/home_main.jpg https://mars.net-itech.com/america/images/home_news_title.gif https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/arrow.gif https://mars.net-itech.com/america/images/arrow.gif https://mars.net-itech.com/america/images/arrow.gif https://mars.net-itech.com/america/images/arrow.gif https://mars.net-itech.com/america/images/arrow.gif https://mars.net-itech.com/america/images/home_news_footer.jpg https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/home_flash.jpg https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/home_how.jpg https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/home_about.jpg https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/home_reseller.jpg https://mars.net-itech.com/america/images/dot.gif https://mars.net-itech.com/america/images/border.jpg wvstreams-4.6.1/urlget/tests/http2test.cc0000644000175000001440000000335111036722347017515 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvHttpPool test. Downloads the urls given on stdin. */ #include "wvhttppool.h" #include "wvfile.h" #include "strutils.h" #include static WvLog mylog("http2test", WvLog::Info); static bool want_to_die = false; static void sighandler_die(int signum) { fprintf(stderr, "Caught signal %d; cleaning up and terminating.\n", signum); want_to_die = true; signal(signum, SIG_DFL); } static void close_callback(WvStream *s) { if (!s->isok()) mylog(WvLog::Error, "%s\n", s->geterr()); } int main(int argc, char **argv) { WvIStreamList l; WvHttpPool p; WvString headers(""); char *line; #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); signal(SIGINT, sighandler_die); #endif l.append(wvcon, false, "wvcon"); l.append(&p, false, "WvHttpPool"); while (!want_to_die && p.isok() && (wvcon->isok() || !p.idle())) { if (l.select(1000)) { l.callback(); line = wvcon->getline(); if (line) { line = trim_string(line); if (!line[0]) continue; else if (strstr(line, ": ")) { // an extra http header headers = WvString("%s%s\n", headers, line); continue; } WvStream *s = p.addurl(line, "GET", headers); if (s) { static int num = 0; WvFile *f = new WvFile(WvString("/tmp/url_%s", ++num), O_CREAT|O_WRONLY|O_TRUNC); assert(!f->readable); s->autoforward(*f); s->setclosecallback(wv::bind(close_callback, s)); l.append(s, true, "url"); l.append(f, true, "file"); } } } } if (!p.isok() && p.geterr()) mylog("HttpPool: %s\n", p.errstr()); return 0; } wvstreams-4.6.1/urlget/tests/imgtags.pl0000755000175000001440000000045211036722347017237 0ustar wlachusers#!/usr/bin/perl -w # Parse an html file and grab all the urls requested by IMG tags. # $urlbase=$ARGV[0]; @all = ; $_ = join("", @all); @l = /]*src="([^"]*)"[^>]*>/gis; foreach $u (@l) { if ($u =~ m{^https?://}) { print "$u\n"; } else { print "$urlbase$u\n"; } } wvstreams-4.6.1/urlget/ftpparse.cc0000644000175000001440000003244211036722347016241 0ustar wlachusers/* ftpparse.c, ftpparse.h: library for parsing FTP LIST responses 20001223 D. J. Bernstein, djb@cr.yp.to http://cr.yp.to/ftpparse.html Commercial use is fine, if you let me know what programs you're using this in. Currently covered formats: EPLF. UNIX ls, with or without gid. Microsoft FTP Service. Windows NT FTP Server. VMS. WFTPD. NetPresenz (Mac). NetWare. MSDOS. Definitely not covered: Long VMS filenames, with information split across two lines. NCSA Telnet FTP server. Has LIST = NLST (and bad NLST for directories). */ #include #include "ftpparse.h" static long totai(long year,long month,long mday) { long result; if (month >= 2) month -= 2; else { month += 10; --year; } result = (mday - 1) * 10 + 5 + 306 * month; result /= 10; if (result == 365) { year -= 3; result = 1460; } else result += 365 * (year % 4); year /= 4; result += 1461 * (year % 25); year /= 25; if (result == 36524) { year -= 3; result = 146096; } else { result += 36524 * (year % 4); } year /= 4; result += 146097 * (year - 5); result += 11017; return result * 86400; } static int flagneedbase = 1; static time_t base; /* time() value on this OS at the beginning of 1970 TAI */ static long now; /* current time */ static int flagneedcurrentyear = 1; static long currentyear; /* approximation to current year */ static void initbase(void) { struct tm *t; if (!flagneedbase) return; base = 0; t = gmtime(&base); base = -(totai(t->tm_year + 1900,t->tm_mon,t->tm_mday) + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec); /* assumes the right time_t, counting seconds. */ /* base may be slightly off if time_t counts non-leap seconds. */ flagneedbase = 0; } static void initnow(void) { long day; long year; initbase(); now = time((time_t *) 0) - base; if (flagneedcurrentyear) { day = now / 86400; if ((now % 86400) < 0) --day; day -= 11017; year = 5 + day / 146097; day = day % 146097; if (day < 0) { day += 146097; --year; } year *= 4; if (day == 146096) { year += 3; day = 36524; } else { year += day / 36524; day %= 36524; } year *= 25; year += day / 1461; day %= 1461; year *= 4; if (day == 1460) { year += 3; day = 365; } else { year += day / 365; day %= 365; } day *= 10; if ((day + 5) / 306 >= 10) ++year; currentyear = year; flagneedcurrentyear = 0; } } /* UNIX ls does not show the year for dates in the last six months. */ /* So we have to guess the year. */ /* Apparently NetWare uses ``twelve months'' instead of ``six months''; ugh. */ /* Some versions of ls also fail to show the year for future dates. */ static long guesstai(long month,long mday) { long year; long t; initnow(); for (year = currentyear - 1;year < currentyear + 100;++year) { t = totai(year,month,mday); if (now - t < 350 * 86400) return t; } return 0; /* shouldn't happen, but this gets rid of compiler warnings */ } static int check(char *buf, const char *monthname) { if ((buf[0] != monthname[0]) && (buf[0] != monthname[0] - 32)) return 0; if ((buf[1] != monthname[1]) && (buf[1] != monthname[1] - 32)) return 0; if ((buf[2] != monthname[2]) && (buf[2] != monthname[2] - 32)) return 0; return 1; } static const char *months[12] = { "jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec" } ; static int getmonth(char *buf, int len) { int i; if (len == 3) for (i = 0;i < 12;++i) if (check(buf,months[i])) return i; return -1; } static long getlong(char *buf,int len) { long u = 0; while (len-- > 0) u = u * 10 + (*buf++ - '0'); return u; } int ftpparse(struct ftpparse *fp,char *buf,int len) { int i; int j; int state; long size = 0; long year; long month = 0; long mday = 0; long hour; long minute; fp->name = 0; fp->namelen = 0; fp->flagtrycwd = 0; fp->flagtryretr = 0; fp->sizetype = FTPPARSE_SIZE_UNKNOWN; fp->size = 0; fp->mtimetype = FTPPARSE_MTIME_UNKNOWN; fp->mtime = 0; fp->idtype = FTPPARSE_ID_UNKNOWN; fp->id = 0; fp->idlen = 0; if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */ return 0; switch(*buf) { /* see http://pobox.com/~djb/proto/eplf.txt */ /* "+i8388621.29609,m824255902,/,\tdev" */ /* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF" */ case '+': i = 1; for (j = 1;j < len;++j) { if (buf[j] == 9) { fp->name = buf + j + 1; fp->namelen = len - j - 1; return 1; } if (buf[j] == ',') { switch(buf[i]) { case '/': fp->flagtrycwd = 1; break; case 'r': fp->flagtryretr = 1; break; case 's': fp->sizetype = FTPPARSE_SIZE_BINARY; fp->size = getlong(buf + i + 1,j - i - 1); break; case 'm': fp->mtimetype = FTPPARSE_MTIME_LOCAL; initbase(); fp->mtime = base + getlong(buf + i + 1,j - i - 1); break; case 'i': fp->idtype = FTPPARSE_ID_FULL; fp->id = buf + i + 1; fp->idlen = j - i - 1; } i = j + 1; } } return 0; /* UNIX-style listing, without inum and without blocks */ /* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */ /* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */ /* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */ /* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */ /* Also produced by Microsoft's FTP servers for Windows: */ /* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */ /* "d--------- 1 owner group 0 May 9 19:45 Softlib" */ /* Also WFTPD for MSDOS: */ /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */ /* Also NetWare: */ /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */ /* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */ /* Also NetPresenz for the Mac: */ /* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */ /* "drwxrwxr-x folder 2 May 10 1996 network" */ case 'b': case 'c': case 'd': case 'l': case 'p': case 's': case '-': if (*buf == 'd') fp->flagtrycwd = 1; if (*buf == '-') fp->flagtryretr = 1; if (*buf == 'l') fp->flagtrycwd = fp->flagtryretr = 1; state = 1; i = 0; for (j = 1;j < len;++j) if ((buf[j] == ' ') && (buf[j - 1] != ' ')) { switch(state) { case 1: /* skipping perm */ state = 2; break; case 2: /* skipping nlink */ state = 3; if ((j - i == 6) && (buf[i] == 'f')) /* for NetPresenz */ state = 4; break; case 3: /* skipping uid */ state = 4; break; case 4: /* getting tentative size */ size = getlong(buf + i,j - i); state = 5; break; case 5: /* searching for month, otherwise getting tentative size */ month = getmonth(buf + i,j - i); if (month >= 0) state = 6; else size = getlong(buf + i,j - i); break; case 6: /* have size and month */ mday = getlong(buf + i,j - i); state = 7; break; case 7: /* have size, month, mday */ if ((j - i == 4) && (buf[i + 1] == ':')) { hour = getlong(buf + i,1); minute = getlong(buf + i + 2,2); fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; initbase(); fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; } else if ((j - i == 5) && (buf[i + 2] == ':')) { hour = getlong(buf + i,2); minute = getlong(buf + i + 3,2); fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; initbase(); fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; } else if (j - i >= 4) { year = getlong(buf + i,j - i); fp->mtimetype = FTPPARSE_MTIME_REMOTEDAY; initbase(); fp->mtime = base + totai(year,month,mday); } else return 0; fp->name = buf + j + 1; fp->namelen = len - j - 1; state = 8; break; case 8: /* twiddling thumbs */ break; } i = j + 1; while ((i < len) && (buf[i] == ' ')) ++i; } if (state != 8) return 0; fp->size = size; fp->sizetype = FTPPARSE_SIZE_BINARY; if (*buf == 'l') for (i = 0;i + 3 < fp->namelen;++i) if (fp->name[i] == ' ') if (fp->name[i + 1] == '-') if (fp->name[i + 2] == '>') if (fp->name[i + 3] == ' ') { fp->namelen = i; break; } /* eliminate extra NetWare spaces */ if ((buf[1] == ' ') || (buf[1] == '[')) if (fp->namelen > 3) if (fp->name[0] == ' ') if (fp->name[1] == ' ') if (fp->name[2] == ' ') { fp->name += 3; fp->namelen -= 3; } return 1; } /* MultiNet (some spaces removed from examples) */ /* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */ /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */ /* and non-MutliNet VMS: */ /* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */ for (i = 0;i < len;++i) if (buf[i] == ';') break; if (i < len) { fp->name = buf; fp->namelen = i; if (i > 4) if (buf[i - 4] == '.') if (buf[i - 3] == 'D') if (buf[i - 2] == 'I') if (buf[i - 1] == 'R') { fp->namelen -= 4; fp->flagtrycwd = 1; } if (!fp->flagtrycwd) fp->flagtryretr = 1; while (buf[i] != ' ') if (++i == len) return 0; while (buf[i] == ' ') if (++i == len) return 0; while (buf[i] != ' ') if (++i == len) return 0; while (buf[i] == ' ') if (++i == len) return 0; j = i; while (buf[j] != '-') if (++j == len) return 0; mday = getlong(buf + i,j - i); while (buf[j] == '-') if (++j == len) return 0; i = j; while (buf[j] != '-') if (++j == len) return 0; month = getmonth(buf + i,j - i); if (month < 0) return 0; while (buf[j] == '-') if (++j == len) return 0; i = j; while (buf[j] != ' ') if (++j == len) return 0; year = getlong(buf + i,j - i); while (buf[j] == ' ') if (++j == len) return 0; i = j; while (buf[j] != ':') if (++j == len) return 0; hour = getlong(buf + i,j - i); while (buf[j] == ':') if (++j == len) return 0; i = j; while ((buf[j] != ':') && (buf[j] != ' ')) if (++j == len) return 0; minute = getlong(buf + i,j - i); fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; initbase(); fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; return 1; } /* MSDOS format */ /* 04-27-00 09:09PM licensed */ /* 07-18-00 10:16AM pub */ /* 04-14-00 03:47PM 589 readme.htm */ if ((*buf >= '0') && (*buf <= '9')) { i = 0; j = 0; while (buf[j] != '-') if (++j == len) return 0; month = getlong(buf + i,j - i) - 1; while (buf[j] == '-') if (++j == len) return 0; i = j; while (buf[j] != '-') if (++j == len) return 0; mday = getlong(buf + i,j - i); while (buf[j] == '-') if (++j == len) return 0; i = j; while (buf[j] != ' ') if (++j == len) return 0; year = getlong(buf + i,j - i); if (year < 50) year += 2000; if (year < 1000) year += 1900; while (buf[j] == ' ') if (++j == len) return 0; i = j; while (buf[j] != ':') if (++j == len) return 0; hour = getlong(buf + i,j - i); while (buf[j] == ':') if (++j == len) return 0; i = j; while ((buf[j] != 'A') && (buf[j] != 'P')) if (++j == len) return 0; minute = getlong(buf + i,j - i); if (hour == 12) hour = 0; if (buf[j] == 'A') if (++j == len) return 0; if (buf[j] == 'P') { hour += 12; if (++j == len) return 0; } if (buf[j] == 'M') if (++j == len) return 0; while (buf[j] == ' ') if (++j == len) return 0; if (buf[j] == '<') { fp->flagtrycwd = 1; while (buf[j] != ' ') if (++j == len) return 0; } else { i = j; while (buf[j] != ' ') if (++j == len) return 0; fp->size = getlong(buf + i,j - i); fp->sizetype = FTPPARSE_SIZE_BINARY; fp->flagtryretr = 1; } while (buf[j] == ' ') if (++j == len) return 0; fp->name = buf + j; fp->namelen = len - j; fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; initbase(); fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; return 1; } /* Some useless lines, safely ignored: */ /* "Total of 11 Files, 10966 Blocks." (VMS) */ /* "total 14786" (UNIX) */ /* "DISK$ANONFTP:[ANONYMOUS]" (VMS) */ /* "Directory DISK$PCSA:[ANONYM]" (VMS) */ return 0; } wvstreams-4.6.1/urlget/wvhttpcomponent.cc0000644000175000001440000000147211036722347017673 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Componentization stuff for wvhttppool.h. Constitutes cheating. */ #include "wvhttppool.h" #include "wvmoniker.h" #include "wvistreamlist.h" static WvHttpPool *pool; static void pool_init() { // FIXME: we never free it! if (!pool) { pool = new WvHttpPool; WvIStreamList::globallist.append(pool, false, "pool_init urlpool"); } } static IWvStream *creator(WvStringParm s, IObject*) { pool_init(); return pool->addurl(WvString("http:%s", s), "GET"); } static IWvStream *screator(WvStringParm s, IObject*) { pool_init(); return pool->addurl(WvString("https:%s", s), "GET"); } static WvMoniker reg("http", creator); static WvMoniker regs("https", screator); wvstreams-4.6.1/urlget/t/0000755000175000001440000000000011260431126014333 5ustar wlachuserswvstreams-4.6.1/urlget/t/wvhttppool.t.cc0000644000175000001440000001467511077124114017351 0ustar wlachusers#include "wvtest.h" #include "wvhttppool.h" #include "wvtcplistener.h" #include #ifndef _WIN32 #include #endif static void close_callback(WvStream& s) { if (!s.isok()) printf("%d", s.geterr()); } WVTEST_MAIN("WvHttpPool GET") { if (gethostbyname("www.google.com")) { WvHttpPool pool; WvIStreamList l; l.append(&pool, false, "WvHttpPool"); WvStream *buf; WVPASS(buf = pool.addurl("http://www.google.com")); WVPASS(buf->isok()); buf->autoforward(*wvcon); buf->setclosecallback(wv::bind(close_callback, wv::ref(*buf))); l.append(buf, true, "buf stream"); while (buf->isok() && (wvcon->isok() || !pool.idle())) l.runonce(); WVPASS(!(buf->isok())); WVPASSEQ(l.count(), 2); } else printf("Can't find www.google.com. SKIPPED.\n"); } WVTEST_MAIN("WvHttpPool HEAD") { if (gethostbyname("www.google.com")) { WvHttpPool pool; WvIStreamList l; l.append(&pool, false, "WvHttpPool"); WvStream *buf; WVPASS(buf = pool.addurl("http://www.google.com", "HEAD")); WVPASS(buf->isok()); buf->autoforward(*wvcon); buf->setclosecallback(wv::bind(close_callback, wv::ref(*buf))); l.append(buf, true, "buf stream"); while (buf->isok() && (wvcon->isok() || !pool.idle())) { if (l.select(-1)) { l.callback(); } } WVPASS(!(buf->isok())); } else printf("Can't find www.google.com. SKIPPED.\n"); } WVTEST_MAIN("wvhttppool can't connect") { unsigned int port = 4200; WvHttpPool pool; WvIStreamList l; l.append(&pool, false, "WvHttpPool"); WvStream *buf; WVPASS(buf = pool.addurl(WvString("http://joeyjoejoejuniorshabadoo.fi", port), "HEAD")); WVPASS(buf->isok()); buf->autoforward(*wvcon); l.append(buf, true, "buf stream"); while (buf->isok() && (wvcon->isok() || !pool.idle())) l.runonce(); WVFAIL(buf->isok()); } bool pipelining_enabled = true; bool expecting_request = false; bool break_connection = false; unsigned int http_conns = 0; void tcp_callback(WvStream &s) { bool last_was_pipeline_check = false; WvString buf(""); char *line; do { line = s.getline(); if (line && (strncmp(line, "GET", 3) == 0 || strncmp(line, "HEAD", 4) == 0)) { if (expecting_request) { if (strstr(line, "wvhttp-pipeline-check-should-not-exist")) { printf("Sending 404\n"); buf.append("HTTP/1.1 404 Not Found\n\n"); last_was_pipeline_check = true; } else { printf("Sending 200\n"); buf.append("HTTP/1.1 200 OK\n" "Content-Length: 5\n" "Content-Type: text/html\n\n" "Foo!\n"); last_was_pipeline_check = false; if (break_connection) { break_connection = false; s.close(); } } if (!pipelining_enabled) expecting_request = false; } else { printf("Sending 400\n"); buf.append("HTTP/1.1 400 Invalid Request\n" "Content-Length: 5\n" "Content-Type: text/html\n\n" "Bar!\n"); // we should only be returning a 400 during the pipeling test; // otherwise, it means that WvHttpPool didn't detect broken // pipelining correctly. WVPASS(last_was_pipeline_check); } } } while (line); s.print(buf); expecting_request = true; } static void listener_callback(WvIStreamList *list, IWvStream *_newconn) { http_conns++; printf("Incoming connection (%u)\n", http_conns); WvStreamClone *newconn = new WvStreamClone(_newconn); newconn->setcallback(wv::bind(tcp_callback, wv::ref(*newconn))); list->append(newconn, true, "incoming http conn"); expecting_request = true; } static void do_test(WvIStreamList &l, unsigned int port, unsigned int num_requests) { printf("pipelining [%d] requests [%u]\n", pipelining_enabled, num_requests); WvHttpPool pool; WvIStreamList bufs; l.append(&pool, false, "WvHttpPool"); l.append(&bufs, false, "list of bufs"); http_conns = 0; WvStream *buf; for (unsigned int i = 0; i < num_requests; i++) { WVPASS(buf = pool.addurl(WvString("http://localhost:%s/%s.html", port, i))); WVPASS(buf->isok()); buf->autoforward(*wvcon); buf->setclosecallback(wv::bind(close_callback, wv::ref(*buf))); bufs.append(buf, true, "poolbuf"); } WvIStreamList::Iter j(bufs); while (wvcon->isok() || !pool.idle()) { bool buf_ok = false; for (j.rewind(); j.next(); ) if (j().isok()) buf_ok = true; if (!buf_ok) break; l.runonce(); } l.runonce(10); l.runonce(10); WVPASSEQ(bufs.count(), 0); l.unlink(&bufs); l.unlink(&pool); } WVTEST_MAIN("WvHttpPool pipelining") { WvIStreamList l; unsigned int port = 4200; WvTCPListener *listener; bool search = true; while (search) { listener = new WvTCPListener(port); if (listener->isok()) search = false; else { WVRELEASE(listener); ++port; } } listener->onaccept(wv::bind(listener_callback, &l, _1)); l.append(listener, true, "http listener"); // Pipelining-enabled tests share one connection for the pipeline test // and actual requests. do_test(l, port, 1); WVPASSEQ(http_conns, 1); do_test(l, port, 5); WVPASSEQ(http_conns, 1); break_connection = true; do_test(l, port, 1); WVPASSEQ(http_conns, 2); break_connection = true; do_test(l, port, 5); WVPASSEQ(http_conns, 2); // All pipelining-disabled tests should have one connection for the // pipeline test and one for the real connection. pipelining_enabled = false; do_test(l, port, 1); WVPASSEQ(http_conns, 2); do_test(l, port, 5); WVPASSEQ(http_conns, 2); break_connection = true; do_test(l, port, 1); WVPASSEQ(http_conns, 3); break_connection = true; do_test(l, port, 5); WVPASSEQ(http_conns, 3); WVPASS(listener->isok()); } wvstreams-4.6.1/urlget/wvhttpstream.cc0000644000175000001440000004412311077124114017155 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A fast, easy-to-use, parallelizing, pipelining HTTP/1.1 file retriever. * * See wvhttppool.h. */ #include "wvhttppool.h" #include "wvtcp.h" #include "wvsslstream.h" #include "wvbuf.h" #include "wvbase64.h" #include "strutils.h" #ifdef HAVE_EXECINFO_H #include // FIXME: add a WvCrash feature for explicit dumps #endif #ifdef _WIN32 #define ETIMEDOUT WSAETIMEDOUT #endif WvHttpStream::WvHttpStream(const WvIPPortAddr &_remaddr, WvStringParm _username, bool _ssl, WvIPPortAddrTable &_pipeline_incompatible) : WvUrlStream(_remaddr, _username, WvString("HTTP %s", _remaddr)), pipeline_incompatible(_pipeline_incompatible), in_doneurl(false) { log("Opening server connection.\n"); http_response = ""; encoding = Unknown; bytes_remaining = 0; in_chunk_trailer = false; pipeline_test_count = 0; last_was_pipeline_test = false; enable_pipelining = global_enable_pipelining && !pipeline_incompatible[target.remaddr]; ssl = _ssl; if (ssl) cloned = new WvSSLStream(static_cast(cloned)); sent_url_request = false; alarm(60000); // timeout if no connection, or something goes wrong } WvHttpStream::~WvHttpStream() { log(WvLog::Debug2, "Deleting.\n"); #if 0 #ifdef HAVE_EXECINFO_H void* trace[10]; int count = backtrace(trace, sizeof(trace)/sizeof(trace[0])); char** tracedump = backtrace_symbols(trace, count); log(WvLog::Debug, "TRACE"); for (int i = 0; i < count; ++i) log(WvLog::Debug, ":%s", tracedump[i]); log(WvLog::Debug, "\n"); free(tracedump); #endif #endif if (geterr()) log("Error was: %s\n", errstr()); close(); } void WvHttpStream::close() { log("close called\n"); #if 0 #ifdef HAVE_EXECINFO_H void *trace[10]; int count = backtrace(trace, sizeof(trace)/sizeof(trace[0])); char** tracedump = backtrace_symbols(trace, count); log(WvLog::Debug, "TRACE"); for (int i = 0; i < count; ++i) log(WvLog::Debug, ":%s", tracedump[i]); log(WvLog::Debug, "\n"); free(tracedump); #endif #endif // assume pipelining is broken if we're closing without doing at least // one successful pipelining test and a following non-test request. if (enable_pipelining && max_requests > 1 && (pipeline_test_count < 1 || (pipeline_test_count == 1 && last_was_pipeline_test))) pipelining_is_broken(2); if (isok()) log("Closing.\n"); WvStreamClone::close(); if (geterr()) { // if there was an error, count the first URL as done. This prevents // retrying indefinitely. WvUrlRequest *msgurl = curl; if (!msgurl && !urls.isempty()) msgurl = urls.first(); if (!msgurl && !waiting_urls.isempty()) msgurl = waiting_urls.first(); if (msgurl) { log("URL '%s' is FAILED (%s (%s))\n", msgurl->url, geterr(), errstr()); curl = msgurl; doneurl(); } } waiting_urls.zap(); if (curl) { log("curl is %s\n", curl->url); doneurl(); } log("close done\n"); } void WvHttpStream::doneurl() { // There is a slight chance that we might receive an error during or just before // this function is called, which means that the write occuring during // start_pipeline_test() would be called, which would call close() because of the // error, which would call doneurl() again. We don't want to execute doneurl() // a second time when we're already in the middle. if (in_doneurl) return; in_doneurl = true; assert(curl != NULL); WvString last_response(http_response); log("Done URL: %s\n", curl->url); http_response = ""; encoding = Unknown; in_chunk_trailer = false; bytes_remaining = 0; last_was_pipeline_test = curl->pipeline_test; bool broken = false; if (last_was_pipeline_test) { pipeline_test_count++; if (pipeline_test_count == 1) start_pipeline_test(&curl->url); else if (pipeline_test_response != last_response) { // getting a bit late in the game to be detecting brokenness :( // However, if the response code isn't the same for both tests, // something's definitely screwy. pipelining_is_broken(4); broken = true; } pipeline_test_response = last_response; } assert(curl == urls.first()); curl->done(); curl = NULL; sent_url_request = false; urls.unlink_first(); if (broken) close(); request_next(); in_doneurl = false; } static WvString encode64(WvStringParm user, WvStringParm password) { WvBase64Encoder encoder; WvString ret; encoder.flushstrstr(WvString("%s:%s", user, password), ret); return ret; } static WvString fixnl(WvStringParm nonl) { WvDynBuf b; const char *cptr; for (cptr = nonl; cptr && *cptr; cptr++) { if (*cptr == '\r') continue; else if (*cptr == '\n') b.put("\r", 1); // put BOTH \r and \n b.put(cptr, 1); } return b.getstr(); } WvString WvHttpStream::request_str(WvUrlRequest *url, bool keepalive) { WvString request; WvString auth(""); if(!!url->url.getuser() && !!url->url.getpassword()) auth = WvString("Authorization: Basic %s\n", encode64(url->url.getuser(), url->url.getpassword())); request = fixnl( WvString( "%s %s HTTP/1.1\n" "Host: %s:%s\n" "Connection: %s\n" "%s" "%s" "%s%s" "\n", url->method, url->url.getfile(), url->url.gethost(), url->url.getport(), keepalive ? "keep-alive" : "close", auth, (putstream_data.used() > 0 ? WvString( "Content-Length: %s\n", putstream_data.used()) : ""), trim_string(url->headers.edit()), !!url->headers ? "\n" : "")); return request; } void WvHttpStream::send_request(WvUrlRequest *url) { request_count++; log("Request #%s: %s\n", request_count, url->url); write(request_str(url, url->pipeline_test || request_count < max_requests)); write(putstream_data); sent_url_request = true; alarm(60000); } void WvHttpStream::start_pipeline_test(WvUrl *url) { WvUrl location(WvString( "%s://%s:%s/wvhttp-pipeline-check-should-not-exist/", url->getproto(), url->gethost(), url->getport())); WvUrlRequest *testurl = new WvUrlRequest(location, "HEAD", "", NULL, false, true); testurl->instream = this; send_request(testurl); urls.append(testurl, true, "sent_running_url"); } void WvHttpStream::request_next() { // Clear the putstream buffer before we start any new requests putstream_data.zap(); // don't do a request if we've done too many already or we have none // waiting. if (request_count >= max_requests || waiting_urls.isempty()) return; // don't do more than one request at a time if we're not pipelining. if (!enable_pipelining && !urls.isempty()) return; // okay then, we really do want to send a new request. WvUrlRequest *url = waiting_urls.first(); waiting_urls.unlink_first(); if (!url->putstream) { if (enable_pipelining && !request_count && max_requests > 1) start_pipeline_test(&url->url); send_request(url); } urls.append(url, false, "sent_running_url"); } void WvHttpStream::pipelining_is_broken(int why) { if (!pipeline_incompatible[target.remaddr]) { pipeline_incompatible.add(new WvIPPortAddr(target.remaddr), true); log("Pipelining is broken on this server (%s)! Disabling.\n", why); } } void WvHttpStream::pre_select(SelectInfo &si) { SelectRequest oldwant = si.wants; WvUrlRequest *url; WvUrlStream::pre_select(si); if (!urls.isempty()) { url = urls.first(); if(url && url->putstream) url->putstream->pre_select(si); } si.wants = oldwant; } bool WvHttpStream::post_select(SelectInfo &si) { SelectRequest oldwant = si.wants; WvUrlRequest *url; if (WvUrlStream::post_select(si)) return true; if (!urls.isempty()) { url = urls.first(); if(url && url->putstream && url->putstream->post_select(si)) return true; } si.wants = oldwant; return false; } void WvHttpStream::execute() { char buf[1024], *line; size_t len; WvStreamClone::execute(); // make connections timeout after some idleness if (alarm_was_ticking) { log(WvLog::Debug4, "urls count: %s\n", urls.count()); if (!urls.isempty()) { seterr(ETIMEDOUT); // Must check again here since seterr() // will close our stream and if we only // had one url then it'll be gone. if (!urls.isempty()) { WvUrlRequest *url = urls.first(); if (url->outstream) url->outstream->seterr(ETIMEDOUT); } } else close(); // timed out, but not really an error return; } // Die if somebody closed our outstream. This is so that if we were // downloading a really big file, they can stop it in the middle and // our next url request can start downloading immediately. if (curl && !curl->outstream) { if (!(encoding == PostHeadInfinity || encoding == PostHeadChunked || encoding == PostHeadStream)) { // don't complain about pipelining failures pipeline_test_count++; last_was_pipeline_test = false; close(); } if (curl) doneurl(); return; } else if (curl) curl->inuse = true; if(!sent_url_request && !urls.isempty()) { WvUrlRequest *url = urls.first(); if(url) { if(url->putstream) { int len = 0; if(url->putstream->isok()) len = url->putstream->read(putstream_data, 1024); if(!url->putstream->isok() || len == 0) { url->putstream = NULL; send_request(url); } } } } if (!curl) { // in the header section line = getline(); if (line) { line = trim_string(line); log(WvLog::Debug4, "Header: '%s'\n", line); if (!http_response) { http_response = line; // there are never two pipeline test requests in a row, so // a second response string exactly like the pipeline test // response implies that everything between the first and // second test requests was lost: bad! if (last_was_pipeline_test && http_response == pipeline_test_response) { pipelining_is_broken(1); close(); return; } // http response #400 is "invalid request", which we // shouldn't be sending. If we get one of these right after // a test, it probably means the stuff that came after it // was mangled in some way during transmission ...and we // should throw it away. if (last_was_pipeline_test && !!http_response) { const char *cptr = strchr(http_response, ' '); if (cptr && atoi(cptr+1) == 400) { pipelining_is_broken(3); close(); return; } } } if (urls.isempty()) { log("got unsolicited data.\n"); seterr("unsolicited data from server!"); return; } if (!strncasecmp(line, "Content-length: ", 16)) { bytes_remaining = atoi(line+16); encoding = ContentLength; } else if (!strncasecmp(line, "Transfer-Encoding: ", 19) && strstr(line+19, "chunked")) { encoding = Chunked; } if (line[0]) { char *p; WvBufUrlStream *outstream = urls.first()->outstream; if ((p = strchr(line, ':')) != NULL) { *p = 0; p = trim_string(p+1); if (outstream) { struct WvHTTPHeader *h; h = new struct WvHTTPHeader(line, p); outstream->headers.add(h, true); } } else if (strncasecmp(line, "HTTP/", 5) == 0) { char *p = strchr(line, ' '); if (p) { *p = 0; if (outstream) { outstream->version = line+5; outstream->status = atoi(p+1); } } } } else { // blank line is the beginning of data section curl = urls.first(); in_chunk_trailer = false; log(WvLog::Debug4, "Starting data: %s (enc=%s)\n", bytes_remaining, encoding); if (encoding == Unknown) encoding = Infinity; // go until connection closes itself if (curl->method == "HEAD") { log("Got all headers.\n"); if (!enable_pipelining) doneurl(); if (encoding == Infinity) encoding = PostHeadInfinity; else if (encoding == Chunked) encoding = PostHeadChunked; else encoding = PostHeadStream; } } } } else if (encoding == PostHeadInfinity || encoding == PostHeadChunked || encoding == PostHeadStream) { WvDynBuf chkbuf; len = read(chkbuf, 5); // If there is more data available right away, and it isn't an // HTTP header from another request, then it's a stupid web // server that likes to send bodies with HEAD requests. if (len && strncmp(reinterpret_cast(chkbuf.peek(0, 5)), "HTTP/", 5)) { if (encoding == PostHeadInfinity) encoding = ChuckInfinity; else if (encoding == PostHeadChunked) encoding = ChuckChunked; else if (encoding == PostHeadStream) encoding = ChuckStream; else log(WvLog::Warning, "WvHttpStream: inconsistent state.\n"); } else doneurl(); unread(chkbuf, len); } else if (encoding == ChuckInfinity) { len = read(buf, sizeof(buf)); if (len) log(WvLog::Debug5, "Chucking %s bytes.\n", len); if (!isok()) doneurl(); } else if (encoding == ChuckChunked && !bytes_remaining) { encoding = Chunked; } else if (encoding == ChuckChunked || encoding == ChuckStream) { if (bytes_remaining > sizeof(buf)) len = read(buf, sizeof(buf)); else len = read(buf, bytes_remaining); bytes_remaining -= len; if (len) log(WvLog::Debug5, "Chucked %s bytes (%s bytes left).\n", len, bytes_remaining); if (!bytes_remaining && encoding == ContentLength) doneurl(); if (bytes_remaining && !isok()) seterr("connection interrupted"); } else if (encoding == Chunked && !bytes_remaining) { line = getline(); if (line) { line = trim_string(line); if (in_chunk_trailer) { // in the trailer section of a chunked encoding log(WvLog::Debug4, "Trailer: '%s'\n", line); // a blank line means we're finally done! if (!line[0]) doneurl(); } else { // in the "length line" section of a chunked encoding if (line[0]) { bytes_remaining = (size_t)strtoul(line, NULL, 16); if (!bytes_remaining) in_chunk_trailer = true; log(WvLog::Debug4, "Chunk length is %s ('%s').\n", bytes_remaining, line); } } } } else if (encoding == Infinity) { // just read data until the connection closes, and assume all was // well. It sucks, but there's no way to tell if all the data arrived // okay... that's why Chunked or ContentLength encoding is better. len = read(buf, sizeof(buf)); if (!isok()) return; if (len) log(WvLog::Debug5, "Infinity: read %s bytes.\n", len); if (curl && curl->outstream) curl->outstream->write(buf, len); if (!isok() && curl) doneurl(); } else // not chunked or currently in a chunk - read 'bytes_remaining' bytes. { // in the data section of a chunked or content-length encoding, // with 'bytes_remaining' bytes of data left. if (bytes_remaining > sizeof(buf)) len = read(buf, sizeof(buf)); else len = read(buf, bytes_remaining); if (!isok()) return; bytes_remaining -= len; if (len) log(WvLog::Debug5, "Read %s bytes (%s bytes left).\n", len, bytes_remaining); if (curl && curl->outstream) curl->outstream->write(buf, len); if (!bytes_remaining && encoding == ContentLength && curl) doneurl(); if (bytes_remaining && !isok()) seterr("connection interrupted"); if (!isok()) doneurl(); } if (urls.isempty()) alarm(5000); // just wait a few seconds before closing connection else alarm(60000); // give the server a minute to respond, if we're waiting } wvstreams-4.6.1/urlget/wvhttppool.cc0000644000175000001440000001537111077373056016651 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A fast, easy-to-use, parallelizing, pipelining HTTP/1.1 file retriever. * * See wvhttppool.h. */ #include #include #include "wvhttppool.h" #include "wvbufstream.h" #include "wvtcp.h" #include "strutils.h" bool WvHttpStream::global_enable_pipelining = true; int WvUrlStream::max_requests = 100; unsigned WvHash(const WvUrlStream::Target &n) { WvString key("%s%s", n.remaddr, n.username); return (WvHash(key)); } WvUrlRequest::WvUrlRequest(WvStringParm _url, WvStringParm _method, WvStringParm _headers, WvStream *content_source, bool _create_dirs, bool _pipeline_test) : url(_url), headers(_headers) { instream = NULL; create_dirs = _create_dirs; pipeline_test = _pipeline_test; method = _method; is_dir = false; // for ftp primarily; set later if (pipeline_test) { outstream = NULL; putstream = NULL; } else { WvBufUrlStream *x = new WvBufUrlStream; outstream = x; x->url = url; putstream = content_source; } inuse = false; } WvUrlRequest::~WvUrlRequest() { done(); } void WvUrlRequest::done() { if (outstream) { outstream->seteof(); outstream = NULL; } if (putstream) putstream = NULL; inuse = false; } void WvUrlStream::addurl(WvUrlRequest *url) { log(WvLog::Debug4, "Adding a new url: '%s'\n", url->url); assert(url->outstream); if (!url->url.isok()) return; waiting_urls.append(url, false, "waiting_url"); request_next(); } void WvUrlStream::delurl(WvUrlRequest *url) { log(WvLog::Debug4, "Removing an url: '%s'\n", url->url); if (url == curl) doneurl(); waiting_urls.unlink(url); urls.unlink(url); } WvHttpPool::WvHttpPool() : log("HTTP Pool", WvLog::Debug), conns(10), pipeline_incompatible(50) { log("Pool initializing.\n"); num_streams_created = 0; } WvHttpPool::~WvHttpPool() { log("Created %s individual session%s during this run.\n", num_streams_created, num_streams_created == 1 ? "" : "s"); if (geterr()) log("Error was: %s\n", errstr()); // these must get zapped before the URL list, since they have pointers // to URLs. zap(); conns.zap(); } void WvHttpPool::pre_select(SelectInfo &si) { // log(WvLog::Debug5, "pre_select: main:%s conns:%s urls:%s\n", // count(), conns.count(), urls.count()); WvIStreamList::pre_select(si); WvUrlStreamDict::Iter ci(conns); for (ci.rewind(); ci.next(); ) { if (!ci->isok()) si.msec_timeout = 0; } WvUrlRequestList::Iter i(urls); for (i.rewind(); i.next(); ) { if (!i->instream) { log(WvLog::Debug4, "Checking dns for '%s'\n", i->url.gethost()); if (i->url.resolve()) si.msec_timeout = 0; else dns.pre_select(i->url.gethost(), si); } } } bool WvHttpPool::post_select(SelectInfo &si) { bool sure = false; WvUrlStreamDict::Iter ci(conns); for (ci.rewind(); ci.next(); ) { if (!ci->isok()) { log(WvLog::Debug4, "Selecting true because of a dead stream.\n"); unconnect(ci.ptr()); ci.rewind(); sure = true; } } WvUrlRequestList::Iter i(urls); for (i.rewind(); i.next(); ) { if ((!i->outstream && !i->inuse) || !i->url.isok()) { //log("'%s' is dead: %s/%s\n", // i->url, i->url.isok(), i.outstream->isok()); if (!i->url.isok()) { log("URL not okay: '%s'\n", i->url); i->done(); } // nicely delete the url request WvUrlStream::Target target(i->url.getaddr(), i->url.getuser()); WvUrlStream *s = conns[target]; if (s) s->delurl(i.ptr()); i.xunlink(); continue; } if (!i->instream) { log(WvLog::Debug4, "Checking dns for '%s'\n", i->url.gethost()); if (i->url.resolve() || dns.post_select(i->url.gethost(), si)) { log(WvLog::Debug4, "Selecting true because of '%s'\n", i->url); sure = true; } } } return WvIStreamList::post_select(si) || sure; } void WvHttpPool::execute() { WvIStreamList::execute(); WvUrlRequestList::Iter i(urls); for (i.rewind(); i.next(); ) { WvUrlStream *s; if (!i->outstream || !i->url.isok() || !i->url.resolve()) continue; // skip it for now WvUrlStream::Target target(i->url.getaddr(), i->url.getuser()); //log(WvLog::Info, "remaddr is %s; username is %s\n", target.remaddr, // target.username); s = conns[target]; //if (!s) log("conn for '%s' is not found.\n", ip); if (s && !s->isok()) { unconnect(s); s = NULL; } if (!i->outstream) continue; // unconnect might have caused this URL to be marked bad if (!s) { num_streams_created++; if (!strncasecmp(i->url.getproto(), "http", 4)) s = new WvHttpStream(target.remaddr, target.username, i->url.getproto() == "https", pipeline_incompatible); else if (!strcasecmp(i->url.getproto(), "ftp")) s = new WvFtpStream(target.remaddr, target.username, i->url.getpassword()); conns.add(s, true); // add it to the streamlist, so it can do things append(s, false, "http/ftp stream"); } if (!i->instream) { s->addurl(i.ptr()); i->instream = s; } } } WvBufUrlStream *WvHttpPool::addurl(WvStringParm _url, WvStringParm _method, WvStringParm _headers, WvStream *content_source, bool create_dirs) { log(WvLog::Debug4, "Adding a new url to pool: '%s'\n", _url); WvUrlRequest *url = new WvUrlRequest(_url, _method, _headers, content_source, create_dirs, false); urls.append(url, true, "addurl"); return url->outstream; } void WvHttpPool::unconnect(WvUrlStream *s) { if (!s->target.username) log("Unconnecting stream to %s.\n", s->target.remaddr); else log("Unconnecting stream to %s@%s.\n", s->target.username, s->target.remaddr); WvUrlRequestList::Iter i(urls); for (i.rewind(); i.next(); ) { if (i->instream == s) i->instream = NULL; } unlink(s); conns.remove(s); } wvstreams-4.6.1/Makefile0000644000175000001440000002166611254003232014235 0ustar wlachusersWVSTREAMS:=. include wvrules.mk include install.mk ifdef _WIN32 include win32.mk endif ifdef _SOLARIS RM = rm -f CFLAGS += -DSOLARIS CXXFLAGS += -DSOLARIS else ifdef _MACOS CFLAGS+= -DMACOS CXXFLAGS+= -DMACOS WV_EXCLUDES+= linuxstreams/tests/aliastest linuxstreams/tests/ifctest linuxstreams/tests/routetest qt/tests/qtstringtest TEST_SKIP_OBJS+= linuxstreams/t/% else RM = rm -fv endif endif %: %.subst sed -e 's/#VERSION#/$(WVPACKAGE_VERSION)/g' < $< > $@ ifeq ("$(enable_testgui)", "no") WVTESTRUN=env endif LIBS += -lm ifeq ($(USE_WVSTREAMS_ARGP),1) utils/wvargs.o-CPPFLAGS += -Iargp libwvutils.so-LIBS += -Largp -largp # argp does its own dependency checking, so let's call it once per wvstreams # build, in case some system dependencies have changed and argp should be # recompiled ARGP_TARGET=argp/libargp.list TARGETS += $(ARGP_TARGET) .PHONY: argp/all argp/all: $(MAKE) -C argp # Warning! Crucial! KEEP THIS SEMICOLON HERE! Without it, if you blow away # $(ARGP_TARGET), $(MAKE) will get confused. $(ARGP_TARGET): argp/all; else ARGP_TARGET= endif # # libwvbase: a the minimal code needed to link a wvstreams program. # BASEOBJS = \ utils/wvbuffer.o utils/wvbufferstore.o \ utils/wvcont.o \ utils/wverror.o \ streams/wvfdstream.o \ utils/wvfork.o \ utils/wvhash.o \ utils/wvhashtable.o \ utils/wvlinklist.o \ utils/wvmoniker.o \ utils/wvregex.o \ utils/wvscatterhash.o utils/wvsorter.o \ utils/wvattrs.o \ utils/wvstring.o utils/wvstringlist.o \ utils/wvstringmask.o \ utils/strutils.o \ utils/wvtask.o \ utils/wvtimeutils.o \ streams/wvistreamlist.o \ utils/wvstreamsdebugger.o \ streams/wvlog.o \ streams/wvstream.o \ uniconf/uniconf.o \ uniconf/uniconfgen.o uniconf/uniconfkey.o uniconf/uniconfroot.o \ uniconf/unihashtree.o \ uniconf/unimountgen.o \ uniconf/unitempgen.o \ utils/wvbackslash.o \ utils/wvencoder.o \ utils/wvtclstring.o \ utils/wvstringcache.o \ uniconf/uniinigen.o \ uniconf/unigenhack.o \ uniconf/unilistiter.o \ streams/wvfile.o \ streams/wvstreamclone.o \ streams/wvconstream.o \ utils/wvcrashbase.o \ xplc-cxx/factory.o \ xplc-cxx/getiface.o \ xplc-cxx/strtouuid.o \ xplc-cxx/uuidtostr.o \ xplc-cxx/xplc.o \ xplc/category.o \ xplc/catiter.o \ xplc/catmgr.o \ xplc/loader.o \ xplc/moduleloader.o \ xplc/modulemgr.o \ xplc/monikers.o \ xplc/new.o \ xplc/servmgr.o \ xplc/statichandler.o TARGETS += libwvbase.so libwvbase_OBJS += $(filter-out uniconf/unigenhack.o $(WV_EXCLUDES),$(BASEOBJS)) libwvbase.so: $(libwvbase_OBJS) uniconf/unigenhack.o libwvbase.so-LIBS += $(LIBXPLC) # # libwvutils: handy utility library for C++ # TARGETS += libwvutils.so TESTS += $(call tests_cc,utils/tests) libwvutils_OBJS += $(filter-out $(BASEOBJS) $(TESTOBJS),$(call objects,utils)) libwvutils.so: $(libwvutils_OBJS) $(LIBWVBASE) $(ARGP_TARGET) ifndef _MACOS libwvutils.so-LIBS += -lz -lcrypt $(LIBS_PAM) else libwvutils.so-LIBS += -lz $(LIBS_PAM) endif utils/tests/%: PRELIBS+=$(LIBWVSTREAMS) # # libwvstreams: stream/event handling library # TARGETS += libwvstreams.so TARGETS += crypto/tests/ssltest ipstreams/tests/unixtest TARGETS += crypto/tests/printcert ifndef _MACOS ifneq ("$(with_readline)", "no") TARGETS += ipstreams/tests/wsd ipstreams/tests/wsd-LIBS += -lreadline else TEST_SKIP_OBJS += ipstreams/tests/wsd endif else TEST_SKIP_OBJS += ipstreams/tests/wsd endif TESTS += $(call tests_cc,configfile/tests) TESTS += $(call tests_cc,streams/tests) TESTS += $(call tests_cc,ipstreams/tests) TESTS += $(call tests_cc,crypto/tests) TESTS += $(call tests_cc,urlget/tests) TESTS += $(call tests_cc,linuxstreams/tests) libwvstreams_OBJS += $(filter-out $(BASEOBJS), \ $(call objects,configfile crypto ipstreams \ $(ARCH_SUBDIRS) streams urlget)) libwvstreams.so: $(libwvstreams_OBJS) $(LIBWVUTILS) libwvstreams.so-LIBS += -lz -lssl -lcrypto $(LIBS_PAM) configfile/tests/% streams/tests/% ipstreams/tests/% crypto/tests/% \ urlget/tests/% linuxstreams/tests/%: PRELIBS+=$(LIBWVSTREAMS) # # libuniconf: unified configuration system # TARGETS += libuniconf.so TARGETS += uniconf/daemon/uniconfd uniconf/tests/uni TESTS += $(call tests_cc,uniconf/tests) uniconf/tests/uni libuniconf_OBJS += $(filter-out $(BASEOBJS) uniconf/daemon/uniconfd.o, \ $(call objects,uniconf uniconf/daemon)) libuniconf.so: $(libuniconf_OBJS) $(LIBWVSTREAMS) uniconf/daemon/uniconfd uniconf/tests/uni: $(LIBUNICONF) uniconf/daemon/uniconfd: uniconf/daemon/uniconfd.o $(LIBUNICONF) uniconf/daemon/uniconfd: uniconf/daemon/uniconfd.ini \ uniconf/daemon/uniconfd.8 uniconf/tests/%: PRELIBS+=$(LIBUNICONF) # # libwvdbus: C++ DBus library based on wvstreams # ifneq ("$(with_dbus)", "no") TARGETS += libwvdbus.so TARGETS += dbus/tests/wvdbus dbus/tests/wvdbusd TESTS += $(call tests_cc,dbus/tests) libwvdbus_OBJS += $(call objects,dbus) libwvdbus.so: $(libwvdbus_OBJS) $(LIBWVSTREAMS) libwvdbus.so-LIBS += $(LIBS_DBUS) dbus/tests/wvdbus-LIBS += $(LIBS_DBUS) dbus/tests/wvdbusd-LIBS += $(LIBS_DBUS) dbus/tests/%: PRELIBS+=$(LIBWVDBUS) else TEST_SKIP_OBJS += dbus/t/% endif # # libwvqt: helper library to make WvStreams work better in Qt event loops # This is not made to work with MacOS, so let's not ask it to. ifndef _MACOS ifneq ("$(with_qt)", "no") TARGETS += libwvqt.so TESTS += $(patsubst %.cc,%,$(wildcard qt/tests/*.cc)) libwvqt_OBJS += $(call objects,qt) libwvqt.so: $(libwvqt_OBJS) $(LIBWVSTREAMS) libwvqt.so-LIBS += $(LIBS_QT) qt/tests/%: PRELIBS+=$(LIBWVQT) qt/wvqtstreamclone.o: include/wvqtstreamclone.moc qt/wvqthook.o: include/wvqthook.moc endif endif # # libwvstatic.a: all the wvstreams libraries in one static .a file, to make # it easy to link your programs statically to wvstreams. # TARGETS += libwvstatic.a libwvstatic.a: \ $(libwvbase_OBJS) \ $(libwvutils_OBJS) \ $(libwvstreams_OBJS) \ $(libuniconf_OBJS) \ $(libwvdbus_OBJS) \ $(libwvqt_OBJS) \ uniconf/unigenhack_s.o \ $(ARGP_TARGET) # # libwvtest: the WvTest tools for writing C++ unit tests # TARGETS += wvtestmain.o libwvtest.a TESTOBJS = utils/wvtest.o libwvtest.a: wvtestmain.o $(TESTOBJS) TARGETS_SO = $(filter %.so,$(TARGETS)) TARGETS_A = $(filter %.a,$(TARGETS)) all: config.mk $(filter-out $(WV_EXCLUDES), $(TARGETS)) TESTS += wvtestmain REAL_TESTS = $(filter-out $(TEST_SKIP_OBJS), $(TESTS)) $(addsuffix .o,$(REAL_TESTS)): tests: $(REAL_TESTS) test: all autodep-test tests qtest qtest: all wvtestmain LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):$(shell pwd)" $(WVTESTRUN) $(MAKE) runtests runtests: $(VALGRIND) ./wvtestmain '$(TESTNAME)' ifeq ("$(TESTNAME)", "") cd uniconf/tests && DAEMON=0 ./unitest.sh cd uniconf/tests && DAEMON=1 ./unitest.sh endif TEST_TARGETS = $(filter-out $(TEST_SKIP_OBJS), $(call objects, $(filter-out win32/%, \ $(shell find . -type d -name t | sed 's,^\./,,')))) wvtestmain-LIBS += $(LIBS) $(LIBS_DBUS) wvtestmain: $(TEST_TARGETS) $(LIBWVDBUS) $(LIBUNICONF) $(LIBWVSTREAMS) $(LIBWVTEST) # self test for wvrules.mk autodependencies, since people keep @$@#! breaking # them. autodep-prog: autodep-prog.o autodep-test: rm -f autodep-prog* echo 'int main() { return 0; }' >autodep-prog-stupid.cc ( \ echo '#include "autodep-prog.h"'; \ echo 'int main() { return AUTODEP_VAL; }'; \ ) >autodep-prog.cc echo '#define AUTODEP_VAL 0' >autodep-prog.h $(MAKE) autodep-prog $(MAKE) autodep-prog-stupid if ! ./autodep-prog; then exit 1; fi # should return 0 == ok sleep 1 # ensure timestamp has changed echo '#define AUTODEP_VAL 1' >autodep-prog.h $(MAKE) autodep-prog $(MAKE) autodep-prog-stupid if ./autodep-prog; then exit 1; fi # should return 1 == not-ok rm -f autodep-prog.h sleep 1 # ensure timestamp has changed echo 'int main() { return 0; }' >autodep-prog.cc $(MAKE) autodep-prog # autodep should recover from missing header $(MAKE) autodep-prog-stupid if ! ./autodep-prog; then exit 1; fi # should return 0 == ok rm -f autodep-prog* distclean: clean rm -f uniconf/daemon/uniconfd.8 uniconf/tests/uni rm -f config.mk config.log config.status \ include/wvautoconf.h config.cache \ stamp-h.in rm -rf autom4te.cache rm -rf argp/autom4te.cache rm -rf argp/config.status argp/config.log rm -rf argp/configure.lineno argp/config.h rm -rf argp/Makefile argp/testsuite/Makefile rm -rf argp/testsuite/ex1 argp/testsuite/ex2 argp/testsuite/ex3 rm -rf argp/libargp.a argp/stamp-h1 rm -f pkgconfig/*.pc clean: $(subdirs) @$(RM) .junk $(TARGETS) uniconf/daemon/uniconfd \ $(TESTS) tmp*.ini uniconf/daemon/uniconfd.ini \ .wvtest-total \ $(shell find . -name '*.o' -o -name '.*.d' \ -o -name '*~' -o -name '*.moc') clean-targets: $(RM) $(TARGETS) clean-tests: $(RM) $(TESTS) kdoc: kdoc -f html -d Docs/kdoc-html --name wvstreams --strip-h-path */*.h doxygen: doxygen .PHONY: \ clean distclean \ kdoc doxygen \ install install-shared install-dev uninstall \ tests test debug-make: @echo tests: $(TESTS) @echo real_tests: $(REAL_TESTS) @echo skip_tests: $(TEST_SKIP_OBJS) @echo excluded_items: $(WV_EXCLUDES) @echo targets: $(TARGETS) wvstreams-4.6.1/configure0000755000175000001440000124106411260431130014500 0ustar wlachusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for WvStreams 4.6.1. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='WvStreams' PACKAGE_TARNAME='wvstreams' PACKAGE_VERSION='4.6.1' PACKAGE_STRING='WvStreams 4.6.1' PACKAGE_BUGREPORT='wvstreams-devel@googlegroups.com' ac_unique_file="streams/wvstream.cc" # 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 COMPILER_STANDARD ac_libs LIBS_TCL LIBS_PAM LIBS_QT LIBS_DBUS with_zlib with_tcl with_qt with_readline with_pam with_openssl_policy_mapping with_openssl with_dbus enable_testgui enable_warnings enable_delete_detector enable_resolver_fork enable_optimization enable_debug USE_WVSTREAMS_ARGP SO_VERSION VALGRIND PKGCONFIG LN ALLOCA EGREP GREP OS ARCH_SUBDIRS target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build RANLIB SET_MAKE LN_S INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CXXCPP CPP ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC WEAVER_BUILD_INFO MOC 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_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug enable_fatal_warnings enable_optimization enable_resolver_fork enable_delete_detector enable_warnings enable_testgui with_dbus with_openssl with_pam with_tcl with_qt with_zlib with_valgrind ' ac_precious_vars='build_alias host_alias target_alias MOC WEAVER_BUILD_INFO CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP' # 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_TARNAME}' 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 WvStreams 4.6.1 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/wvstreams] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of WvStreams 4.6.1:";; esac 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] --disable-debug strip debug information --enable-fatal-warnings turn warnings into errors --disable-optimization optimization options --disable-resolver-fork WvResolver background name resolution (debugging) --enable-delete-detector Delete detector (reference counting) --disable-warnings extra warnings --disable-testgui GUI for unit tests Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-dbus DBUS --with-openssl OpenSSL >= 0.9.7 (required) --with-pam PAM --with-tcl Tcl --with-qt Qt --with-zlib zlib (required) --with-valgrind Valgrind Some influential environment variables: MOC Qt meta object compiler WEAVER_BUILD_INFO Extra version info 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 CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP 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 . _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 WvStreams configure 4.6.1 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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 WvStreams $as_me 4.6.1, which was generated by GNU Autoconf 2.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # 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:$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= ;; #( *) $as_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'; { (exit 1); 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 # 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 # 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:$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:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 SO_VERSION=4.6 # append to a variable without introducing superfluous white space QT_SEARCH_PATH=" $prefix /usr $libdir/qt-3.1 $libdir/qt3 $libdir/qt $datadir/qt3 $datadir/qt /usr /usr/lib/qt3 /usr/lib/qt-3.1 /usr/share/qt3 /usr/lib/qt /usr/share/qt " # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; fi # Check whether --enable-fatal-warnings was given. if test "${enable_fatal_warnings+set}" = set; then enableval=$enable_fatal_warnings; fi # Check whether --enable-optimization was given. if test "${enable_optimization+set}" = set; then enableval=$enable_optimization; fi # Check whether --enable-resolver-fork was given. if test "${enable_resolver_fork+set}" = set; then enableval=$enable_resolver_fork; fi # Check whether --enable-delete-detector was given. if test "${enable_delete_detector+set}" = set; then enableval=$enable_delete_detector; fi # Check whether --enable-warnings was given. if test "${enable_warnings+set}" = set; then enableval=$enable_warnings; fi # Check whether --enable-testgui was given. if test "${enable_testgui+set}" = set; then enableval=$enable_testgui; fi # Check whether --with-dbus was given. if test "${with_dbus+set}" = set; then withval=$with_dbus; fi # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then withval=$with_openssl; fi # Check whether --with-pam was given. if test "${with_pam+set}" = set; then withval=$with_pam; fi # Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then withval=$with_tcl; fi # Check whether --with-qt was given. if test "${with_qt+set}" = set; then withval=$with_qt; fi # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then withval=$with_zlib; fi # Check whether --with-valgrind was given. if test "${with_valgrind+set}" = set; then withval=$with_valgrind; fi # avoid autoconf's default values, but keep those the user might have given CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } 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:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # 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_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi 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 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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 ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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 ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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:$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:$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' { $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" 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:$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:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 # Detect target build environment # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 $as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 $as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 $as_echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 $as_echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:$LINENO: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if test "${ac_cv_target+set}" = set; then $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 $as_echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- case "$target" in *-linux*) ARCH_SUBDIRS="linuxstreams" OS="LINUX" ;; *-sunos*|*-solaris*) ARCH_SUBDIRS="" ac_libs="-lstdc++ -lgcc_s -ldl -lm -lc" OS="SOLARIS" ;; *-win*|*-mingw32*) ARCH_SUBDIRS="win32" OS="WIN32" ;; *-apple*) ARCH_SUBDIRS="" OS="MACOS" ;; *) ARCH_SUBDIRS="" OS="OTHER" ;; esac # Detect endianness { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # Check for potential -arch flags. It is not universal unless # there are some -arch flags. Note that *ppc* also matches # ppc64. This check is also rather less than ideal. case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in #( *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to _BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no 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 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; #( no) ;; #( universal) cat >>confdefs.h <<\_ACEOF #define AC_APPLE_UNIVERSAL_BUILD 1 _ACEOF ;; #( *) { { $as_echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 $as_echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac # Look for __attribute__ ((deprecated)) CPPFLAGS_save="$CPPFLAGS" if test -z "$CPPFLAGS"; then CPPFLAGS="-Werror" else CPPFLAGS="$CPPFLAGS -Werror" fi { $as_echo "$as_me:$LINENO: checking for __attribute__ ((deprecated))" >&5 $as_echo_n "checking for __attribute__ ((deprecated))... " >&6; } cat >conftest.$ac_ext <<_ACEOF #include "confdefs.h" void f() __attribute__ ((deprecated)); void f() { } int main() { return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define ATTR_DEPRECATED __attribute__ ((deprecated)) _ACEOF else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF #define ATTR_DEPRECATED /**/ _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CPPFLAGS="$CPPFLAGS_save" # argp USE_WVSTREAMS_ARGP=0 for ac_header in argp.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking for argp_parse" >&5 $as_echo_n "checking for argp_parse... " >&6; } if test "${ac_cv_func_argp_parse+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define argp_parse to an innocuous variant, in case declares argp_parse. For example, HP-UX 11i declares gettimeofday. */ #define argp_parse innocuous_argp_parse /* System header to define __stub macros and hopefully few prototypes, which can conflict with char argp_parse (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef argp_parse /* 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 argp_parse (); /* 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_argp_parse || defined __stub___argp_parse choke me #endif int main () { return argp_parse (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_argp_parse=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_argp_parse=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_argp_parse" >&5 $as_echo "$ac_cv_func_argp_parse" >&6; } if test "$ac_cv_func_argp_parse" != yes \ -o "$ac_cv_header_argp_h" != yes ; then ( echo echo 'configuring argp...' cd argp ./configure --host=$host_cpu-$host_os || exit $? echo 'argp configured.' echo ) || exit $? USE_WVSTREAMS_ARGP=1 fi # Function checks ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:$LINENO: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if test "${ac_cv_search_opendir+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_search_opendir=$ac_res else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:$LINENO: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if test "${ac_cv_search_opendir+set}" = set; then $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_search_opendir=$ac_res else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_working_alloca_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_alloca_works=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF 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 cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 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 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$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 for ac_header in execinfo.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Check for error_t for ac_header in argz.h errno.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking for error_t" >&5 $as_echo_n "checking for error_t... " >&6; } if test "${ac_cv_type_error_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_error_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_ARGZ_H # include #else # if HAVE_ERRNO_H # include # endif #endif int main () { if (sizeof (error_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if HAVE_ARGZ_H # include #else # if HAVE_ERRNO_H # include # endif #endif int main () { if (sizeof ((error_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_error_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_error_t" >&5 $as_echo "$ac_cv_type_error_t" >&6; } if test "x$ac_cv_type_error_t" = x""yes; then : else cat >>confdefs.h <<\_ACEOF #define error_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define __error_t_defined 1 _ACEOF fi # Check for size of ethernet addresses for ac_header in sys/socket.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 net/if.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 net/ethernet.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/if_ether.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_IF_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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:$LINENO: checking whether ETHER_ADDR_LEN is declared" >&5 $as_echo_n "checking whether ETHER_ADDR_LEN is declared... " >&6; } if test "${ac_cv_have_decl_ETHER_ADDR_LEN+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { #ifndef ETHER_ADDR_LEN (void) ETHER_ADDR_LEN; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_ETHER_ADDR_LEN=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_ETHER_ADDR_LEN=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_ETHER_ADDR_LEN" >&5 $as_echo "$ac_cv_have_decl_ETHER_ADDR_LEN" >&6; } if test "x$ac_cv_have_decl_ETHER_ADDR_LEN" = x""yes; then : else { $as_echo "$as_me:$LINENO: checking for ether_addr_t" >&5 $as_echo_n "checking for ether_addr_t... " >&6; } if test "${ac_cv_type_ether_addr_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_ether_addr_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { if (sizeof (ether_addr_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_ETHERNET_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif int main () { if (sizeof ((ether_addr_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_ether_addr_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_ether_addr_t" >&5 $as_echo "$ac_cv_type_ether_addr_t" >&6; } if test "x$ac_cv_type_ether_addr_t" = x""yes; then cat >>confdefs.h <<\_ACEOF #define ETHER_ADDR_LEN sizeof(ether_addr_t) _ACEOF else cat >>confdefs.h <<\_ACEOF #define ETHER_ADDR_LEN 6 _ACEOF fi fi # Check for basic Internet support for ac_header in netdb.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/in.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/in_systm.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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/ip.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IN_SYSTM_H # include #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Check for advanced Linux-style modem support for ac_header in linux/serial.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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_func in cfmakeraw do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 # Detect hard-linking based on LN_S's behaviour { $as_echo "$as_me:$LINENO: checking whether ln works..." >&5 $as_echo_n "checking whether ln works...... " >&6; } case "$LN_S" in ln*) LN='ln' { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } ;; *) LN="$LN_S" { $as_echo "$as_me:$LINENO: result: no, using $LN" >&5 $as_echo "no, using $LN" >&6; } ;; esac # Setting the default language to C++ means that CXX and CXXCPP will be # used for compile tests. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # __libc_stack_end isn't available to shared libraries with some libc versions { $as_echo "$as_me:$LINENO: checking whether __libc_stack_end is public" >&5 $as_echo_n "checking whether __libc_stack_end is public... " >&6; } LDFLAGS_save="$LDFLAGS" if test -z "$LDFLAGS"; then LDFLAGS="-Wl,-z,defs -shared" else LDFLAGS="$LDFLAGS -Wl,-z,defs -shared" fi HAVE_LIBC_STACK_END=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern const void *__libc_stack_end; int main () { volatile const void *x = __libc_stack_end; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then HAVE_LIBC_STACK_END=yes; else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test "$HAVE_LIBC_STACK_END" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBC_STACK_END 1 _ACEOF fi { $as_echo "$as_me:$LINENO: result: $HAVE_LIBC_STACK_END" >&5 $as_echo "$HAVE_LIBC_STACK_END" >&6; } LDFLAGS="$LDFLAGS_save" # Detect pkg-config # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKGCONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. ;; *) 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_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKGCONFIG" && ac_cv_path_PKGCONFIG="no" ;; esac fi PKGCONFIG=$ac_cv_path_PKGCONFIG if test -n "$PKGCONFIG"; then { $as_echo "$as_me:$LINENO: result: $PKGCONFIG" >&5 $as_echo "$PKGCONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKGCONFIG" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: pkg-config is not installed" >&5 $as_echo "$as_me: WARNING: pkg-config is not installed" >&2;} fi if test "$enable_debug" != "no"; then cat >>confdefs.h <<_ACEOF #define VER_STRING_EXTRA " (`whoami`@`hostname`$VER_STRING_EXTRA)" _ACEOF fi # resolver-fork if test "$enable_resolver_fork" = "no"; then cat >>confdefs.h <<\_ACEOF #define WVRESOLVER_SKIP_FORK /**/ _ACEOF fi # xplc delete detector if test "$enable_delete_detector" = "yes"; then cat >>confdefs.h <<\_ACEOF #define ENABLE_DELETE_DETECTOR /**/ _ACEOF fi # dbus if test "$with_dbus" != "no"; then if test "$with_dbus" = "" -o "$with_dbus" = "yes"; then { $as_echo "$as_me:$LINENO: checking Checking that D-Bus version greater than 1.2.14 installed." >&5 $as_echo_n "checking Checking that D-Bus version greater than 1.2.14 installed.... " >&6; } if pkg-config --atleast-version 1.2.14 dbus-1; then if test -z "$CPPFLAGS"; then CPPFLAGS="`pkg-config --cflags dbus-1`" else CPPFLAGS="$CPPFLAGS `pkg-config --cflags dbus-1`" fi if test -z "$LDFLAGS"; then LDFLAGS="`pkg-config --libs-only-L dbus-1`" else LDFLAGS="$LDFLAGS `pkg-config --libs-only-L dbus-1`" fi LIBS_DBUS=`pkg-config --libs-only-l dbus-1` { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else with_dbus=no { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi else # no version check when doing --with-dbus DBUS_LIBDIR=$with_dbus/dbus/.libs if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_dbus" else CPPFLAGS="$CPPFLAGS -I$with_dbus" fi if test -z "$LDFLAGS"; then LDFLAGS="-L$DBUS_LIBDIR" else LDFLAGS="$LDFLAGS -L$DBUS_LIBDIR" fi LIBS_DBUS=-ldbus-1 fi # ... but double check that we actually have D-Bus if test "$with_dbus" != "no"; then OLD_LIBS="$LIBS" if test -z "$LIBS"; then LIBS="$LIBS_DBUS" else LIBS="$LIBS $LIBS_DBUS" fi for ac_header in dbus/dbus.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_dbus=no fi done with_dbus=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern "C" void dbus_message_new(); int main () { dbus_message_new(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then with_dbus= else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$OLD_LIBS fi if test "$with_dbus" != "no"; then cat >>confdefs.h <<\_ACEOF #define WITH_DBUS /**/ _ACEOF fi fi # BSD sockets, if you're on Solaris { $as_echo "$as_me:$LINENO: checking for bind in -lsocket" >&5 $as_echo_n "checking for bind in -lsocket... " >&6; } if test "${ac_cv_lib_socket_bind+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 bind (); int main () { return bind (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_bind=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_bind=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_bind" >&5 $as_echo "$ac_cv_lib_socket_bind" >&6; } if test "x$ac_cv_lib_socket_bind" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi # openssl if test "$with_openssl" != "no"; then if test "$with_openssl" != ""; then if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_openssl/include" else CPPFLAGS="$CPPFLAGS -I$with_openssl/include" fi if test -z "$LDFLAGS"; then LDFLAGS="-L$with_openssl" else LDFLAGS="$LDFLAGS -L$with_openssl" fi fi for ac_header in openssl/ssl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define OPENSSL_NO_KRB5 #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_openssl=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for X509_free in -lcrypto" >&5 $as_echo_n "checking for X509_free in -lcrypto... " >&6; } if test "${ac_cv_lib_crypto_X509_free+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 X509_free (); int main () { return X509_free (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_crypto_X509_free=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypto_X509_free=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_X509_free" >&5 $as_echo "$ac_cv_lib_crypto_X509_free" >&6; } if test "x$ac_cv_lib_crypto_X509_free" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" fi { $as_echo "$as_me:$LINENO: checking for SSL_has_matching_session_id in -lssl" >&5 $as_echo_n "checking for SSL_has_matching_session_id in -lssl... " >&6; } if test "${ac_cv_lib_ssl_SSL_has_matching_session_id+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 SSL_has_matching_session_id (); int main () { return SSL_has_matching_session_id (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ssl_SSL_has_matching_session_id=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ssl_SSL_has_matching_session_id=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_has_matching_session_id" >&5 $as_echo "$ac_cv_lib_ssl_SSL_has_matching_session_id" >&6; } if test "x$ac_cv_lib_ssl_SSL_has_matching_session_id" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else with_openssl=no fi { $as_echo "$as_me:$LINENO: checking for POLICY_MAPPING_new in -lssl" >&5 $as_echo_n "checking for POLICY_MAPPING_new in -lssl... " >&6; } if test "${ac_cv_lib_ssl_POLICY_MAPPING_new+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 POLICY_MAPPING_new (); int main () { return POLICY_MAPPING_new (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ssl_POLICY_MAPPING_new=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ssl_POLICY_MAPPING_new=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_POLICY_MAPPING_new" >&5 $as_echo "$ac_cv_lib_ssl_POLICY_MAPPING_new" >&6; } if test "x$ac_cv_lib_ssl_POLICY_MAPPING_new" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else with_openssl_policy_mapping=no fi if test "$with_openssl_policy_mapping" != "no"; then cat >>confdefs.h <<\_ACEOF #define HAVE_OPENSSL_POLICY_MAPPING 1 _ACEOF fi LIBS="$LIBS_save" if test "$with_openssl" != "no"; then LIBS_SSL="-lcrypto -lssl" fi fi # readline if test "$with_readline" != "no"; then for ac_header in readline/readline.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_readline=no fi done { $as_echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 readline (); int main () { return readline (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_readline_readline=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" else with_readline=no fi fi # pam if test "$with_pam" != "no"; then for ac_header in security/pam_appl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_pam=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if test "${ac_cv_lib_pam_pam_start+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pam_pam_start=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pam_pam_start=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else with_pam=no fi { $as_echo "$as_me:$LINENO: checking for sane PAM implementation" >&5 $as_echo_n "checking for sane PAM implementation... " >&6; } cat >conftest.$ac_ext <<_ACEOF #include "confdefs.h" #if HAVE_SECURITY_PAM_APPL_H # include #endif /* noconv: null PAM conversation function */ int noconv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *userdata) { // if you need to ask things, it won't work return PAM_CONV_ERR; } int main() { struct pam_conv c; c.conv = noconv; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_BROKEN_PAM 0 _ACEOF else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_BROKEN_PAM 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext LIBS="$LIBS_save" if test "$with_pam" != "no" -a "$HAVE_BROKEN_PAM" != "1"; then LIBS_PAM=-lpam fi fi # tcl if test "$with_tcl" != "no"; then CPPFLAGS_save="$CPPFLAGS" if test -z "$CPPFLAGS"; then CPPFLAGS="-I/usr/include/tcl8.3" else CPPFLAGS="$CPPFLAGS -I/usr/include/tcl8.3" fi for ac_header in tcl.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_tcl=no fi done LIBS_save="$LIBS" { $as_echo "$as_me:$LINENO: checking for TclInterpInit in -ltcl8.3" >&5 $as_echo_n "checking for TclInterpInit in -ltcl8.3... " >&6; } if test "${ac_cv_lib_tcl8_3_TclInterpInit+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltcl8.3 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 TclInterpInit (); int main () { return TclInterpInit (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_tcl8_3_TclInterpInit=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tcl8_3_TclInterpInit=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_tcl8_3_TclInterpInit" >&5 $as_echo "$ac_cv_lib_tcl8_3_TclInterpInit" >&6; } if test "x$ac_cv_lib_tcl8_3_TclInterpInit" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBTCL8_3 1 _ACEOF LIBS="-ltcl8.3 $LIBS" else with_tcl=no fi LIBS="$LIBS_save" if test "$with_tcl" != "no"; then CPPFLAGS="$CPPFLAGS_save" LIBS_TCL=-ltcl8.3 fi fi # qt if test "$with_qt" != "no"; then test "$with_qt" = yes && with_qt= { $as_echo "$as_me:$LINENO: checking for Qt" >&5 $as_echo_n "checking for Qt... " >&6; } if test "${wv_cv_with_qt+set}" = set; then $as_echo_n "(cached) " >&6 else wv_cv_with_qt=no CPPFLAGS_save="$CPPFLAGS" LDFLAGS_save="$LDFLAGS" LIBS_save="$LIBS" for wv_qtdir in $with_qt $QTDIR $QT_SEARCH_PATH $(pkg-config --variable=prefix qt-mt); do eval wv_qtdir="$wv_qtdir" CPPFLAGS="$CPPFLAGS_save -I$wv_qtdir/include -I$wv_qtdir/include/qt3" LDFLAGS="$LDFLAGS_save -L$wv_qtdir/lib" LIBS="$LIBS_save -lqt-mt" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { QString x("hello"); return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then wv_cv_with_qt=$wv_qtdir; break else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext done CPPFLAGS="$CPPFLAGS_save" LDFLAGS="$LDFLAGS_save" LIBS="$LIBS_save" fi { $as_echo "$as_me:$LINENO: result: $wv_cv_with_qt" >&5 $as_echo "$wv_cv_with_qt" >&6; } with_qt=$wv_cv_with_qt if test "$with_qt" != no; then if test -z "$CPPFLAGS"; then CPPFLAGS="-I$with_qt/include -I$with_qt/include/qt3" else CPPFLAGS="$CPPFLAGS -I$with_qt/include -I$with_qt/include/qt3" fi if test "$wv_qtdir" != "/usr" ; then # never explicitly include /usr/lib if test -z "$LDFLAGS"; then LDFLAGS="-L$with_qt/lib" else LDFLAGS="$LDFLAGS -L$with_qt/lib" fi fi if test -z "$LIBS_QT"; then LIBS_QT="-lqt-mt" else LIBS_QT="$LIBS_QT -lqt-mt" fi fi # Extract the first word of "moc", so it can be a program name with args. set dummy moc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MOC+set}" = set; then $as_echo_n "(cached) " >&6 else case $MOC in [\\/]* | ?:[\\/]*) ac_cv_path_MOC="$MOC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $with_qt/bin 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_path_MOC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MOC" && ac_cv_path_MOC="moc not found" ;; esac fi MOC=$ac_cv_path_MOC if test -n "$MOC"; then { $as_echo "$as_me:$LINENO: result: $MOC" >&5 $as_echo "$MOC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi # valgrind if test "$with_valgrind" != "no"; then # Extract the first word of "valgrind", so it can be a program name with args. set dummy valgrind; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_VALGRIND+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$VALGRIND"; then ac_cv_prog_VALGRIND="$VALGRIND" # 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_VALGRIND="valgrind" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi VALGRIND=$ac_cv_prog_VALGRIND if test -n "$VALGRIND"; then { $as_echo "$as_me:$LINENO: result: $VALGRIND" >&5 $as_echo "$VALGRIND" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi for ac_header in valgrind/memcheck.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 fi # zlib if test "$with_zlib" != "no"; then for ac_header in zlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else with_zlib=no fi done { $as_echo "$as_me:$LINENO: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } if test "${ac_cv_lib_z_compress+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 compress (); int main () { return compress (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_z_compress=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_compress=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } if test "x$ac_cv_lib_z_compress" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else with_zlib=no fi fi # Find out whether TR1 or Boost are available. for ac_header in tr1/functional do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 boost/function.hpp do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # When compiling with exceptions disabled and Boost, applications need # to provide an "exception handler", declared here. for ac_header in boost/throw_exception.hpp do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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_cxx_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------------------- ## ## Report this to wvstreams-devel@googlegroups.com ## ## ----------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # check for missing packages missing_required= missing_devel= if test "$with_dbus" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: DBUS is missing." >&5 $as_echo "$as_me: WARNING: DBUS is missing." >&2;} missing_devel=yes fi if test "$with_pam" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: PAM is missing." >&5 $as_echo "$as_me: WARNING: PAM is missing." >&2;} missing_devel=yes fi if test "$with_qt" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: Qt is missing." >&5 $as_echo "$as_me: WARNING: Qt is missing." >&2;} missing_devel=yes fi if test "$VALGRIND" = ""; then { $as_echo "$as_me:$LINENO: WARNING: Valgrind is missing." >&5 $as_echo "$as_me: WARNING: Valgrind is missing." >&2;} fi if test "$with_openssl" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: OpenSSL is missing." >&5 $as_echo "$as_me: WARNING: OpenSSL is missing." >&2;} missing_required="$missing_required OpenSSL>=0.9.7" fi if test "$with_readline" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: readline is missing." >&5 $as_echo "$as_me: WARNING: readline is missing." >&2;} fi if test "$with_zlib" = "no"; then { $as_echo "$as_me:$LINENO: WARNING: zlib is missing." >&5 $as_echo "$as_me: WARNING: zlib is missing." >&2;} missing_required="$missing_required zlib" fi if test "$ac_cv_header_tr1_functional" != "yes" \ -a "$ac_cv_header_boost_function_hpp" != "yes"; then { $as_echo "$as_me:$LINENO: WARNING: both tr1/functional and boost/function.hpp are missing." >&5 $as_echo "$as_me: WARNING: both tr1/functional and boost/function.hpp are missing." >&2;} missing_required="$missing_required boost/function.hpp" fi if test -n "$missing_required"; then { { $as_echo "$as_me:$LINENO: error: Required dependencies missing:$missing_required" >&5 $as_echo "$as_me: error: Required dependencies missing:$missing_required" >&2;} { (exit 1); exit 1; }; } fi if test "$VALGRIND" != ""; then VALGRIND="valgrind --tool=memcheck --leak-check=yes --num-callers=10 --suppressions=\$(WVSTREAMS_SRC)/wvstreams.supp" if valgrind --help | grep log-file >/dev/null; then VALGRIND="$VALGRIND --log-file=valgrind.log" else VALGRIND="$VALGRIND --logfile=valgrind.log" fi fi # Compiler is always posix if invoking this configure script COMPILER_STANDARD=posix cat >>confdefs.h <<_ACEOF #define VERBOSE_PACKAGE_VERSION "$PACKAGE_VERSION$WEAVER_BUILD_INFO" _ACEOF ac_config_files="$ac_config_files config.mk" ac_config_files="$ac_config_files pkgconfig/libuniconf.pc pkgconfig/libuniconf-uninstalled.pc pkgconfig/libwvbase.pc pkgconfig/libwvbase-uninstalled.pc pkgconfig/libwvdbus.pc pkgconfig/libwvdbus-uninstalled.pc pkgconfig/libwvqt.pc pkgconfig/libwvqt-uninstalled.pc pkgconfig/libwvstreams.pc pkgconfig/libwvstreams-uninstalled.pc pkgconfig/libwvutils.pc pkgconfig/libwvutils-uninstalled.pc pkgconfig/libwvtest.pc pkgconfig/libwvtest-uninstalled.pc" ac_config_headers="$ac_config_headers include/wvautoconf.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:$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= ;; #( *) $as_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:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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 # 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 WvStreams $as_me 4.6.1, which was generated by GNU Autoconf 2.63. 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 from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ WvStreams config.status 4.6.1 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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 CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; "pkgconfig/libuniconf.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libuniconf.pc" ;; "pkgconfig/libuniconf-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libuniconf-uninstalled.pc" ;; "pkgconfig/libwvbase.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvbase.pc" ;; "pkgconfig/libwvbase-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvbase-uninstalled.pc" ;; "pkgconfig/libwvdbus.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvdbus.pc" ;; "pkgconfig/libwvdbus-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvdbus-uninstalled.pc" ;; "pkgconfig/libwvqt.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvqt.pc" ;; "pkgconfig/libwvqt-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvqt-uninstalled.pc" ;; "pkgconfig/libwvstreams.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvstreams.pc" ;; "pkgconfig/libwvstreams-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvstreams-uninstalled.pc" ;; "pkgconfig/libwvutils.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvutils.pc" ;; "pkgconfig/libwvutils-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvutils-uninstalled.pc" ;; "pkgconfig/libwvtest.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvtest.pc" ;; "pkgconfig/libwvtest-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES pkgconfig/libwvtest-uninstalled.pc" ;; "include/wvautoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS include/wvautoconf.h" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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 '{ (exit 1); 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_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _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_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } fi ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # Now convert PACKAGE_* macros into WVPACKAGE_* in include/wvautoconf.h sed 's,\(\#define.*\)PACKAGE,\1WVPACKAGE,' include/wvautoconf.h > include/wvautoconf.h.new if test "x$?" = "x0"; then if ! diff include/wvautoconf.h include/wvautoconf.h.new >/dev/null; then mv include/wvautoconf.h.new include/wvautoconf.h else rm include/wvautoconf.h.new fi fi wvstreams-4.6.1/autogen.sh0000755000175000001440000000007311253746065014604 0ustar wlachusers#!/bin/sh set -e autoheader autoconf (cd argp && autoconf) wvstreams-4.6.1/linuxstreams/0000755000175000001440000000000011260431126015324 5ustar wlachuserswvstreams-4.6.1/linuxstreams/if_tun.h0000644000175000001440000000376711036722347017007 0ustar wlachusers/* * Universal TUN/TAP device driver. * Copyright (C) 1999-2000 Maxim Krasnyansky * * 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. * */ #ifndef __IF_TUN_H #define __IF_TUN_H /* Uncomment to enable debugging */ /* #define TUN_DEBUG 1 */ #ifdef __KERNEL__ #ifdef TUN_DEBUG #define DBG if(tun->debug)printk #define DBG1 if(debug==2)printk #else #define DBG( a... ) #define DBG1( a... ) #endif struct tun_struct { char *name; unsigned long flags; int attached; uid_t owner; wait_queue_head_t read_wait; struct sk_buff_head readq; struct net_device dev; struct net_device_stats stats; struct fasync_struct *fasync; #ifdef TUN_DEBUG int debug; #endif }; #ifndef MIN #define MIN(a,b) ( (a)<(b) ? (a):(b) ) #endif #endif /* __KERNEL__ */ /* Read queue size */ #define TUN_READQ_SIZE 10 /* TUN device flags */ #define TUN_TUN_DEV 0x0001 #define TUN_TAP_DEV 0x0002 #define TUN_TYPE_MASK 0x000f #define TUN_FASYNC 0x0010 #define TUN_NOCHECKSUM 0x0020 #define TUN_NO_PI 0x0040 #define TUN_ONE_QUEUE 0x0080 #define TUN_PERSIST 0x0100 /* Ioctl defines */ #define TUNSETNOCSUM _IOW('T', 200, int) #define TUNSETDEBUG _IOW('T', 201, int) #define TUNSETIFF _IOW('T', 202, int) #define TUNSETPERSIST _IOW('T', 203, int) #define TUNSETOWNER _IOW('T', 204, int) /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 #define IFF_NO_PI 0x1000 #define IFF_ONE_QUEUE 0x2000 struct tun_pi { unsigned short flags; unsigned short proto; }; #define TUN_PKT_STRIP 0x0001 #endif /* __IF_TUN_H */ wvstreams-4.6.1/linuxstreams/tests/0000755000175000001440000000000011260431126016466 5ustar wlachuserswvstreams-4.6.1/linuxstreams/tests/ifctest.cc0000644000175000001440000000073411036722347020453 0ustar wlachusers#include "wvinterface.h" int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: %s \n", argv[0]); return 1; } WvInterface ifc(argv[1]); wvcon->print("exists: %s\n" "IP: %s\n" "dst: %s\n" "hwaddr: %s\n" "flags: %s\n" "up: %s\n" "promisc: %s\n" "arp: %s\n", ifc.valid, ifc.ipaddr(), ifc.dstaddr(), ifc.hwaddr(), ifc.getflags(), ifc.isup(), ifc.ispromisc(), ifc.isarp()); return 0; } wvstreams-4.6.1/linuxstreams/tests/routetest.cc0000644000175000001440000000203111036722347021040 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPRoute test. Gets the kernel routing table, adds some new routes, and * writes the table. * */ #include "wviproute.h" #include "wvlog.h" int main() { WvLog l("test"); WvIPRouteList r; WvIPRouteList::Iter i(r); WvIPRoute *rr; r.get_kernel(); for (i.rewind(); i.next(); ) l("%s\n", i()); WvIPAddr a("192.168.42.22"); rr = r.find(a); if (rr) l("\n%s through:\n %s\n", a, *r.find(a)); WvIPAddr b("1.2.3.4"); rr = r.find(b); if (rr) l("\n%s through:\n %s\n", b, *r.find(b)); l("Check point.\n"); WvIPRouteList r2; r2.append(new WvIPRoute("eth1", WvIPNet("24.112.104.0/255.255.252.0"), "0", 5, "default"), true); r2.append(new WvIPRoute("eth0", WvIPNet("192.168.42.4/24"), "0", 0, "default"), true); r2.append(new WvIPRoute("eth1", WvIPNet("0.0.0.0/0"), "24.112.104.1", 1, "default"), true); r2.set_kernel(); } wvstreams-4.6.1/linuxstreams/tests/aliastest.cc0000644000175000001440000000110311036722347020772 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPAliaser test program. * */ #include "wvipaliaser.h" int main() { free(malloc(1)); WvIPAliaser a, b; a.start_edit(); a.add("1.2.3.4"); b.start_edit(); a.add("1.2.3.4"); b.add("2.4.6.5"); b.add("3.4.5.6"); b.add("1.2.3.4"); b.done_edit(); a.done_edit(); a.dump(); b.dump(); a.start_edit(); a.add("1.2.3.5"); a.add("1.2.3.6"); a.done_edit(); a.dump(); b.dump(); return 0; } wvstreams-4.6.1/linuxstreams/t/0000755000175000001440000000000011260431126015567 5ustar wlachuserswvstreams-4.6.1/linuxstreams/t/wvpty.t.cc0000644000175000001440000000143011036722347017540 0ustar wlachusers#include "wvpty.h" #include "wvpipe.h" #include "wvistreamlist.h" #include "wvtest.h" WVTEST_MAIN("stty") { const char *argv[] = { "stty", NULL }; { WvIStreamList l; WvPty pty(argv[0], argv); pty.autoforward(*wvout); l.append(&pty, false, "pty"); while (!pty.child_exited() || pty.isok()) { printf("runonce\n"); l.runonce(100); } WVPASS("process exited"); // pty is a tty! exit code should show success. WVPASSEQ(pty.finish(), 0); } { WvIStreamList l; WvPipe pipe(argv[0], argv, true, true, true); pipe.autoforward(*wvout); l.append(&pipe, false, "pipe"); while (!pipe.child_exited() || pipe.isok()) { printf("runonce\n"); l.runonce(100); } // pipe is not a tty. exit code should show failure. WVFAILEQ(pipe.finish(), 0); } } wvstreams-4.6.1/linuxstreams/wvipaliaser.cc0000644000175000001440000000737611036722347020207 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPAliaser handles IP aliasing in the Linux kernel. See wvipaliaser.h. */ #include "wvipaliaser.h" #include "wvinterface.h" #include WvIPAliaser::AliasList WvIPAliaser::all_aliases; ///////////////////////////////////// WvIPAliaser::Alias WvIPAliaser::Alias::Alias(const WvIPAddr &_ip) : ip(_ip) { WvIPAddr noip; WvIPNet nonet(noip, noip); link_count = 0; for (index = 0; index < 256; index++) { WvInterface i(WvString("lo:wv%s", index)); if (!i.isup() || i.ipaddr() == nonet) // not in use yet! { i.setipaddr(ip); i.up(true); if (WvIPAddr(i.ipaddr()) != ip) { // no permission, most likely. index = -1; i.up(false); } return; } if (i.isup() && WvIPNet(i.ipaddr(),32) == ip) { // a bit weird... this alias already has the right address. // Keep it. return; } } // got through all possible names without a free one? Weird! index = -1; } WvIPAliaser::Alias::~Alias() { if (index >= 0) { WvInterface i(WvString("lo:wv%s", index)); // i.setipaddr(WvIPAddr()); // not necessary in recent kernels i.up(false); } } //////////////////////////////////// WvIPAliaser WvIPAliaser::WvIPAliaser() : interfaces() { // nothing to do } WvIPAliaser::~WvIPAliaser() { // clear the alias list start_edit(); done_edit(); } void WvIPAliaser::start_edit() { AliasList::Iter i(aliases); #ifndef NDEBUG AliasList::Iter i_all(all_aliases); #endif interfaces.update(); for (i.rewind(); i.next(); ) { assert(i_all.find(i.ptr())); // the global alias entry goes down by one i().link_count--; } // empty out the local list aliases.zap(); } WvIPAliaser::Alias *WvIPAliaser::ipsearch(WvIPAliaser::AliasList &l, const WvIPAddr &ip) { AliasList::Iter i(l); for (i.rewind(); i.next(); ) { if (i->ip == WvIPAddr(ip)) return i.ptr(); } return NULL; } bool WvIPAliaser::add(const WvIPAddr &ip) { Alias *a; if (WvIPAddr(ip) == WvIPAddr() || ipsearch(aliases, ip)) return false; // already done. // If the alias is already a local address, there is no need for an alias. // We have to be careful that we don't find an existing alias as the // local interface. Otherwise, we'll toggle that alias on and off. WvString ifc(interfaces.islocal(WvIPAddr(ip))); if (!!ifc && !strchr(ifc, ':')) // Make sure it is a real interface return false; a = ipsearch(all_aliases, ip); if (a) { // It's already in the global list, so we add its entry to // our list and increase the link count. aliases.append(a, false); a->link_count++; return false; } else { // It's not there, so we add a new alias to the global list and // our local list. a = new Alias(ip); aliases.append(a, false); all_aliases.append(a, true); a->link_count++; return true; } } bool WvIPAliaser::done_edit() { bool any_change=false; AliasList::Iter i(all_aliases); i.rewind(); i.next(); while (i.cur()) { Alias &a = *i; if (!a.link_count) { i.unlink(); any_change = true; } else i.next(); } return any_change; } void WvIPAliaser::dump() { { WvLog log("local aliases"); AliasList::Iter i(aliases); for (i.rewind(); i.next(); ) { Alias &a = *i; log("#%s = lo:wv%s: %s (%s links)\n", a.index, a.index, a.ip, a.link_count); } log(".\n"); } { WvLog log("global aliases"); AliasList::Iter i(all_aliases); for (i.rewind(); i.next(); ) { Alias &a = *i; log("#%s = lo:wv%s: %s (%s links)\n", a.index, a.index, a.ip, a.link_count); } log(".\n.\n"); } } wvstreams-4.6.1/linuxstreams/wvinterface.cc0000644000175000001440000004436511036722347020175 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A WvInterface stores information about a particular network interface. */ #include "wvinterface.h" #if 1 // FIXME: this file doesn't compile on anything other than Linux #include "wvsubproc.h" #include "wvfile.h" #include #include #include #include #include #include #include #include #define _LINUX_IF_H /* Hack to prevent loading linux/if.h */ #include #define min(x,y) ({ \ const typeof(x) _x = (x); \ const typeof(y) _y = (y); \ (void) (&_x == &_y); \ _x < _y ? _x : _y; }) WvInterfaceDictBase WvInterfaceDict::slist(15); int WvInterfaceDict::links = 0; WvInterface::WvInterface(WvStringParm _name) : err("Net Interface", WvLog::Error), name(_name) { my_hwaddr = my_ipaddr = NULL; valid = true; } WvInterface::~WvInterface() { rescan(); } int WvInterface::req(int ioctl_num, struct ifreq *ifr) { int sock, retval; sock = socket(AF_INET, SOCK_STREAM, 0); strncpy(ifr->ifr_name, name, IFNAMSIZ-1); ifr->ifr_name[IFNAMSIZ-1] = 0; retval = ioctl(sock, ioctl_num, ifr); if (retval == -1) retval = errno; close(sock); return retval; } // For Wireless Interfaces... int WvInterface::req(int ioctl_num, struct iwreq *ifr) { int sock, retval; sock = socket(AF_INET, SOCK_STREAM, 0); strncpy(ifr->ifr_name, name, IFNAMSIZ-1); ifr->ifr_name[IFNAMSIZ-1] = 0; retval = ioctl(sock, ioctl_num, ifr); if (retval) retval = errno; close(sock); return retval; } // forget all stored information about the address(es) of this interface void WvInterface::rescan() { if (my_hwaddr) { delete my_hwaddr; my_hwaddr = NULL; } if (my_ipaddr) { delete my_ipaddr; my_ipaddr = NULL; } } // get the hardware address of this interface const WvAddr &WvInterface::hwaddr() { struct ifreq ifr; if (!my_hwaddr) { if (req(SIOCGIFHWADDR, &ifr)) my_hwaddr = new WvStringAddr("Unknown", WvEncap::Unknown); else my_hwaddr = WvAddr::gen(&ifr.ifr_hwaddr); } return *my_hwaddr; } // get the local IP net of this interface const WvIPNet &WvInterface::ipaddr() { struct ifreq ifr, ifr2; if (!my_ipaddr) { ifr.ifr_addr.sa_family = AF_INET; ifr2.ifr_netmask.sa_family = AF_INET; if (req(SIOCGIFADDR, &ifr) || req(SIOCGIFNETMASK, &ifr2)) my_ipaddr = new WvIPNet(); else my_ipaddr = new WvIPNet(&ifr.ifr_addr, &ifr2.ifr_netmask); } return *my_ipaddr; } // get the point-to-point IP address of this interface const WvIPAddr WvInterface::dstaddr() { struct ifreq ifr; ifr.ifr_dstaddr.sa_family = AF_INET; if (!(getflags() & IFF_POINTOPOINT) || req(SIOCGIFDSTADDR, &ifr)) return WvIPAddr(); else return WvIPAddr(&ifr.ifr_dstaddr); } int WvInterface::getflags() { struct ifreq ifr; int retval = req(SIOCGIFFLAGS, &ifr); if (retval) valid = false; return retval? 0: ifr.ifr_flags; } int WvInterface::setflags(int clear, int set) { struct ifreq ifr; int retval = req(SIOCGIFFLAGS, &ifr); if (retval) return retval; int newflags = (ifr.ifr_flags & ~clear) | set; if (newflags != ifr.ifr_flags) { ifr.ifr_flags = newflags; retval = req(SIOCSIFFLAGS, &ifr); if (retval && retval != EACCES && retval != EPERM) err.perror(WvString("SetFlags %s", name)); } return retval; } void WvInterface::up(bool enable) { setflags(IFF_UP, enable ? IFF_UP : 0); rescan(); } bool WvInterface::isup() { return (valid && (getflags() & IFF_UP)) ? 1 : 0; } void WvInterface::promisc(bool enable) { setflags(IFF_PROMISC, enable ? IFF_PROMISC : 0); } int WvInterface::ptp(bool enable, const WvIPNet &addr) { struct ifreq ifr; sockaddr *saddr = addr.sockaddr(); memcpy(&ifr.ifr_dstaddr, saddr, addr.sockaddr_len()); int retval = req(SIOCSIFDSTADDR, &ifr); if (retval && retval != EACCES && retval != EPERM) { err.perror(WvString("Set PointoPoint %s", name)); return retval; } return setflags(IFF_POINTOPOINT, enable ? IFF_POINTOPOINT : 0); } bool WvInterface::ispromisc() { return (getflags() & IFF_PROMISC) ? 1 : 0; } int WvInterface::setipaddr(const WvIPNet &addr) { struct ifreq ifr; struct sockaddr *sa; size_t len; int sock; WvIPAddr none; if (addr != ipaddr()) err(WvLog::Info, "Changing %s address to %s (%s bits)\n", name, addr.base(), addr.bits()); sock = socket(AF_INET, SOCK_STREAM, 0); strncpy(ifr.ifr_name, name, IFNAMSIZ-1); ifr.ifr_name[IFNAMSIZ-1] = 0; ifr.ifr_addr.sa_family = AF_INET; len = min(sizeof(sockaddr), addr.sockaddr_len()); sa = addr.sockaddr(); memcpy(&ifr.ifr_addr, sa, len); delete sa; if (ioctl(sock, SIOCSIFADDR, &ifr)) { if (errno != EACCES && errno != EPERM) err.perror(WvString("SetIfAddress %s", name)); close(sock); return -1; } // 2.1 kernels error when we try to change netmask/broadcast for // a 0.0.0.0 address. if (addr.base() != none) { sa = addr.netmask().sockaddr(); memcpy(&ifr.ifr_netmask, sa, len); delete sa; if (ioctl(sock, SIOCSIFNETMASK, &ifr)) { if (errno != EACCES && errno != EPERM) err.perror(WvString("SetNetmask %s", name)); close(sock); return -1; } if (!strchr(name, ':')) // otherwise, an alias, and no broadcast addr! { sa = addr.broadcast().sockaddr(); memcpy(&ifr.ifr_broadaddr, sa, len); delete sa; if (ioctl(sock, SIOCSIFBRDADDR, &ifr)) { if (errno != EACCES && errno != EPERM) err.perror(WvString("SetBroadcast %s", name)); close(sock); return -1; } } } // addroute(addr); // not necessary on 2.1 and higher kernels close(sock); rescan(); return 0; } int WvInterface::setmtu(int mtu) { struct ifreq ifr; ifr.ifr_mtu = mtu; int retval = req(SIOCSIFMTU, &ifr); if (retval && retval != EACCES && retval != EPERM) err.perror(WvString("SetMTU %s", name)); return retval; } int WvInterface::sethwaddr(const WvAddr &addr) { struct ifreq ifr; sockaddr *saddr = addr.sockaddr(); memcpy(& ifr.ifr_hwaddr, saddr, addr.sockaddr_len()); delete saddr; bool wasup = isup(); if (wasup) up(false); int retval = req(SIOCSIFHWADDR, &ifr); if (retval && retval != EACCES && retval != EPERM) err.perror(WvString("SetHWAddr %s", name)); if (wasup) up(true); rescan(); return retval; } // Fill a routing table entry with the given information. void WvInterface::fill_rte(struct rtentry *rte, char ifname[17], const WvIPNet &dest, const WvIPAddr &gw, int metric) { struct sockaddr *net, *mask, *gwaddr; size_t len; bool is_direct = (gw == WvIPAddr()); bool is_host = dest.is_host(); memset(rte, 0, sizeof(struct rtentry)); rte->rt_metric = metric + 1; strncpy(ifname, name, 17); ifname[17-1] = 0; rte->rt_dev = ifname; len = min(sizeof(sockaddr), dest.sockaddr_len()); net = dest.network().sockaddr(); memcpy(&rte->rt_dst, net, len); delete net; if (!is_host) { mask = dest.netmask().sockaddr(); memcpy(&rte->rt_genmask, mask, len); delete mask; } if (!is_direct) { gwaddr = gw.sockaddr(); memcpy(&rte->rt_gateway, gwaddr, len); delete gwaddr; } rte->rt_flags = (RTF_UP | (is_host ? RTF_HOST : 0) | (is_direct ? 0 : RTF_GATEWAY)); } int WvInterface::really_addroute(const WvIPNet &dest, const WvIPAddr &gw, const WvIPAddr &src, int metric, WvStringParm table, bool shutup) { struct rtentry rte; char ifname[17]; int sock; WvString deststr(dest), gwstr(gw), metr(metric), srcstr(src); // FIXME: There has got to be a better way to do this. const char * const argvnosrc[] = { "ip", "route", "add", deststr, "table", table, "dev", name, "via", gwstr, "metric", metr, NULL }; const char * const argvsrc[] = { "ip", "route", "add", deststr, "table", table, "dev", name, "via", gwstr, "src", srcstr, "metric", metr, NULL }; WvIPAddr zero; const char * const * argv; if (src != zero) argv = argvsrc; else argv = argvnosrc; if (dest.is_default() || table != "default") { err(WvLog::Debug2, "addroute: "); for (int i = 0; argv[i]; i++) err(WvLog::Debug2, "%s ", argv[i]); err(WvLog::Debug2, "\n"); WvSubProc checkProc; checkProc.startv(*argv, argv); checkProc.wait(-1); //if (WvPipe(argv[0], argv, false, false, false).finish() != 242) if (checkProc.estatus != 242) { // added a default route via the subprogram // 242 is the magic "WvPipe could not exec program..." exit code. return 0; } } // if we get here, it is not a default route or the 'ip' command is // broken somehow. fill_rte(&rte, ifname, dest, gw, metric); sock = socket(AF_INET, SOCK_STREAM, 0); if (ioctl(sock, SIOCADDRT, &rte)) { if (errno != EACCES && errno != EPERM && errno != EEXIST && errno != ENOENT) { if (!shutup) err.perror(WvString("AddRoute '%s' %s (up=%s)", name, dest, isup())); } close(sock); return -1; } close(sock); return 0; } int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw, const WvIPAddr &src, int metric, WvStringParm table) { WvIPAddr zero; int ret; // The kernel (2.4.19) sometimes tries to protect us from ourselves by // not letting us create a route via 'x' if 'x' isn't directly reachable // on the same interface. This is non-helpful to us in some cases, // particularly with FreeSwan's screwy lying kernel routes. Anyway, // the kernel people weren't clever enough to check that the routing // table *stays* self-consistent, so we add an extra route, then we // create our real route, and then we delete the extra route again. // Blah. // // Using metric 255 should make it not the same as any other route. if (gw != zero) really_addroute(gw, zero, zero, 255, "default", true); ret = really_addroute(dest, gw, src, metric, table, false); if (gw != zero) delroute(gw, zero, 255, "default"); return ret; } // add a route with no gateway, ie. direct to interface int WvInterface::addroute(const WvIPNet &dest, int metric, WvStringParm table) { return addroute(dest, WvIPAddr(), WvIPAddr(), metric, table); } int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw, int metric, WvStringParm table) { struct rtentry rte; char ifname[17]; int sock; WvString deststr(dest), gwstr(gw), metr(metric); const char *argv[] = { "ip", "route", "del", deststr, "table", table, "dev", name, "via", gwstr, "metric", metr, NULL }; if (dest.is_default() || table != "default") { err(WvLog::Debug2, "delroute: "); for (int i = 0; argv[i]; i++) err(WvLog::Debug2, "%s ", argv[i]); err(WvLog::Debug2, "\n"); WvSubProc checkProc; checkProc.startv(*argv, (char * const *)argv); checkProc.wait(-1); //if (WvPipe(argv[0], argv, false, false, false).finish() == 0) if (!WEXITSTATUS(checkProc.estatus)) { // successfully deleted a default route via the subprogram return 0; } } fill_rte(&rte, ifname, dest, gw, metric); sock = socket(AF_INET, SOCK_STREAM, 0); if (ioctl(sock, SIOCDELRT, &rte)) { if (errno != EACCES && errno != EPERM && errno != EEXIST) err.perror(WvString("DelRoute %s", name)); close(sock); return -1; } close(sock); return 0; } // delete a route with no gateway, ie. direct to interface int WvInterface::delroute(const WvIPNet &dest, int metric, WvStringParm table) { return delroute(dest, WvIPAddr(), metric, table); } // add an ARP or proxy ARP entry on this interface int WvInterface::addarp(const WvIPNet &dest, const WvAddr &hw, bool proxy) { int sock; struct arpreq ar; struct sockaddr *sa; size_t len; sa = dest.network().sockaddr(); len = min(dest.sockaddr_len(), sizeof(ar.arp_pa)); memcpy(&ar.arp_pa, sa, len); delete sa; sa = hw.sockaddr(); len = min(hw.sockaddr_len(), sizeof(ar.arp_ha)); memcpy(&ar.arp_ha, sa, len); delete sa; sa = dest.netmask().sockaddr(); len = min(dest.sockaddr_len(), sizeof(ar.arp_netmask)); memcpy(&ar.arp_netmask, sa, len); delete sa; strncpy(ar.arp_dev, name, sizeof(ar.arp_dev)); ar.arp_flags = (ATF_COM | ATF_PERM | (proxy ? ATF_PUBL : 0) | (proxy && dest.is_host() ? ATF_NETMASK : 0)); sock = socket(AF_INET, SOCK_STREAM, 0); if (ioctl(sock, SIOCSARP, &ar)) { if (errno != EACCES && errno != EPERM) err.perror(WvString("AddARP %s", name)); close(sock); return -1; } close(sock); return 0; } bool WvInterface::isarp() { int f = getflags(); return !(f & (IFF_NOARP | IFF_LOOPBACK)) && (f & IFF_BROADCAST); } static char *find_ifname(char *line) { if (!line) return NULL; // skip leading whitespace while (*line==' ') line++; // everything before the last colon is the device name char *cptr = strrchr(line, ':'); if (!cptr) return NULL; *cptr = 0; return line; } ////////////////////////////////////////////// WvInterfaceDict WvInterfaceDict::WvInterfaceDict() : log("Net Interface", WvLog::Info) { links++; update(); } WvInterfaceDict::~WvInterfaceDict() { links--; if (!links) slist.zap(); } // auto-fill the list of interfaces using the list from /proc/net/dev. // // I wish there was a better way to do this, but the SIOCGIFCONF ioctl // ignores 'down' interfaces, which is not what we want. // void WvInterfaceDict::update() { int sock; struct ifconf ifconf; char buf[sizeof(ifconf.ifc_req) * 100]; // room for 100 interfaces WvLog err(log.split(WvLog::Error)); WvFile procdev("/proc/net/dev", O_RDONLY); char *ifname; // mark all interfaces in list invalid for now Iter i(*this); for (i.rewind(); i.next(); ) i().valid = false; // get list of all non-aliased interfaces from /proc/net/dev // skip the two header lines procdev.blocking_getline(-1); procdev.blocking_getline(-1); // add/validate existing interfaces while ((ifname = find_ifname(procdev.blocking_getline(-1))) != NULL) { WvString s(ifname); WvInterface *ifc = (*this)[s]; if (!ifc) { ifc = new WvInterface(ifname); slist.add(ifc, true); log(WvLog::Debug3, "Found %-16s [%s]\n", ifname, ifc->hwaddr()); } else ifc->rescan(); ifc->valid = true; } // get list of "up" and aliased interfaces with SIOCGIFCONF ioctl ifconf.ifc_buf = buf; ifconf.ifc_len = sizeof(buf); sock = socket(AF_INET, SOCK_STREAM, 0); if (! ioctl(sock, SIOCGIFCONF, &ifconf)) { int count, max = ifconf.ifc_len / sizeof(ifconf.ifc_req[0]); for (count = 0; count < max; count++) { struct ifreq &ifr = ifconf.ifc_req[count]; WvInterface *ifc = (*this)[ifr.ifr_name]; if (!ifc) { ifc = new WvInterface(ifr.ifr_name); slist.add(ifc, true); } else ifc->rescan(); ifc->valid = true; } } close(sock); } // determine if the given address belongs to the local system WvString WvInterfaceDict::islocal(const WvAddr &addr) { static WvIPAddr bcast("255.255.255.255"); // always a local address! if (addr == bcast) return "lo"; Iter i(*this); for (i.rewind(); i.next(); ) { WvInterface &ifc(*i); if (!ifc.valid) continue; if (ifc.ipaddr() == addr || ifc.ipaddr().base() == addr || ifc.ipaddr().broadcast() == addr) return ifc.name; if (ifc.hwaddr() == addr) return ifc.name; } return WvString::null; } bool WvInterfaceDict::on_local_net(const WvIPNet &addr) { WvIPAddr zero; if (islocal(addr)) return true; Iter i(*this); for (i.rewind(); i.next(); ) { WvInterface &ifc = *i; if (!ifc.valid) continue; if (ifc.isup() && WvIPAddr(ifc.ipaddr()) != zero && ifc.ipaddr().includes(addr)) return true; } return false; } #else WvInterfaceDictBase WvInterfaceDict::slist(15); int WvInterface::getinfo(struct ifreq *ifr, int ioctl_num) { return 0; } void WvInterface::fill_rte(struct rtentry *rte, char *ifname, const WvIPNet &dest, const WvIPAddr &gw, int metric) {} WvInterface::WvInterface(WvStringParm _name) :err("fake") {} WvInterface::~WvInterface() {} void WvInterface::rescan() {} const WvIPNet &WvInterface::ipaddr() { return *(new WvIPNet()); } const WvIPAddr WvInterface::dstaddr() { return *(new WvIPAddr()); } int WvInterface::getflags() { return 0; } int WvInterface::setflags(int clear, int set) { return 0; } bool WvInterface::isup() { return true; } void WvInterface::up(bool enable) {} bool WvInterface::ispromisc() { return true; } void WvInterface::promisc(bool enable) {} int WvInterface::setipaddr(const WvIPNet &addr) { return 0; } int WvInterface::setmtu(int mtu) { return 0; } int WvInterface::addroute(const WvIPNet &dest, int metric = 0, WvStringParm table = "default") { return 0; } int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw, int metric = 0, WvStringParm table = "default") { return 0; } int WvInterface::delroute(const WvIPNet &dest, int metric = 0, WvStringParm table = "default") { return 0; } int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw, int metric = 0, WvStringParm table = "default") { return 0; } bool WvInterface::isarp() { return true; } int WvInterface::addarp(const WvIPNet &proto, const WvAddr &hw, bool proxy) { return 0; } WvInterfaceDict::WvInterfaceDict() :log("fake") {} WvInterfaceDict::~WvInterfaceDict() {} void WvInterfaceDict::update() {} bool WvInterfaceDict::islocal(const WvAddr &addr) { return true; } bool WvInterfaceDict::on_local_net(const WvIPNet &addr) { return true; } #endif wvstreams-4.6.1/linuxstreams/wvpty.cc0000644000175000001440000001217011036722347017036 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * WvStreams implementation of ptys under Linux. * * For more information on programming ptys, see chapter 19 of * Stevens' "Advanced Programming in the UNIX Environment" */ #include "wvpty.h" #include #include #include #include #include #include #include #include #define DPRINTF(format, args...) //#define DPRINTF(format, args...) fprintf(stderr, "WvPty:" format, ##args) bool WvPty::open_pty(WvString &master, int &master_fd, WvString &slave, int &slave_fd) { const char *xvals = "pqrstuvwxyzPQRST"; const char *yvals = "0123456789abcdef"; char pty[] = "/dev/ptyXY"; char tty[] = "/dev/ttyXY"; for (int i=0; xvals[i]; ++i) { pty[8] = tty[8] = xvals[i]; for (int j=0; yvals[j]; ++j) { pty[9] = tty[9] = yvals[j]; master_fd = ::open(pty, O_RDWR); if (master_fd >= 0) slave_fd = ::open(tty, O_RDWR); else slave_fd = -1; if (master_fd < 0 || slave_fd < 0) { int saved_errno = errno; if (master_fd >= 0) ::close(master_fd); if (slave_fd >= 0) ::close(slave_fd); if (saved_errno == ENOENT) { DPRINTF("No more PTYs (ENOENT)\n"); return false; // no more ptys } } else { DPRINTF("PTY is %s\n", (master = WvString(pty)).edit()); DPRINTF("TTY is %s\n", (slave = WvString(tty)).edit()); // try to change owner and permissions of slave. // this will only work if we // are root; if we're not root, we don't care. struct group *gr = ::getgrnam("tty"); ::fchown(slave_fd, ::getuid(), gr? gr->gr_gid: (gid_t)-1); ::fchmod(slave_fd, S_IRUSR | S_IWUSR | S_IWGRP); return true; } } } DPRINTF("No more PTYs\n"); return false; } WvPty::WvPty(const char *program, const char * const *argv, Callback _pre_exec_cb, Callback _post_exec_cb) : _pid(-1), _exit_status(242), pre_exec_cb(_pre_exec_cb), post_exec_cb(_post_exec_cb) { int master_fd, slave_fd; if (!open_pty(_master, master_fd, _slave, slave_fd) || (_pid = ::fork()) < 0) { // error _pid = -1; setfd(-1); } else if (_pid == 0) { // child static const int std_fds[] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, -1 }; const int *std_fd; if (::close(master_fd) < 0) { DPRINTF("close(master_fd) failed: %s\n", strerror(errno)); goto _error; } if (::setsid() < 0) { DPRINTF("setsid() failed: %s\n", strerror(errno)); goto _error; } ::ioctl(slave_fd, TIOCSCTTY, NULL); // This may fail in case opening the // ptys in open_slave proactively gave us a // controling terminal for (std_fd = std_fds; *std_fd != -1; ++std_fd) { if (::dup2(slave_fd, *std_fd) < 0) { DPRINTF("dup2(slave_fd, %s) failed: %s\n", *std_fd, strerror(errno)); goto _error; } } if (slave_fd > STDERR_FILENO && ::close(slave_fd) < 0) { DPRINTF("close(slave_fd) failed: %s\n", strerror(errno)); goto _error; } for (std_fd = std_fds; *std_fd != -1; ++std_fd) { if (::fcntl(*std_fd, F_SETFL, fcntl(*std_fd, F_GETFL) & (O_APPEND|O_ASYNC))) { DPRINTF("fcntl(%s, F_SETFL) failed: %s\n", *std_fd, strerror(errno)); goto _error; } } if (pre_exec_cb && !pre_exec_cb(*this)) goto _error; execvp(program, (char * const *)argv); if (post_exec_cb) post_exec_cb(*this); _error: _exit(242); } else { // parent if (::close(slave_fd) < 0) { DPRINTF("close(slave_fd) failed: %s\n", strerror(errno)); goto _error; } setfd(master_fd); } } void WvPty::kill(int signum) { if (_pid != -1) ::kill(_pid, signum); } void WvPty::monitor_child(bool wait) { if (_pid != -1) { int status; if (::waitpid(_pid, &status, wait? 0: WNOHANG) == _pid) { _pid = -1; _exit_status = status; } } } bool WvPty::child_exited() { monitor_child(false); return _pid == -1; } bool WvPty::child_killed() { monitor_child(false); return _pid == -1 && WIFSIGNALED(_exit_status); } int WvPty::finish() { monitor_child(true); return WEXITSTATUS(_exit_status); } int WvPty::exit_status() { monitor_child(false); if (_pid == -1) { if (child_killed()) return WTERMSIG(_exit_status); else return WEXITSTATUS(_exit_status); } else return 242; } wvstreams-4.6.1/linuxstreams/wvipfirewall.cc0000644000175000001440000002127111036722347020362 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPFirewall is an extremely simple hackish class that handles the Linux * 2.4 "iptables" firewall. See wvipfirewall.h. */ #include "wvipfirewall.h" #include "wvinterface.h" #include bool WvIPFirewall::enable = false, WvIPFirewall::ignore_errors = true; WvIPFirewall::WvIPFirewall() : log("Firewall", WvLog::Debug2) { // don't change any firewall rules here! Remember that there may be // more than one instance of the firewall object. } WvIPFirewall::~WvIPFirewall() { zap(); } WvString WvIPFirewall::port_command(const char *cmd, const char *proto, const WvIPPortAddr &addr) { WvIPAddr ad(addr), none; return WvString("iptables %s Services -j ACCEPT -p %s " "%s --dport %s " "%s", cmd, proto, ad == none ? WvString("") : WvString("-d %s", ad), addr.port, shutup()); } WvString WvIPFirewall::redir_command(const char *cmd, const WvIPPortAddr &src, int dstport) { WvIPAddr ad(src), none; return WvString("iptables -t nat %s TProxy " "-p tcp %s --dport %s " "-j REDIRECT --to-ports %s " "%s", cmd, ad == none ? WvString("") : WvString("-d %s", ad), src.port, dstport, shutup()); } WvString WvIPFirewall::forward_command(const char *cmd, const char *proto, const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat) { WvIPAddr srcaddr(src), dstaddr(dst), zero; WvString haveiface(""), haveoface(""); if (!(srcaddr == zero)) { haveiface.append("-d "); haveiface.append((WvString)srcaddr); } WvString retval; if ((dst == WvIPAddr("127.0.0.1")) || (dst == zero)) { retval.append("iptables -t nat %s FASTFORWARD -p %s --dport %s %s " "-j REDIRECT --to-port %s %s \n", cmd, proto, src.port, haveiface, dst.port, shutup()); } else { haveoface.append("-d "); haveoface.append((WvString)dstaddr); retval.append("iptables -t nat %s FASTFORWARD -p %s --dport %s %s " "-j DNAT --to-destination %s " "%s \n", cmd, proto, src.port, haveiface, dst, shutup()); } // FA57 is leet-speak for FAST, which is short for FASTFORWARD --adewhurst // FA58 is FA57+1. Nothing creative sprang to mind. --adewhurst // // We need this to mark the packet as it comes in so that we allow the // FastForward-ed packets to bypass the firewall (FA57). // // If we mark the packet with FA58, that means it gets masqueraded before // leaving, which may be useful to work around some network configuratios. retval.append("iptables -t mangle %s FASTFORWARD -p %s --dport %s " "-j MARK --set-mark %s %s %s\n", cmd, proto, src.port, snat ? "0xFA58" : "0xFA57", haveiface, shutup()); // Don't open the port completely; just open it for the forwarded packets retval.append("iptables %s FFASTFORWARD -j ACCEPT -p %s " "--dport %s -m mark --mark %s %s %s\n", cmd, proto, dst.port, snat ? "0xFA58" : "0xFA57", haveoface, shutup()); return retval; } WvString WvIPFirewall::redir_port_range_command(const char *cmd, const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport) { WvIPAddr ad(src_min), none; return WvString("iptables -t nat %s TProxy " "-p tcp %s --dport %s:%s " "-j REDIRECT --to-ports %s " "%s", cmd, ad == none ? WvString("") : WvString("-d %s", ad), src_min.port == 0? WvString(""): WvString(src_min.port), src_max.port == 0? WvString(""): WvString(src_max.port), dstport, shutup()); } WvString WvIPFirewall::redir_all_command(const char *cmd, int dstport) { return WvString("iptables -t nat %s TProxy " "-p tcp " "-j REDIRECT --to-ports %s " "%s", cmd, dstport, shutup()); } WvString WvIPFirewall::proto_command(const char *cmd, const char *proto) { return WvString("iptables %s Services -p %s -j ACCEPT " "%s", cmd, proto, shutup()); } void WvIPFirewall::add_port(const WvIPPortAddr &addr) { addrs.append(new WvIPPortAddr(addr), true); WvString s(port_command("-A", "tcp", addr)), s2(port_command("-A", "udp", addr)); if (enable) { system(s); system(s2); } } // note! This does not remove the address from the list, only the kernel! void WvIPFirewall::del_port(const WvIPPortAddr &addr) { WvIPPortAddrList::Iter i(addrs); for (i.rewind(); i.next(); ) { if (*i == addr) { WvString s(port_command("-D", "tcp", addr)), s2(port_command("-D", "udp", addr)); if (enable) { system(s); system(s2); } return; } } } void WvIPFirewall::add_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat) { ffwds.append(new FFwd(src, dst, snat), true); WvString s(forward_command("-A", "tcp", src, dst, snat)), s2(forward_command("-A", "udp", src, dst, snat)); log("Add Forwards (%s):\n%s\n%s\n", enable, s, s2); if (enable) { system(s); system(s2); } } void WvIPFirewall::del_forward(const WvIPPortAddr &src, const WvIPPortAddr &dst, bool snat) { FFwdList::Iter i(ffwds); for (i.rewind(); i.next();) { if (i->src == src && i->dst == dst && i->snat == snat) { WvString s(forward_command("-D", "tcp", src, dst, snat)), s2(forward_command("-D", "udp", src, dst, snat)); log("Delete Forward (%s):\n%s\n%s\n", enable, s, s2); if (enable) { system(s); system(s2); } } } } void WvIPFirewall::add_redir(const WvIPPortAddr &src, int dstport) { redirs.append(new Redir(src, dstport), true); WvString s(redir_command("-A", src, dstport)); if (enable) system(s); } void WvIPFirewall::del_redir(const WvIPPortAddr &src, int dstport) { RedirList::Iter i(redirs); for (i.rewind(); i.next(); ) { if (i->src == src && i->dstport == dstport) { WvString s(redir_command("-D", src, dstport)); if (enable) system(s); return; } } } void WvIPFirewall::add_redir_all(int dstport) { redir_alls.append(new RedirAll(dstport), true); WvString s(redir_all_command("-A", dstport)); if (enable) system(s); } void WvIPFirewall::del_redir_all(int dstport) { RedirAllList::Iter i(redir_alls); for (i.rewind(); i.next(); ) { if (i->dstport == dstport) { WvString s(redir_all_command("-D", dstport)); if (enable) system(s); return; } } } void WvIPFirewall::add_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport) { redir_port_ranges.append(new RedirPortRange(src_min, src_max, dstport), true); WvString s(redir_port_range_command("-A", src_min, src_max, dstport)); if (enable) system(s); } void WvIPFirewall::del_redir_port_range(const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport) { RedirPortRangeList::Iter i(redir_port_ranges); for (i.rewind(); i.next(); ) { if (i->src_min == src_min && i->src_max == src_max && i->dstport == dstport) { WvString s(redir_port_range_command("-D", src_min, src_max, dstport)); if (enable) system(s); return; } } } void WvIPFirewall::add_proto(WvStringParm proto) { protos.append(new WvString(proto), true); WvString s(proto_command("-A", proto)); if (enable) system(s); } void WvIPFirewall::del_proto(WvStringParm proto) { WvStringList::Iter i(protos); for (i.rewind(); i.next(); ) { if (*i == proto) { WvString s(proto_command("-D", proto)); if (enable) system(s); return; } } } // clear out our portion of the firewall void WvIPFirewall::zap() { WvIPPortAddrList::Iter i(addrs); for (i.rewind(); i.next(); ) { del_port(*i); i.xunlink(); } FFwdList::Iter ifwd(ffwds); for (ifwd.rewind(); ifwd.next();) { del_forward(ifwd->src, ifwd->dst, ifwd->snat); ifwd.xunlink(); } RedirList::Iter i2(redirs); for (i2.rewind(); i2.next(); ) { del_redir(i2->src, i2->dstport); i2.xunlink(); } RedirAllList::Iter i2_5(redir_alls); for (i2_5.rewind(); i2_5.next(); ) { del_redir_all(i2_5->dstport); i2_5.xunlink(); } RedirPortRangeList::Iter port_range(redir_port_ranges); for (port_range.rewind(); port_range.next(); ) { del_redir_port_range(port_range->src_min, port_range->src_max, port_range->dstport); port_range.xunlink(); } WvStringList::Iter i3(protos); for (i3.rewind(); i3.next(); ) { del_proto(*i3); i3.xunlink(); } } wvstreams-4.6.1/linuxstreams/wvtundev.cc0000644000175000001440000000242711036722347017533 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTunDev provides a convenient way of using Linux tunnel devices. * * If you don't have the /dev/net/tun device, try doing: * mknod /dev/net/tun c 10 200 */ #include #include #include "if_tun.h" #include #include "wvlog.h" #include "wvtundev.h" WvTunDev::WvTunDev(const WvIPNet &addr, int mtu) : WvFile("/dev/net/tun", O_RDWR) { init(addr, mtu); } void WvTunDev::init(const WvIPNet &addr, int mtu) { WvLog log("New tundev", WvLog::Debug2); if (getfd() < 0) { log("Could not open /dev/net/tun: %s\n", strerror(errno)); seterr(errno); return; } struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_NO_PI | IFF_TUN; if (ioctl(getfd(), TUNSETIFF, (void *) &ifr) < 0 || ioctl(getfd(), TUNSETNOCSUM, 1) < 0) { log("Could not initialize the interface: %s\n", strerror(errno)); seterr(errno); return; } WvInterface iface(ifr.ifr_name); iface.setipaddr(addr); iface.setmtu(mtu); iface.up(true); ifcname = ifr.ifr_name; log.app = ifcname; log(WvLog::Debug2, "Now up (%s).\n", addr); } wvstreams-4.6.1/linuxstreams/wviproute.cc0000644000175000001440000001521411036722347017713 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * The WvIPRoute and WvIPRouteList class, a quick (mostly hackish) attempt * at a way to read the Linux kernel routing table. */ #include "wviproute.h" #include "wvpipe.h" #include "wvinterface.h" #include "wvfile.h" #include "wvstringlist.h" #include #include WvIPRoute::WvIPRoute(WvStringParm _ifc, const WvIPNet &_net, const WvIPAddr &_gate, int _metric, WvStringParm _table) : ifc(_ifc), ip(_net), gateway(_gate), table(_table), src() { metric = _metric; } WvIPRoute::operator WvString() const { WvIPAddr zero; return WvString("%s via %s %s %s metric %s%s", ip, ifc, gateway, (src != zero ? WvString("src %s", src) : WvString("")), metric, (table != "default") ? WvString(" (table %s)", table) : WvString("")); } bool WvIPRoute::operator== (const WvIPRoute &r2) const { return (ip.network() == r2.ip.network() && ip.netmask() == r2.ip.netmask() && gateway == r2.gateway && ifc == r2.ifc && metric == r2.metric && table == r2.table); } /////////////////////////////////////// WvIPRouteList WvIPRouteList::WvIPRouteList() : log("Route Table", WvLog::Debug) { // nothing else to do } // Reads the kernel routing table, from /proc/net/route, and parses it into // A WvIPRouteList. Also reads the kernel 2.1.x "policy routing" tables, // (via the "ip" command) and parses those routes. void WvIPRouteList::get_kernel() { char *line; WvString ifc, table, gate, addr, mask, src; int metric, flags; bool invalid; WvIPRoute *r; WvStringList words; WvStringList::Iter word(words); // read each route information line from /proc/net/route; even though // "ip route list table all" returns all the same information plus more, // there's no guarantee that the ip command is available on all systems. WvFile kinfo("/proc/net/route", O_RDONLY); kinfo.getline(); while ((line = kinfo.getline()) != NULL) { //log(WvLog::Debug2, "get_kern1: line: %s\n", line); words.zap(); words.split(line); if (words.count() < 10) continue; // weird entry word.rewind(); word.next(); ifc = *word; word.next(); addr = *word; word.next(); gate = *word; word.next(); flags = strtoul(*word, NULL, 16); word.next(); // refcnt word.next(); // use word.next(); metric = atoi(*word); word.next(); mask = *word; // routes appear in the list even when not "up" -- strange. if (!(flags & RTF_UP)) continue; // the addresses in /proc/net/route are in hex. This here is some // pretty sicky type-munging... uint32_t a = strtoul(addr, NULL, 16), m = strtoul(mask, NULL, 16); uint32_t g = strtoul(gate, NULL, 16); WvIPAddr aa(a), mm(m); WvIPNet net(aa, mm); WvIPAddr gw(g); r = new WvIPRoute(ifc, net, gw, metric, "default"); append(r, true); //log(WvLog::Debug2, "get_kern1: out: %s\n", *r); } // add more data from the kernel "policy routing" default table const char *argv[] = { "ip", "route", "list", "table", "all", NULL }; WvPipe defaults(argv[0], argv, false, true, false); while (defaults.isok() && (line = defaults.blocking_getline(-1)) != NULL) { //log(WvLog::Debug2, "get_kern2: line: %s\n", line); invalid = false; ifc = gate = table = ""; metric = 0; words.zap(); words.split(line); if (words.count() < 3) continue; // weird entry word.rewind(); word.next(); if (*word == "broadcast" || *word == "local") continue; // these lines are weird: skip them WvIPNet net((*word == "default") ? WvString("0/0") : *word); while (word.next()) { WvString word1(*word); if (!word.next()) break; WvString word2(*word); if (word1 == "table") { if (word2 == "local") { invalid = true; // ignore 'local' table - too complex break; } else table = word2; } else if (word1 == "dev") ifc = word2; else if (word1 == "via") gate = word2; else if (word1 == "metric") metric = word2.num(); else if (word1 == "scope") ; // ignore else if (word1 == "proto" && word2 == "kernel") ; // ignore else if (word1 == "src") src = word2; else log(WvLog::Debug, "Unknown keyvalue: '%s' '%s' in (%s)\n", word1, word2, line); // ignore all other words - just use their defaults. } // if no table keyword was given, it's the default "main" table, which // we already read from /proc/net/route. Skip it. if (!table) continue; if (!ifc) { log(WvLog::Debug2, "No interface given for this route; skipped.\n"); continue; } r = new WvIPRoute(ifc, net, gate ? WvIPAddr(gate) : WvIPAddr(), metric, table); if (!!src) r->src = src; append(r, true); //log(WvLog::Debug2, "get_kern2: out: %s\n", *r); } } static WvString realtable(WvIPRoute &r) { if (!r.ip.is_default() && r.table == "default") return "main"; else return r.table; } // we use an n-squared algorithm here, for no better reason than readability. void WvIPRouteList::set_kernel() { WvIPRouteList old_kern; old_kern.get_kernel(); Iter oi(old_kern), ni(*this); // FIXME!! // Kernel 2.1.131: deleting a route with no gateway causes the kernel // to delete the _first_ route to that network, regardless of its // gateway. This is probably to make things like "route del default" // more convenient. However, it messes up if we add routes first, then // delete routes. // // Except for this problem, it makes more sense to add and then delete, // since we avoid races (we never completely remove a route to a host // we should be routing to). // delete outdated routes. for (oi.rewind(); oi.next(); ) { if (oi->metric == 99) continue; // "magic" metric for manual override for (ni.rewind(); ni.next(); ) if (*ni == *oi) break; if (!ni.cur()) // hit end of list without finding a match { WvInterface i(oi->ifc); log("Del %s\n", *oi); i.delroute(oi->ip, oi->gateway, oi->metric, realtable(*oi)); } } // add any new routes. for (ni.rewind(); ni.next(); ) { for (oi.rewind(); oi.next(); ) if (*oi == *ni) break; if (!oi.cur()) // hit end of list without finding a match { WvInterface i(ni->ifc); log("Add %s\n", *ni); i.addroute(ni->ip, ni->gateway, ni->src, ni->metric, realtable(*ni)); } } } WvIPRoute *WvIPRouteList::find(const WvIPAddr &addr) { Iter i(*this); for (i.rewind(); i.next(); ) { if (i->ip.includes(addr)) return &i(); } return NULL; } wvstreams-4.6.1/xplc-cxx/0000755000175000001440000000000011260431126014334 5ustar wlachuserswvstreams-4.6.1/xplc-cxx/getiface.cc0000644000175000001440000000403211077372756016434 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #include #include UUID_MAP_BEGIN(WeakRef) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IWeakRef) UUID_MAP_END IObject* IObjectImplInternal::getInterface(void* self, const UUID& uuid, const UUID_Info* uuidlist) { IObject* rv; while(uuidlist->iid) { if(*(uuidlist->iid) == uuid) { rv = reinterpret_cast (reinterpret_cast(self) + uuidlist->delta); rv->addRef(); return rv; } uuidlist++; } return 0; } wvstreams-4.6.1/xplc-cxx/factory.cc0000644000175000001440000000343411077372756016341 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2003, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #include #include #include UUID_MAP_BEGIN(GenericFactory) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IFactory) UUID_MAP_END GenericFactory::GenericFactory(FactoryFunc aFactory): factory(aFactory) { assert(factory); } IObject* GenericFactory::createObject() { return factory(); } wvstreams-4.6.1/xplc-cxx/uuidtostr.cc0000644000175000001440000000354111077372756016733 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #include #include #include char* UuidToString(const UUID& uuid, char* str) { assert(str); sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", uuid.Data1, uuid.Data2, uuid.Data3, uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3], uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]); return str; } wvstreams-4.6.1/xplc-cxx/strtouuid.cc0000644000175000001440000000557611077372756016745 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2003, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #include #include #include const UUID UuidFromString(const char* str) { UUID rv; char tmp[3]; char* end; bool format1 = false; bool ok = false; do { if(*str == '{') { format1 = true; ++str; } rv.Data1 = strtoul(str, &end, 16); if(end != str + 8) break; str = end; if(*str != '-') break; ++str; rv.Data2 = static_cast(strtoul(str, &end, 16)); if(end != str + 4) break; str = end; if(*str != '-') break; ++str; rv.Data3 = static_cast(strtoul(str, &end, 16)); if(end != str + 4) break; str = end; if(*str != '-') break; ++str; tmp[2] = 0; strncpy(tmp, str, 2); rv.Data4[0] = static_cast(strtoul(tmp, &end, 16)); if(end != tmp + 2) break; str += 2; strncpy(tmp, str, 2); rv.Data4[1] = static_cast(strtoul(tmp, &end, 16)); if(end != tmp + 2) break; str += 2; if(*str != '-') break; ++str; for(int i = 2; i < 8; ++i) { strncpy(tmp, str, 2); rv.Data4[i] = static_cast(strtoul(tmp, &end, 16)); if(end != tmp + 2) break; str += 2; } if(format1) { if(*str != '}') break; ++str; } if(*str != 0) break; ok = true; } while(0); if(!ok) rv = UUID_null; return rv; } wvstreams-4.6.1/xplc-cxx/xplc.cc0000644000175000001440000000501111077372756015631 0ustar wlachusers/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * XPLC - Cross-Platform Lightweight Components * Copyright (C) 2002-2004, Net Integration Technologies, Inc. * Copyright (C) 2003-2004, Pierre Phaneuf * * 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 * * As a special exception, you may use this file as part of a free * software library without restriction. Specifically, if other files * instantiate templates or use macros or inline functions from this * file, or you compile this file and link it with other files to * produce an executable, this file does not by itself cause the * resulting executable to be covered by the GNU Lesser General Public * License. This exception does not however invalidate any other * reasons why the executable file might be covered by the GNU Lesser * General Public License. */ #include #include #include #include #include void XPLC::addModuleDirectory(const char* directory) { xplc_ptr factory(get(XPLC_moduleManagerFactory)); if(!factory) return; xplc_ptr modulemgr(factory->createModuleManager(directory)); if(!modulemgr) return; servmgr->addHandler(modulemgr); } IObject* XPLC::create(const UUID& cid) { if(!servmgr) return 0; xplc_ptr factory(mutate(servmgr->getObject(cid))); if(!factory) return 0; return factory->createObject(); } IObject* XPLC::create(const char* aMoniker) { if(!servmgr) return 0; xplc_ptr moniker(mutate(servmgr->getObject(XPLC_monikers))); if(!moniker) return 0; xplc_ptr factory(mutate(moniker->resolve(aMoniker))); if(!factory) return 0; return factory->createObject(); } wvstreams-4.6.1/config.guess0000755000175000001440000012475311036722347015133 0ustar wlachusers#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-08-03' # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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 Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp 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` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: wvstreams-4.6.1/Doxyfile0000644000175000001440000012526211036722347014315 0ustar wlachusers# Doxyfile 1.3.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = WvStreams # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = Docs # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en # (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, # Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited # members of a class in the documentation of that class as if those members were # ordinary class members. Constructors, destructors and assignment operators of # the base classes will not be shown. INLINE_INHERITED_MEMB = YES # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. It is allowed to use relative paths in the argument list. STRIP_FROM_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explict @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # reimplements. INHERIT_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = YES # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = . # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc FILE_PATTERNS = *.h *.c *.cc *.cpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # that are symbolic links (a Unix filesystem feature) are excluded from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = test*.* *test.* *gremlin*.* *.t.* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = Docs/sgmlmanual/egfiles # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = *.cc *.h *.c # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. INPUT_FILTER = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = Wv I IWv #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = doxy-html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output dir. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimised for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assigments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. PREDEFINED = __cplusplus # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse the # parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::addtions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or # super classes. Setting the tag to NO turns the diagrams off. Note that this # option is superceded by the HAVE_DOT option below. This is only a fallback. It is # recommended to install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similiar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes that # lay further from the root node will be omitted. Note that setting this option to # 1 or 2 may greatly reduce the computation time needed for large code bases. Also # note that a graph may be further truncated if the graph's image dimensions are # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). # If 0 is used for the depth value (the default), the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::addtions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO wvstreams-4.6.1/install.mk0000644000175000001440000000363411205042556014577 0ustar wlachusersifeq ("$(with_readline)", "no") install: install-shared install-dev install-uniconfd else install: install-shared install-dev install-uniconfd install-wsd endif install-shared: $(TARGETS_SO) $(INSTALL) -d $(DESTDIR)$(libdir) for i in $(TARGETS_SO); do \ $(INSTALL_PROGRAM) $$i.$(SO_VERSION) $(DESTDIR)$(libdir)/ ; \ done $(INSTALL) -d $(DESTDIR)$(sysconfdir) $(INSTALL_DATA) uniconf/daemon/uniconf.conf $(DESTDIR)$(sysconfdir)/ install-dev: $(TARGETS_SO) $(TARGETS_A) $(INSTALL) -d $(DESTDIR)$(includedir)/wvstreams/xplc $(INSTALL_DATA) $(wildcard include/*.h) $(DESTDIR)$(includedir)/wvstreams $(INSTALL_DATA) $(wildcard include/xplc/*.h) $(DESTDIR)$(includedir)/wvstreams/xplc $(INSTALL) -d $(DESTDIR)$(libdir) for i in $(TARGETS_A); do \ $(INSTALL_DATA) $$i $(DESTDIR)$(libdir); \ done cd $(DESTDIR)$(libdir) && for i in $(TARGETS_SO); do \ rm -f $$i; \ $(LN_S) $$i.$(SO_VERSION) $$i; \ done $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL_DATA) $(filter-out %-uninstalled.pc, $(wildcard pkgconfig/*.pc)) $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) wvtestrun $(DESTDIR)$(bindir) $(INSTALL) -d $(DESTDIR)$(libdir)/valgrind $(INSTALL) wvstreams.supp $(DESTDIR)$(libdir)/valgrind install-uniconfd: uniconf/daemon/uniconfd uniconf/tests/uni uniconf/tests/uni.8 $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) uniconf/tests/uni $(DESTDIR)$(bindir)/ $(INSTALL) -d $(DESTDIR)$(sbindir) $(INSTALL_PROGRAM) uniconf/daemon/uniconfd $(DESTDIR)$(sbindir)/ $(INSTALL) -d $(DESTDIR)$(localstatedir)/lib/uniconf touch $(DESTDIR)$(localstatedir)/lib/uniconf/uniconfd.ini $(INSTALL) -d $(DESTDIR)$(mandir)/man8 $(INSTALL_DATA) uniconf/daemon/uniconfd.8 $(DESTDIR)$(mandir)/man8 $(INSTALL_DATA) uniconf/tests/uni.8 $(DESTDIR)$(mandir)/man8 install-wsd: ipstreams/tests/wsd $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) ipstreams/tests/wsd $(DESTDIR)$(bindir)/ wvstreams-4.6.1/configure-mingw320000755000175000001440000000065311100163451015761 0ustar wlachusers#!/bin/bash PORTS=$PWD/../wvports ./configure \ --build=$(./config.guess) \ --host=i586-mingw32msvc \ --enable-exceptions \ CPPFLAGS="-mno-cygwin \ -I$PORTS/zlib/build/zlib \ -I$PORTS/openssl/build/openssl/include $XCPPFLAGS \ -I$PORTS/win32api/build/w32api/include" \ LDFLAGS="\ -L$PORTS/zlib/build/zlib \ -L$PORTS/openssl/build/openssl \ -L$PORTS/win32api/build/w32api/lib" \ LIBS="-lwsock32 -lgdi32" \ $@ wvstreams-4.6.1/dbus/0000755000175000001440000000000011260431126013523 5ustar wlachuserswvstreams-4.6.1/dbus/wvdbusconn.cc0000644000175000001440000002606211152037070016230 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * */ #include "wvdbusconn.h" #include "wvmoniker.h" #include "wvstrutils.h" #undef interface // windows #include static WvString translate(WvStringParm dbus_moniker) { WvStringList l; WvStringList::Iter i(l); if (!strncasecmp(dbus_moniker, "unix:", 5)) { WvString path, tmpdir; l.split(dbus_moniker+5, ","); for (i.rewind(); i.next(); ) { if (!strncasecmp(*i, "path=", 5)) path = *i + 5; else if (!strncasecmp(*i, "abstract=", 9)) path = WvString("@%s", *i + 9); else if (!strncasecmp(*i, "tmpdir=", 7)) tmpdir = *i + 7; } if (!!path) return WvString("unix:%s", path); else if (!!tmpdir) return WvString("unix:%s/dbus.sock", tmpdir); } else if (!strncasecmp(dbus_moniker, "tcp:", 4)) { WvString host, port, family; l.split(dbus_moniker+4, ","); for (i.rewind(); i.next(); ) { if (!strncasecmp(*i, "family=", 7)) family = *i + 7; else if (!strncasecmp(*i, "host=", 5)) host = *i + 5; else if (!strncasecmp(*i, "port=", 5)) port = *i + 5; } if (!!host && !!port) return WvString("tcp:%s:%s", host, port); else if (!!host) return WvString("tcp:%s", host); else if (!!port) return WvString("tcp:0.0.0.0:%s", port); // localhost } return dbus_moniker; // unrecognized } static IWvStream *stream_creator(WvStringParm _s, IObject *) { WvString s(_s); if (!strcasecmp(s, "starter")) { WvString startbus(getenv("DBUS_STARTER_ADDRESS")); if (!!startbus) return IWvStream::create(translate(startbus)); else { WvString starttype(getenv("DBUS_STARTER_BUS_TYPE")); if (!!starttype && !strcasecmp(starttype, "system")) s = "system"; else if (!!starttype && !strcasecmp(starttype, "session")) s = "session"; } } if (!strcasecmp(s, "system")) { // NOTE: the environment variable for the address of the system // bus is very often not set-- in that case, look in your dbus // system bus config file (e.g. /etc/dbus-1/system.conf) for the // raw address and either set this environment variable to that, or // pass in the address directly WvString bus(getenv("DBUS_SYSTEM_BUS_ADDRESS")); if (!!bus) return IWvStream::create(translate(bus)); } if (!strcasecmp(s, "session")) { WvString bus(getenv("DBUS_SESSION_BUS_ADDRESS")); if (!!bus) return IWvStream::create(translate(bus)); } return IWvStream::create(translate(s)); } static WvMoniker reg("dbus", stream_creator); static int conncount; WvDBusConn::WvDBusConn(IWvStream *_cloned, IWvDBusAuth *_auth, bool _client) : WvStreamClone(_cloned), log(WvString("DBus %s%s", _client ? "" : "s", ++conncount), WvLog::Debug5), pending(10) { init(_auth, _client); } WvDBusConn::WvDBusConn(WvStringParm moniker, IWvDBusAuth *_auth, bool _client) : WvStreamClone(IWvStream::create(moniker)), log(WvString("DBus %s%s", _client ? "" : "s", ++conncount), WvLog::Debug5), pending(10) { log("Connecting to '%s'\n", moniker); init(_auth, _client); } void WvDBusConn::init(IWvDBusAuth *_auth, bool _client) { log("Initializing.\n"); client = _client; auth = _auth ? _auth : new WvDBusClientAuth; authorized = in_post_select = false; if (!client) set_uniquename(WvString(":%s.0", conncount)); if (!isok()) return; delay_output(true); // this will get enqueued until later, but we want to make sure it // comes before anything the user tries to send - including anything // goofy they enqueue in the authorization part. if (client) send_hello(); try_auth(); } WvDBusConn::~WvDBusConn() { log("Shutting down.\n"); if (geterr()) log("Error was: %s\n", errstr()); close(); delete auth; } void WvDBusConn::close() { if (!closed) log("Closing.\n"); WvStreamClone::close(); } WvString WvDBusConn::uniquename() const { return _uniquename; } void WvDBusConn::request_name(WvStringParm name, const WvDBusCallback &onreply, time_t msec_timeout) { uint32_t flags = (DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_REPLACE_EXISTING); WvDBusMsg msg("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName"); msg.append(name).append(flags); send(msg, onreply, msec_timeout); } uint32_t WvDBusConn::send(WvDBusMsg msg) { msg.marshal(out_queue); if (authorized) { log(" >> %s\n", msg); write(out_queue); } else log(" .> %s\n", msg); return msg.get_serial(); } void WvDBusConn::send(WvDBusMsg msg, const WvDBusCallback &onreply, time_t msec_timeout) { send(msg); if (onreply) add_pending(msg, onreply, msec_timeout); } class xxReplyWaiter { public: WvDBusMsg *reply; xxReplyWaiter() { reply = NULL; } ~xxReplyWaiter() { delete reply; } bool reply_wait(WvDBusMsg &msg) { reply = new WvDBusMsg(msg); return true; } }; WvDBusMsg WvDBusConn::send_and_wait(WvDBusMsg msg, time_t msec_timeout, wv::function serial_cb) { xxReplyWaiter rw; send(msg, wv::bind(&xxReplyWaiter::reply_wait, &rw, _1), msec_timeout); if (serial_cb) serial_cb(msg.get_serial()); while (!rw.reply && isok()) runonce(); if (!rw.reply) return WvDBusError(msg, DBUS_ERROR_FAILED, WvString("Connection closed (%s) " "while waiting for reply.", errstr())); else return *rw.reply; } void WvDBusConn::out(WvStringParm s) { log(" >> %s", s); print(s); } const char *WvDBusConn::in() { const char *s = trim_string(getline(0)); if (s) log("<< %s\n", s); return s; } void WvDBusConn::send_hello() { WvDBusMsg msg("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "Hello"); send(msg, wv::bind(&WvDBusConn::_registered, this, _1)); WvDBusMsg msg2("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch"); msg2.append("type='signal'"); send(msg2); // don't need to monitor this for completion } void WvDBusConn::set_uniquename(WvStringParm s) { // we want to print the message before switching log.app, so that we // can trace which log.app turned into which log("Assigned name '%s'\n", s); _uniquename = s; log.app = WvString("DBus %s%s", client ? "" : "s", uniquename()); } void WvDBusConn::try_auth() { bool done = auth->authorize(*this); if (done) { // ready to send messages! if (out_queue.used()) { log(" >> (sending enqueued messages)\n"); write(out_queue); } authorized = true; } } void WvDBusConn::add_callback(CallbackPri pri, WvDBusCallback cb, void *cookie) { callbacks.append(new CallbackInfo(pri, cb, cookie), true); } void WvDBusConn::del_callback(void *cookie) { // remember, there might be more than one callback with the same cookie. CallbackInfoList::Iter i(callbacks); for (i.rewind(); i.next(); ) if (i->cookie == cookie) i.xunlink(); } int WvDBusConn::priority_order(const CallbackInfo *a, const CallbackInfo *b) { return a->pri - b->pri; } bool WvDBusConn::filter_func(WvDBusMsg &msg) { log("<< %s\n", msg); // handle replies uint32_t rserial = msg.get_replyserial(); if (rserial) { Pending *p = pending[rserial]; if (p) { p->cb(msg); pending.remove(p); return true; // handled it } } // handle all the generic filters CallbackInfoList::Sorter i(callbacks, priority_order); for (i.rewind(); i.next(); ) { bool handled = i->cb(msg); if (handled) return true; } return false; // couldn't handle the message, sorry } WvDBusClientAuth::WvDBusClientAuth() { sent_request = false; } wvuid_t WvDBusClientAuth::get_uid() { return wvgetuid(); } bool WvDBusClientAuth::authorize(WvDBusConn &c) { if (!sent_request) { c.write("\0", 1); WvString uid = get_uid(); c.out("AUTH EXTERNAL %s\r\n\0", WvHexEncoder().strflushstr(uid)); sent_request = true; } else { const char *line = c.in(); if (line) { if (!strncasecmp(line, "OK ", 3)) { c.out("BEGIN\r\n"); return true; } else if (!strncasecmp(line, "ERROR ", 6)) c.seterr("Auth failed: %s", line); else c.seterr("Unknown AUTH response: '%s'", line); } } return false; } time_t WvDBusConn::mintimeout_msec() { WvTime when = 0; PendingDict::Iter i(pending); for (i.rewind(); i.next(); ) { if (!when || when > i->valid_until) when = i->valid_until; } if (!when) return -1; else if (when <= wvstime()) return 0; else return msecdiff(when, wvstime()); } bool WvDBusConn::post_select(SelectInfo &si) { bool ready = WvStreamClone::post_select(si); if (si.inherit_request) return ready; if (in_post_select) return false; in_post_select = true; if (!authorized && ready) try_auth(); if (!alarm_remaining()) { WvTime now = wvstime(); PendingDict::Iter i(pending); for (i.rewind(); i.next(); ) { if (now > i->valid_until) { log("Expiring %s\n", i->msg); expire_pending(i.ptr()); i.rewind(); } } } if (authorized && ready) { // put this in a loop so that wvdbusd can forward packets rapidly. // Otherwise TCP_NODELAY kicks in, because we do a select() loop // between packets, which causes delay_output() to flush. bool ran; do { ran = false; size_t needed = WvDBusMsg::demarshal_bytes_needed(in_queue); size_t amt = needed - in_queue.used(); if (amt < 4096) amt = 4096; read(in_queue, amt); WvDBusMsg *m; while ((m = WvDBusMsg::demarshal(in_queue)) != NULL) { ran = true; filter_func(*m); delete m; } } while (ran); } alarm(mintimeout_msec()); in_post_select = false; return false; } bool WvDBusConn::isidle() { return !out_queue.used() && pending.isempty(); } void WvDBusConn::expire_pending(Pending *p) { if (p) { WvDBusCallback xcb(p->cb); pending.remove(p); // prevent accidental recursion WvDBusError e(p->msg, DBUS_ERROR_FAILED, "Timed out while waiting for reply"); xcb(e); } } void WvDBusConn::cancel_pending(uint32_t serial) { Pending *p = pending[serial]; if (p) { WvDBusCallback xcb(p->cb); WvDBusMsg msg(p->msg); pending.remove(p); // prevent accidental recursion WvDBusError e(msg, DBUS_ERROR_FAILED, "Canceled while waiting for reply"); xcb(e); } } void WvDBusConn::add_pending(WvDBusMsg &msg, WvDBusCallback cb, time_t msec_timeout) { uint32_t serial = msg.get_serial(); assert(serial); if (pending[serial]) cancel_pending(serial); pending.add(new Pending(msg, cb, msec_timeout), true); alarm(mintimeout_msec()); } bool WvDBusConn::_registered(WvDBusMsg &msg) { WvDBusMsg::Iter i(msg); _uniquename = i.getnext().get_str(); set_uniquename(_uniquename); return true; } wvstreams-4.6.1/dbus/wvdbusmarshal.cc0000644000175000001440000000553411202637403016725 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Wrapper code for marshalling/demarshalling WvDBusMsg objects. This is * in a separate file from WvDBusMsg in case you want to use a WvDBusMsg * but not our special/gross marshalling code from wvdbusmarshal_c.c. * */ #include "wvdbusmsg.h" #undef interface // windows #include static int wvdbus_message_length(const char *buf, size_t len) { int msglen = dbus_message_demarshal_bytes_needed(buf, len); if (msglen > 0) return msglen; else if (msglen == 0) return DBUS_MINIMUM_HEADER_SIZE; return 0; } WvDBusMsg *WvDBusMsg::demarshal(WvBuf &buf) { // to make sure bytes are aligned (as required by d-bus), copy them into a // new buffer (not very efficient, but what can you do without reworking // our buffer implementation) WvDynBuf alignedbuf; size_t buflen = buf.used(); alignedbuf.put(buf.peek(0, buflen), buflen); // first get size of message to demarshal. if too little or bad length, // return NULL (possibly after consuming the bad data) size_t messagelen = wvdbus_message_length((const char *) alignedbuf.peek(0, buflen), buflen); if (messagelen == 0) // invalid message data { buf.get(buflen); // clear invalid crap - the best we can do return NULL; } else if (messagelen > buflen) // not enough data return NULL; // Assuming that worked and we can demarshal a message, try to do so DBusError error; dbus_error_init(&error); DBusMessage *_msg = dbus_message_demarshal((const char *) alignedbuf.peek(0, buflen), messagelen, &error); if (dbus_error_is_set(&error)) dbus_error_free (&error); buf.get(messagelen); if (_msg) { WvDBusMsg *msg = new WvDBusMsg(_msg); dbus_message_unref(_msg); return msg; } else return NULL; } size_t WvDBusMsg::demarshal_bytes_needed(WvBuf &buf) { // to make sure bytes are aligned (as required by d-bus), copy them into a // new buffer (not very efficient, but what can you do without reworking // our buffer implementation) WvDynBuf alignedbuf; size_t used = buf.used(); alignedbuf.put(buf.peek(0, used), used); return wvdbus_message_length((const char *)alignedbuf.peek(0, used), used); } void WvDBusMsg::marshal(WvBuf &buf) { DBusMessage *msg = *this; static uint32_t global_serial = 1000; if (!dbus_message_get_serial(msg)) { dbus_message_set_serial(msg, ++global_serial); } dbus_message_lock (msg); char *cbuf; int len; dbus_message_marshal(msg, &cbuf, &len); buf.put(cbuf, len); free(cbuf); } wvstreams-4.6.1/dbus/tests/0000755000175000001440000000000011260431131014661 5ustar wlachuserswvstreams-4.6.1/dbus/tests/wvdbus.ini.tmpl0000644000175000001440000000376511057766345017710 0ustar wlachusers; Really simple one-level ini file for WvDBusD to use an SSL certificate. ; ; cert should just map to a valid PEM-encoded certificate, ie: ;cert = -----BEGIN CERTIFICATE-----\ ;MIICUjCCAbugAwIBAgIENWBLDjANBgkqhkiG9w0BAQUFADApMRYwFAYKCZImiZPy\ ;LGQBGRMGaGVybWVzMQ8wDQYDVQQDEwZoZXJtZXMwHhcNMDgwODA2MjEzMzQyWhcN\ ;MTgwODA0MjEzMzQyWjApMRYwFAYKCZImiZPyLGQBGRMGaGVybWVzMQ8wDQYDVQQD\ ;EwZoZXJtZXMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLf5+O19MWDAnlP\ ;otoSesP/lJOOct2SMS2rNI1SNRW2kZ89UZRUiFnPelumZen9AUYeL25IrPf77wwp\ ;JpDLE0Zbw8TNE/hpBEwpCiP0AkD6+CWUz8VPGJoS3olEiUIvtVAQ3zI2BiPmY/qQ\ ;s6tf+2A1JXe8TtKX4d03rU/yuMchAgMBAAGjgYYwgYMwHQYDVR0OBBYEFH62VZzj\ ;T/O2/Ied4j4JVWLCK0MzMBEGCWCGSAGG+EIBAQQEAwIGQDAVBglghkgBhvhCAQwE\ ;CBYGaGVybWVzMA4GA1UdDwEB/wQEAwIDqDAJBgNVHRMEAjAAMB0GA1UdJQQWMBQG\ ;CCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOBgQAQiWKeBs85g619\ ;ThrZ2uIt+xJBsC25pmJwtCFc5U5f6Z1PTvbbriM+tgaubUa1yTC7WF2Q3Cfitczv\ ;ZUZlW3z7cid1ZWNQet+r7MwmE51mgrlNZNsPcU/2LlG4Ym4GFdqeuiVsEdANmFzP\ ;V6bxkeOYeFqXNsUXN1xMk1OHimmRYQ==\ ;-----END CERTIFICATE----- ; ; privrsa should map to a valid PEM-encoded private RSA key, ie: ; ;privrsa = -----BEGIN RSA PRIVATE KEY-----\ ;MIICWwIBAAKBgQCy3+fjtfTFgwJ5T6LaEnrD/5STjnLdkjEtqzSNUjUVtpGfPVGU\ ;VIhZz3pbpmXp/QFGHi9uSKz3++8MKSaQyxNGW8PEzRP4aQRMKQoj9AJA+vgllM/F\ ;TxiaEt6JRIlCL7VQEN8yNgYj5mP6kLOrX/tgNSV3vE7Sl+HdN61P8rjHIQIDAQAB\ ;AoGAYZreHRofm1sWkX2L/nTQ+nxO5Yl4UkFAhowCXA78moGJypuaFVdfI6qcOMB+\ ;ogSFmm5EMWiEwbh+Q2N9AMtfEz57dpcZlDj+/NsQPwIFaVsMsb7H8Pqf5Wo4EdDN\ ;RpgCfpJoALKCqNnUtkNFmwTnNS0PyLEdyuEyBmrt4OhiklUCQQDihKlP1mtXQnSM\ ;k2oIBL7zW6PuiE4zVXlGkOF1zhmhmEhIJEyWPWa+xaPxhyXnVI9u9zjgMB+zIqXg\ ;TKTfTwD7AkEAyifQClJWYWNrvpaYkzLdnwX4DMsHRa1LQyPxHrxAODO0bf2AC+1W\ ;oeX3jiFQ5ttx/BXhGpjW6KJ/nYBh11H1kwJATY2qAkGhQqDoEnEuLkyhq+RGPhbA\ ;32Z2PSjBaHoF4IOoy7pR1mZzVQGJ3dmtqoQTD6To/ii70bMdI6xaDnKYHQJAQyk4\ ;78TtF8vdBuOnavfyMxvbjfyBvP9WysaNG+X0+/cJkaUvvkaqin0JYrnk093CH7rx\ ;H1H5zC34cc4uM0fyawJAK1VdW5K1Xx05V5ZAFlDYBNS7LNaVAbHhm0t/CeqNI3Dp\ ;cwDNVoNs9ebL8w5I5LV2QDQ7HzcAfe9V9YJY0I4xFw==\ ;-----END RSA PRIVATE KEY----- wvstreams-4.6.1/dbus/tests/wvdbusd.cc0000644000175000001440000000326211057766345016677 0ustar wlachusers#include "wvdbusserver.h" #include "wvstreamsdaemon.h" #include "wvautoconf.h" #include "wvx509mgr.h" #include "wvsslstream.h" #include "wvmoniker.h" #include "uniconfroot.h" static WvX509Mgr *cert = NULL; class WvDBusDaemon : public WvStreamsDaemon { public: WvDBusDaemon() : WvStreamsDaemon("WvDBusDaemon", WVPACKAGE_VERSION, wv::bind(&WvDBusDaemon::cb, this)), log("WvDBusDaemon", WvLog::Debug), configfile("wvdbus.ini") { args.add_option('c', "config", "Specify path to configuration file", "FILENAME", configfile); args.add_required_arg("MONIKER", true); } virtual ~WvDBusDaemon() { WVRELEASE(cert); } void cb() { log("WvDBusDaemon starting.\n"); conf.mount(WvString("ini:%s", configfile)); if (!cert && conf["cert"].exists() && conf["privrsa"].exists()) { cert = new WvX509Mgr; cert->decode(WvX509::CertPEM, *conf["cert"]); cert->decode(WvRSAKey::RsaPEM, *conf["privrsa"]); if (!cert->test()) { log("Certificate found in ini file, but failed to load!\n"); WVRELEASE(cert); } else log("Certificate found in ini file, and loaded!\n"); } WvDBusServer *s = new WvDBusServer; WvStringList::Iter i(extra_args()); for (i.rewind(); i.next(); ) s->listen(*i); add_die_stream(s, true, "DBus Server"); } private: WvLog log; UniConfRoot conf; WvString configfile; }; static IWvStream *dbus_serv_creator(WvStringParm s, IObject *obj) { return new WvSSLStream(IWvStream::create(s, obj), cert, 0, true); } static WvMoniker sreg("sslserv", dbus_serv_creator, true); int main(int argc, char *argv[]) { return WvDBusDaemon().run(argc, argv); } wvstreams-4.6.1/dbus/tests/wvdbus.cc0000644000175000001440000000361011061526303016507 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Really basic D-Bus test program. * */ #include "wvargs.h" #include "wvdbusconn.h" #include "wvistreamlist.h" #include "wvlinkerhack.h" WV_LINK_TO(WvTCPConn); static WvStringList paths; static bool incoming(WvDBusMsg &msg) { WvStringList::Iter i(paths); for (i.rewind(); i.next(); ) { if (*i == msg.get_path()) { fprintf(stderr, "\n * %s\n\n", ((WvString)msg).cstr()); return true; } } return false; } int main(int argc, char *argv[]) { WvArgs args; WvString moniker("dbus:session"); WvStringList names, remaining_args; bool sigtest = false, methtest = false, wait = false; // args.add_optional_arg("COMMANDS", true); args.add_option('m', "moniker", "Specify the dbus bus to use", "MONIKER", moniker); args.add_option('p', "path", "Listen on ", "PATH", paths); args.add_option('n', "name", "Register as ", "NAME", names); args.add_set_bool_option('S', "signaltest", "Send a test signal", sigtest); args.add_set_bool_option('M', "methodtest", "Call test method", methtest); args.add_set_bool_option('w', "wait", "Wait forever", wait); args.process(argc, argv, &remaining_args); WvDBusConn conn(moniker); WvIStreamList::globallist.append(&conn, false, "wvdbus conn"); conn.add_callback(WvDBusConn::PriNormal, incoming); WvStringList::Iter i(names); for (i.rewind(); i.next(); ) conn.request_name(*i); if (sigtest) WvDBusSignal("/ca/nit/foo", "ca.nit.foo", "BarSignal").send(conn); if (methtest) { WvDBusMsg("ca.nit.MyListener", "/ca/nit/foo", "ca.nit.foo", "BarMethod") .append("bee").send(conn); } while (conn.isok() && (wait || !conn.isidle())) WvIStreamList::globallist.runonce(); return 0; } wvstreams-4.6.1/dbus/t/0000755000175000001440000000000011260431126013766 5ustar wlachuserswvstreams-4.6.1/dbus/t/wvdbusmsg.t.cc0000644000175000001440000000606611202637403016572 0ustar wlachusers#include "wvtest.h" #include "wvdbusmsg.h" WVTEST_MAIN("marshalling/demarshalling") { WvDBusMsg msg("my.dest", "/my/path", "my.ifc", "method"); WvDynBuf buf; msg.marshal(buf); WvDBusMsg *msg2 = WvDBusMsg::demarshal(buf); WvString msg1_str = msg; WvString msg2_str = (*msg2); WVPASSEQ(msg1_str, msg2_str); delete msg2; } WVTEST_MAIN("dbusmsg basics") { WvDBusMsg msg("my.dest", "/my/path", "my.ifc", "method"); msg.append("yoink").append((int16_t)-1) .append((uint16_t)-1).append(true).append("-2") .append((int64_t)UINT_MAX+1).append(123.45); WVPASSEQ(msg.get_dest(), "my.dest"); WVPASSEQ(msg.get_path(), "/my/path"); WVPASSEQ(msg.get_interface(), "my.ifc"); WVPASSEQ(msg.get_member(), "method"); WVPASSEQ(msg.get_argstr(), "yoink,-1,65535,1,-2,4294967296,123.45"); { WvDBusMsg::Iter i(msg); WvString s = i.getnext(); int n1 = i.getnext(); unsigned n2 = i.getnext(); bool b = (int)i.getnext(); WVPASSEQ(s, "yoink"); WVPASSEQ(n1, -1); WVPASSEQ(n2, 0xFFFF); WVPASSEQ(b, true); WVPASS(i.next()); WVPASSEQ(*i, "-2"); WVPASSEQ(i, -2); WVPASSEQ((bool)i, true); int64_t ll = (int64_t)i.getnext(); WVPASSEQ(ll, UINT_MAX+1); WVPASS(i.next()); // WvTest doesn't have WVPASSEQ for doubles WVFAILEQ(WvString((double)i), ""); WVPASS((double)i == 123.45); WVFAIL(i.next()); // no more parameters WVPASSEQ(i.type(), 0); WVPASS(i.get_str().isnull()); WVPASSEQ((int)i, 0); WVPASSEQ((unsigned)i, 0); } } WVTEST_MAIN("dbusmsg arrays") { WvDBusMsg msg("my.dest", "/my/path", "my.ifc", "method"); WVPASS(true); msg.variant_start("i").append(5).variant_end(); WVPASS(true); msg.struct_start("sib").append("str").append(5).append(true).struct_end(); WVPASS(true); msg.array_start("s").append("one").append("two").array_end(); WVPASS(true); msg.array_start("i").append(5).append(6).array_end(); WVPASS(true); msg.array_start("v") .varray_start("s").append("str1").append("str2").varray_end() .varray_start("i").append(-5).append(-6).varray_end() .array_end(); WVPASS(true); WVPASSEQ(msg.get_argstr(), "{5},[str,5,1],[one,two],[5,6],[{[str1,str2]},{[-5,-6]}]"); } WVTEST_MAIN("dbusmsg char signedness") { unsigned char uc = UCHAR_MAX; signed char sc1 = CHAR_MAX; signed char sc2 = -1; signed char sc3 = CHAR_MIN; WvDBusMsg msg("my.dest", "/my/path", "my.ifc", "method"); msg.array_start("y").append(uc).append(sc1).append(sc2).append(sc3).array_end(); WVPASSEQ(msg.get_argstr(), "[255,127,255,128]"); WvDBusMsg::Iter it(msg); it.rewind(); it.next(); WvDBusMsg::Iter ait(it.open()); ait.rewind(); ait.next(); WVPASSEQ((unsigned char)ait, uc); WVPASSEQ(ait.get_int(), uc); ait.next(); WVPASSEQ((signed char)ait, sc1); WVPASSEQ(ait.get_int(), (unsigned char)sc1); ait.next(); WVPASSEQ((signed char)ait, sc2); WVPASSEQ(ait.get_int(), (unsigned char)sc2); ait.next(); WVPASSEQ((signed char)ait, sc3); WVPASSEQ(ait.get_int(), (unsigned char)sc3); } wvstreams-4.6.1/dbus/t/wvdbusserver.t.cc0000644000175000001440000002010611077124114017301 0ustar wlachusers#include "wvdbusmsg.h" #include "wvdbusconn.h" #include "wvdbusserver.h" #include "wvfileutils.h" #include "wvfork.h" #include "wvtest.h" #include "wvloopback.h" #include "wvuid.h" class TestDBusServer { public: WvString moniker; WvDBusServer *s; TestDBusServer() { fprintf(stderr, "Creating a test DBus server.\n"); // We might prefer to use a unix: moniker, but get_addr() only // supports tcp: monikers just now. WvString smoniker("tcp:0.0.0.0"); s = new WvDBusServer(); s->listen(smoniker); moniker = s->get_addr(); fprintf(stderr, "Server address is '%s'\n", moniker.cstr()); WvIStreamList::globallist.append(s, false, "dbus server listener"); } ~TestDBusServer() { WVRELEASE(s); /* Flush connections out of the globallist, necessary to trigger * the actual killing of the WvDBusServer object (it's ref- * counted based on #connections). No self-respecting program would * need to do this, but we don't want Valgrind thinking we're leaking * memory, or the open file descriptor checker freaking out. */ for (int i = 0; i < 1; ++i) WvIStreamList::globallist.runonce(); WVPASS(WvIStreamList::globallist.isempty()); } }; static int mysignal_count = 0; static bool mysignal(WvDBusMsg &msg) { if (msg.get_interface() == "x.y.z.anything") { fprintf(stderr, "Got a message! (%s)\n", ((WvString)msg).cstr()); mysignal_count++; return true; // we handle *any* message } else { fprintf(stderr, "Ignored a message! (%s)\n", ((WvString)msg).cstr()); return false; } } WVTEST_MAIN("dbusserver basics") { int junk; TestDBusServer serv; WvDBusConn conn1(serv.moniker); WvIStreamList::globallist.append(&conn1, false, "dbus connection"); conn1.request_name("ca.nit.MySender"); conn1.add_callback(WvDBusConn::PriNormal, mysignal, &junk); WVPASSEQ(mysignal_count, 0); WvDBusMsg("ca.nit.MySender", "/foo", "x.y.z.anything", "testmethod") .append("hello").send(conn1); WvDBusSignal("/foo", "x.y.z.anything", "testsignal") .append("hello").send(conn1); while (mysignal_count < 2) WvIStreamList::globallist.runonce(); WVPASSEQ(mysignal_count, 2); } static int replies_received = 0; static bool reply_received(WvDBusMsg &msg) { WvDBusMsg::Iter i(msg); WvString s = i.getnext(); fprintf(stderr, "wow! reply received! (%s)\n", s.cstr()); WVPASS(!!msg.get_sender()); replies_received++; return true; } static int messages_received = 0; static bool msg_received(WvDBusConn &conn, WvDBusMsg &msg) { WvDBusMsg::Iter i(msg); WvString arg1 = i.getnext(); if (msg.get_dest() == "ca.nit.MyListener" && msg.get_path() == "/ca/nit/foo" && msg.get_member() == "bar") { fprintf(stderr, "Message received (%s)\n", ((WvString)msg).cstr()); WVPASS(!!msg.get_sender()); messages_received++; msg.reply().append(WvString("baz %s", arg1)).send(conn); return true; } else { fprintf(stderr, "msg_received: not my message.\n"); return false; } } static int reg_count = 0; bool name_registered(WvDBusMsg &msg) { reg_count++; return true; } WVTEST_MAIN("dbusserver two connections") { TestDBusServer serv; WvDBusConn conn1(serv.moniker); WvDBusConn conn2(serv.moniker); WvIStreamList::globallist.append(&conn1, false, "dbus connection 1"); WvIStreamList::globallist.append(&conn2, false, "dbus connection 2"); conn2.add_callback(WvDBusConn::PriNormal, wv::bind(msg_received, wv::ref(conn2), _1)); reg_count = 0; conn1.request_name("ca.nit.MySender", name_registered); conn2.request_name("ca.nit.MyListener", name_registered); while (reg_count < 2) WvIStreamList::globallist.runonce(); WvDBusMsg msg("ca.nit.MyListener", "/ca/nit/foo", "ca.nit.foo", "bar"); msg.append("bee"); conn1.send(msg, reply_received); while (replies_received < 1 || messages_received < 1) WvIStreamList::globallist.runonce(); WVPASSEQ(messages_received, 1); WVPASSEQ(replies_received, 1); } WVTEST_MAIN("dbusserver overlapping registrations") { TestDBusServer serv; WvDBusConn *cli = new WvDBusConn(serv.moniker); WvDBusConn *l1 = new WvDBusConn(serv.moniker); WvDBusConn *l2 = new WvDBusConn(serv.moniker); WvIStreamList::globallist.append(cli, false, "dbus connection 1"); WvIStreamList::globallist.append(l1, false, "dbus connection 2"); WvIStreamList::globallist.append(l2, false, "dbus connection 3"); reg_count = 0; l1->request_name("ca.nit.MySender", name_registered); while (reg_count < 1) WvIStreamList::globallist.runonce(); l1->add_callback(WvDBusConn::PriNormal, mysignal); l2->add_callback(WvDBusConn::PriNormal, mysignal); WvDBusMsg meth("ca.nit.MySender", "/foo", "x.y.z.anything", "testmethod"); meth.append("methhello"); WvDBusSignal sig("/foo", "x.y.z.anything", "testsignal"); sig.append("sighello"); mysignal_count = 0; cli->send(sig); cli->send(meth, mysignal); while (mysignal_count < 3 || WvIStreamList::globallist.select(200)) WvIStreamList::globallist.runonce(); WVPASSEQ(mysignal_count, 3); // one method, two signals mysignal_count = 0; delete l1; cli->send(sig); #if NO_DBUS_PENDING_MEMORY_LEAK // this seems to cause a memory leak in dbus 0.60, since nobody cleans up // the remaining DBusPendingCall objects if a connection closes. Browsing // the source code for later versions, this seems to have been fixed, but // I haven't tried it yet. Anyway, it's not our bug. The cleanup // activity in newer dbus may reveal that we have a bug too, of course. cli->send(meth, mysignal); #endif while (mysignal_count < 1 || WvIStreamList::globallist.select(200)) WvIStreamList::globallist.runonce(); WVPASSEQ(mysignal_count, 1); // no method receiver, one signal mysignal_count = 0; reg_count = 0; l2->request_name("ca.nit.MySender", name_registered); while (reg_count < 1) WvIStreamList::globallist.runonce(); cli->send(sig); cli->send(meth, mysignal); while (mysignal_count < 2 || WvIStreamList::globallist.select(200)) WvIStreamList::globallist.runonce(); WVPASSEQ(mysignal_count, 2); // one method receiver, one signal delete cli; delete l2; } static bool got_uid = false; static bool check_uid(WvDBusMsg &msg) { fprintf(stderr, "Got a uid message! (%s)\n", ((WvString)msg).cstr()); if (msg.iserror()) WVPASS(wvgetuid() == WVUID_INVALID); else { WvDBusMsg::Iter i(msg); wvuid_t uid = i.getnext(); WVPASSEQ(wvgetuid(), uid); } got_uid = true; return true; // we handle *any* message } static bool got_uname = false; static bool check_uname(WvDBusMsg &msg) { fprintf(stderr, "Got a uname message! (%s)\n", ((WvString)msg).cstr()); if (msg.iserror()) WVPASS(wvgetuid() == WVUID_INVALID); else { WvDBusMsg::Iter i(msg); WvString uname = i.getnext(); WVPASSEQ(wv_username_from_uid(wvgetuid()), uname); } got_uname = true; return true; // we handle *any* message } WVTEST_MAIN("GetConnectionUnixUser") { TestDBusServer serv; WvDBusConn conn1(serv.moniker); WvIStreamList::globallist.append(&conn1, false, "dbus connection"); while (!conn1.uniquename()) WvIStreamList::globallist.runonce(); WvLog log("GetConnection", WvLog::Notice); log("Connection's uniquename: %s\n", conn1.uniquename()); conn1.send(WvDBusMsg("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetConnectionUnixUser") .append(conn1.uniquename().cstr()), check_uid); while (!got_uid) WvIStreamList::globallist.runonce(); WVPASS(got_uid); conn1.send(WvDBusMsg("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetConnectionUnixUserName") .append(conn1.uniquename().cstr()), check_uname); while (!got_uname) WvIStreamList::globallist.runonce(); WVPASS(got_uname); conn1.close(); } wvstreams-4.6.1/dbus/t/wvdbusmarshal.t.cc0000644000175000001440000000255711122167104017431 0ustar wlachusers#include "wvtest.h" #include "wvbuf.h" #include "wvdbusmsg.h" #include "wvstream.h" #include "wvstrutils.h" WVTEST_MAIN("dbusmarshal") { WvDBusMsg msg("a.b.c", "/d/e/f", "g.h.i", "j"), *decoded = NULL; msg.append("string1"); msg.append(2); msg.array_start("v") .varray_start("i").append(10).append(11).varray_end() .varray_start("s").append("wX").append("Yz").varray_end() .array_end() .append(42); WvDBusMsg msg2("a.a", "/", "c.c", "d"); WvDynBuf buf; decoded = WvDBusMsg::demarshal(buf); WVPASS(!decoded); msg.marshal(buf); WVPASS(buf.used() > 0); buf.putstr("BOOGA"); msg2.marshal(buf); size_t used = buf.used(); WVPASS(buf.used() > 0); WVPASSEQ(msg.get_argstr(), "string1,2,[{[10,11]},{[wX,Yz]}],42"); WVPASSEQ(msg2.get_argstr(), ""); wvout->print("%s\n", hexdump_buffer(buf.peek(0, used), used)); WVPASS(buf.used() > 0); decoded = WvDBusMsg::demarshal(buf); WVPASS(buf.used() > 5); // still data left WVPASS(decoded); if (decoded) WVPASSEQ(decoded->get_argstr(), "string1,2,[{[10,11]},{[wX,Yz]}],42"); if (buf.used() > 5) WVPASSEQ(buf.getstr(5), "BOOGA"); if (decoded) delete decoded; decoded = WvDBusMsg::demarshal(buf); WVPASS(buf.used() == 0); WVPASS(decoded); if (decoded) { WVPASSEQ(decoded->get_argstr(), ""); delete decoded; } } wvstreams-4.6.1/dbus/wvdbusserver.cc0000644000175000001440000002666611077124114016615 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * */ #include "wvdbusserver.h" #include "wvdbusconn.h" #include "wvstrutils.h" #include "wvuid.h" #include "wvtcplistener.h" #include "wvdelayedcallback.h" #undef interface // windows #include #include "wvx509.h" class WvDBusServerAuth : public IWvDBusAuth { enum State { NullWait, AuthWait, BeginWait }; State state; wvuid_t client_uid; public: WvDBusServerAuth(); virtual bool authorize(WvDBusConn &c); virtual wvuid_t get_uid() { return client_uid; } }; WvDBusServerAuth::WvDBusServerAuth() { state = NullWait; client_uid = WVUID_INVALID; } bool WvDBusServerAuth::authorize(WvDBusConn &c) { c.log("State=%s\n", state); if (state == NullWait) { char buf[1]; size_t len = c.read(buf, 1); if (len == 1 && buf[0] == '\0') { state = AuthWait; // fall through } else if (len > 0) c.seterr("Client didn't start with NUL byte"); else return false; // no data yet, come back later } const char *line = c.in(); if (!line) return false; // not done yet WvStringList words; words.split(line); WvString cmd(words.popstr()); if (state == AuthWait) { if (!strcasecmp(cmd, "AUTH")) { // FIXME actually check authentication information! WvString typ(words.popstr()); if (!strcasecmp(typ, "EXTERNAL")) { WvString uid = WvHexDecoder().strflushstr(words.popstr()); if (!!uid) { // FIXME: Check that client is on the same machine! client_uid = uid.num(); } state = BeginWait; c.out("OK f00f\r\n"); } else { // Some clients insist that we reject something because // their state machine can't handle us accepting just the // "AUTH " command. c.out("REJECTED EXTERNAL\r\n"); // no change in state } } else c.seterr("AUTH command expected: '%s'", line); } else if (state == BeginWait) { if (!strcasecmp(cmd, "BEGIN")) return true; // done else c.seterr("BEGIN command expected: '%s'", line); } return false; } WvDBusServer::WvDBusServer() : log("DBus Server", WvLog::Debug) { // user must now call listen() at least once. add(&listeners, false, "listeners"); } WvDBusServer::~WvDBusServer() { close(); zap(); } void WvDBusServer::listen(WvStringParm moniker) { IWvListener *listener = IWvListener::create(moniker); log(WvLog::Info, "Listening on '%s'\n", *listener->src()); if (!listener->isok()) log(WvLog::Info, "Can't listen: %s\n", listener->errstr()); listener->onaccept(wv::bind(&WvDBusServer::new_connection_cb, this, _1)); listeners.add(listener, true, "listener"); } bool WvDBusServer::isok() const { if (geterr()) return false; WvIStreamList::Iter i(listeners); for (i.rewind(); i.next(); ) if (!i->isok()) return false; return WvIStreamList::isok(); } int WvDBusServer::geterr() const { return WvIStreamList::geterr(); } WvString WvDBusServer::get_addr() { // FIXME assumes tcp WvIStreamList::Iter i(listeners); for (i.rewind(); i.next(); ) if (i->isok()) return WvString("tcp:%s", *i->src()); return WvString(); } void WvDBusServer::register_name(WvStringParm name, WvDBusConn *conn) { name_to_conn[name] = conn; } void WvDBusServer::unregister_name(WvStringParm name, WvDBusConn *conn) { assert(name_to_conn[name] == conn); name_to_conn.erase(name); } void WvDBusServer::unregister_conn(WvDBusConn *conn) { { std::map::iterator i; for (i = name_to_conn.begin(); i != name_to_conn.end(); ) { if (i->second == conn) { name_to_conn.erase(i->first); i = name_to_conn.begin(); } else ++i; } } all_conns.unlink(conn); } bool WvDBusServer::do_server_msg(WvDBusConn &conn, WvDBusMsg &msg) { WvString method(msg.get_member()); if (msg.get_path() == "/org/freedesktop/DBus/Local") { if (method == "Disconnected") return true; // nothing to do until their *stream* disconnects } if (msg.get_dest() != "org.freedesktop.DBus") return false; // dbus-daemon seems to ignore the path as long as the service is right //if (msg.get_path() != "/org/freedesktop/DBus") return false; // I guess it's for us! if (method == "Hello") { log("hello_cb\n"); msg.reply().append(conn.uniquename()).send(conn); return true; } else if (method == "RequestName") { WvDBusMsg::Iter args(msg); WvString _name = args.getnext(); // uint32_t flags = args.getnext(); // supplied, but ignored log("request_name_cb(%s)\n", _name); register_name(_name, &conn); msg.reply().append((uint32_t)DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) .send(conn); return true; } else if (method == "ReleaseName") { WvDBusMsg::Iter args(msg); WvString _name = args.getnext(); log("release_name_cb(%s)\n", _name); unregister_name(_name, &conn); msg.reply().append((uint32_t)DBUS_RELEASE_NAME_REPLY_RELEASED) .send(conn); return true; } else if (method == "NameHasOwner") { WvDBusMsg::Iter args(msg); WvString known_name = args.getnext(); WvDBusConn *serv = name_to_conn[known_name]; msg.reply().append(!!serv).send(conn); return true; } else if (method == "GetNameOwner") { WvDBusMsg::Iter args(msg); WvString known_name = args.getnext(); WvDBusConn *serv = name_to_conn[known_name]; if (serv) msg.reply().append(serv->uniquename()).send(conn); else WvDBusError(msg, "org.freedesktop.DBus.Error.NameHasNoOwner", "No match for name '%s'", known_name).send(conn); return true; } else if (method == "AddMatch") { // we just proxy every signal to everyone for now msg.reply().send(conn); return true; } else if (method == "StartServiceByName") { // we don't actually support this, but returning an error message // confuses perl's Net::DBus library, at least. msg.reply().send(conn); return true; } else if (method == "GetConnectionUnixUser" || method == "GetConnectionUnixUserName") { WvDBusMsg::Iter args(msg); WvString _name = args.getnext(); WvDBusConn *target = name_to_conn[_name]; if (!target) { WvDBusError(msg, "org.freedesktop.DBus.Error.Failed", "No connection found for name '%s'.", _name).send(conn); return true; } wvuid_t client_uid = target->get_uid(); if (client_uid == WVUID_INVALID) { WvDBusError(msg, "org.freedesktop.DBus.Error.Failed", "No user associated with connection '%s'.", target->uniquename()).send(conn); return true; } log("Found unix user for '%s', uid is %s.\n", _name, client_uid); if (method == "GetConnectionUnixUser") { WvString s(client_uid); msg.reply().append((uint32_t)atoll(s)).send(conn); return true; } else if (method == "GetConnectionUnixUserName") { WvString username = wv_username_from_uid(client_uid); if (!username) { WvDBusError(msg, "org.freedesktop.DBus.Error.Failed", "No username for uid='%s'", client_uid) .send(conn); return true; } msg.reply().append(username).send(conn); return true; } else assert(false); // should never happen assert(false); } else if (method == "GetConnectionCert" || method == "GetConnectionCertFingerprint") { WvDBusMsg::Iter args(msg); WvString connid = args.getnext(); WvDBusConn *c = name_to_conn[connid]; WvString ret = c ? c->getattr("peercert") : WvString::null; if (ret.isnull()) WvDBusError(msg, "org.freedesktop.DBus.Error.Failed", "Connection %s did not present a certificate", connid).send(conn); else { if (method == "GetConnectionCertFingerprint") { WvX509 tempcert; // We can assume it's valid because our SSL conn authenticated tempcert.decode(WvX509::CertPEM, ret); ret = tempcert.get_fingerprint(); } msg.reply().append(ret).send(conn); } return true; } else { WvDBusError(msg, "org.freedesktop.DBus.Error.UnknownMethod", "Unknown dbus method '%s'", method).send(conn); return true; // but we've handled it, since it belongs to us } } bool WvDBusServer::do_bridge_msg(WvDBusConn &conn, WvDBusMsg &msg) { // if we get here, nobody handled the message internally, so we can try // to proxy it. if (!!msg.get_dest()) // don't handle blank (broadcast) paths here { std::map::iterator i = name_to_conn.find(msg.get_dest()); WvDBusConn *dconn = (i == name_to_conn.end()) ? NULL : i->second; log("Proxying #%s -> %s\n", msg.get_serial(), dconn ? dconn->uniquename() : WvString("(UNKNOWN)")); dbus_message_set_sender(msg, conn.uniquename().cstr()); if (dconn) dconn->send(msg); else { log(WvLog::Warning, "Proxy: no connection for '%s'\n", msg.get_dest()); return false; } return true; } return false; } bool WvDBusServer::do_broadcast_msg(WvDBusConn &conn, WvDBusMsg &msg) { if (!msg.get_dest()) { log("Broadcasting #%s\n", msg.get_serial()); // note: we broadcast messages even back to the connection where // they originated. I'm not sure this is necessarily ideal, but if // you don't do that then an app can't signal objects that might be // inside itself. WvDBusConnList::Iter i(all_conns); for (i.rewind(); i.next(); ) i->send(msg); return true; } return false; } bool WvDBusServer::do_gaveup_msg(WvDBusConn &conn, WvDBusMsg &msg) { WvDBusError(msg, "org.freedesktop.DBus.Error.NameHasNoOwner", "No running service named '%s'", msg.get_dest()).send(conn); return true; } void WvDBusServer::conn_closed(WvStream &s) { WvDBusConn *c = (WvDBusConn *)&s; unregister_conn(c); this->release(); } void WvDBusServer::new_connection_cb(IWvStream *s) { WvDBusConn *c = new WvDBusConn(s, new WvDBusServerAuth, false); c->addRef(); this->addRef(); all_conns.append(c, true); register_name(c->uniquename(), c); /* The delayed callback here should be explained. The * 'do_broadcast_msg' function sends out data along all connections. * Unfortunately, this is a prime time to figure out a connection died. * A dying connection is removed from the all_conns list... but we are * still in do_broadcast_msg, and using an iterator to go over this list. * The consequences of this were not pleasant, at best. Wrapping cb in a * delayedcallback will always safely remove a connection. */ IWvStreamCallback mycb = wv::bind(&WvDBusServer::conn_closed, this, wv::ref(*c)); c->setclosecallback(wv::delayed(mycb)); c->add_callback(WvDBusConn::PriSystem, wv::bind(&WvDBusServer::do_server_msg, this, wv::ref(*c), _1)); c->add_callback(WvDBusConn::PriBridge, wv::bind(&WvDBusServer::do_bridge_msg, this, wv::ref(*c), _1)); c->add_callback(WvDBusConn::PriBroadcast, wv::bind(&WvDBusServer::do_broadcast_msg, this, wv::ref(*c), _1)); c->add_callback(WvDBusConn::PriGaveUp, wv::bind(&WvDBusServer::do_gaveup_msg, this, wv::ref(*c), _1)); append(c, true, "wvdbus servconn"); } wvstreams-4.6.1/dbus/wvdbusmsg.cc0000644000175000001440000003114711122167104016060 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2004-2006 Net Integration Technologies, Inc. * * Pathfinder Software: * Copyright (C) 2007, Carillon Information Security Inc. * * This library is licensed under the LGPL, please read LICENSE for details. * */ #include "wvdbusmsg.h" #include "wvdbusconn.h" #include "wvstrutils.h" #undef interface // windows #include class WvDBusReplyMsg : public WvDBusMsg { public: /** * Constructs a new reply message (a message intended to be a reply to * an existing D-Bus message). * * Don't call this directly. Use WvDBusMsg::reply() instead. */ WvDBusReplyMsg(DBusMessage *_msg); virtual ~WvDBusReplyMsg() {} }; WvDBusMsg::Iter::Iter(const WvDBusMsg &_msg) : first(new DBusMessageIter), it(new DBusMessageIter) { dbus_message_iter_init(_msg, first); rewind(); } WvDBusMsg::Iter::Iter(const WvDBusMsg::Iter &_it) : first(new DBusMessageIter), it(new DBusMessageIter) { *first = *_it.first; rewind(); } WvDBusMsg::Iter::Iter(const DBusMessageIter &_first) : first(new DBusMessageIter), it(new DBusMessageIter) { *first = _first; rewind(); } WvDBusMsg::Iter::~Iter() { delete first; delete it; } void WvDBusMsg::Iter::rewind() { rewound = true; } bool WvDBusMsg::Iter::next() { if (rewound) *it = *first; else if (type() != DBUS_TYPE_INVALID) dbus_message_iter_next(it); rewound = false; return type() != DBUS_TYPE_INVALID; } int WvDBusMsg::Iter::type() const { return dbus_message_iter_get_arg_type(it); } WvDBusMsg::Iter WvDBusMsg::Iter::open() const { DBusMessageIter sub; dbus_message_iter_recurse(it, &sub); return Iter(sub); } bool WvDBusMsg::Iter::cur() const { return !rewound && type() != DBUS_TYPE_INVALID; } void WvDBusMsg::Iter::get_all(WvStringList &list) { int items = 0; for (rewind(); next() && items < 20; items++) list.append(get_str()); if (items == 20) list.append("..."); } WvString WvDBusMsg::Iter::get_all() { WvStringList list; get_all(list); return list.join(","); } WvString WvDBusMsg::Iter::get_str() const { char *s; double d; switch (type()) { case DBUS_TYPE_BYTE: // Don't do this: things like vxodbc expect to be able to atoi() // the resulting string! //return WvString("y%s", get_int()); case DBUS_TYPE_BOOLEAN: //return WvString("b%s", get_int()); case DBUS_TYPE_INT16: case DBUS_TYPE_INT32: case DBUS_TYPE_INT64: return get_int(); case DBUS_TYPE_UINT16: case DBUS_TYPE_UINT32: case DBUS_TYPE_UINT64: return get_uint(); case DBUS_TYPE_DOUBLE: dbus_message_iter_get_basic(it, &d); return d; case DBUS_TYPE_STRING: dbus_message_iter_get_basic(it, &s); return s; case DBUS_TYPE_VARIANT: return WvString("{%s}", open().getnext().get_str()); case DBUS_TYPE_STRUCT: case DBUS_TYPE_ARRAY: return WvString("[%s]", open().get_all()); case DBUS_TYPE_INVALID: return WvString(); default: return WvString("UNKNOWN_TYPE(%c)", type()); } } int64_t WvDBusMsg::Iter::get_int() const { dbus_bool_t b; unsigned char c; dbus_int16_t s; dbus_int32_t i; dbus_int64_t l; char *str; switch (type()) { case DBUS_TYPE_BYTE: dbus_message_iter_get_basic(it, &c); return c; case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(it, &b); return b; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: dbus_message_iter_get_basic(it, &s); return s; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: dbus_message_iter_get_basic(it, &i); return i; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: dbus_message_iter_get_basic(it, &l); return l; case DBUS_TYPE_STRING: dbus_message_iter_get_basic(it, &str); return WvString(str).num(); case DBUS_TYPE_VARIANT: return open().getnext().get_int(); default: return 0; } } uint64_t WvDBusMsg::Iter::get_uint() const { dbus_bool_t b; unsigned char c; dbus_uint16_t s; dbus_uint32_t i; dbus_uint64_t l; char *str; switch (type()) { case DBUS_TYPE_BYTE: dbus_message_iter_get_basic(it, &c); return c; case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(it, &b); return b; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: dbus_message_iter_get_basic(it, &s); return s; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: dbus_message_iter_get_basic(it, &i); return i; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: dbus_message_iter_get_basic(it, &l); return l; case DBUS_TYPE_STRING: dbus_message_iter_get_basic(it, &str); return WvString(str).num(); case DBUS_TYPE_VARIANT: return open().getnext().get_uint(); default: return 0; } } double WvDBusMsg::Iter::get_double() const { dbus_bool_t b; unsigned char c; dbus_uint16_t s; dbus_uint32_t i; dbus_uint64_t l; char *str; double d; switch (type()) { case DBUS_TYPE_DOUBLE: dbus_message_iter_get_basic(it, &d); return d; case DBUS_TYPE_BYTE: dbus_message_iter_get_basic(it, &c); return c; case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(it, &b); return b; case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: dbus_message_iter_get_basic(it, &s); return s; case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: dbus_message_iter_get_basic(it, &i); return i; case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: dbus_message_iter_get_basic(it, &l); return l; case DBUS_TYPE_STRING: dbus_message_iter_get_basic(it, &str); return atof(str); case DBUS_TYPE_VARIANT: return open().getnext().get_double(); default: return 0; } } WvString *WvDBusMsg::Iter::ptr() const { s = get_str(); return &s; } static DBusMessageIter *new_append_iter(WvDBusMsg &msg) { DBusMessageIter *it = new DBusMessageIter; dbus_message_iter_init_append(msg, it); return it; } WvDBusMsg::WvDBusMsg(WvStringParm busname, WvStringParm objectname, WvStringParm interface, WvStringParm method) { msg = dbus_message_new_method_call(busname, objectname, interface, method); itlist.prepend(new_append_iter(*this), true); } WvDBusMsg::WvDBusMsg(WvDBusMsg &_msg) { msg = _msg.msg; dbus_message_ref(msg); itlist.prepend(new_append_iter(*this), true); } WvDBusMsg::WvDBusMsg(DBusMessage *_msg) { msg = _msg; dbus_message_ref(msg); itlist.prepend(new_append_iter(*this), true); } WvDBusMsg::~WvDBusMsg() { dbus_message_unref(msg); } WvDBusMsg::operator DBusMessage* () const { return msg; } WvString WvDBusMsg::get_sender() const { return dbus_message_get_sender(msg); } WvString WvDBusMsg::get_dest() const { return dbus_message_get_destination(msg); } WvString WvDBusMsg::get_path() const { return dbus_message_get_path(msg); } WvString WvDBusMsg::get_interface() const { return dbus_message_get_interface(msg); } WvString WvDBusMsg::get_member() const { return dbus_message_get_member(msg); } WvString WvDBusMsg::get_error() const { if (iserror()) return dbus_message_get_error_name(msg); return WvString::null; } bool WvDBusMsg::is_reply() const { // This used to have a hack to deal with replies to message #0. // But it turns out the first message is #1, so that's not an actual // problem. return get_replyserial() != 0; } uint32_t WvDBusMsg::get_serial() const { return dbus_message_get_serial(msg); } uint32_t WvDBusMsg::get_replyserial() const { return dbus_message_get_reply_serial(msg); } void WvDBusMsg::get_arglist(WvStringList &list) const { Iter(*this).get_all(list); } WvString WvDBusMsg::get_argstr() const { return Iter(*this).get_all(); } WvDBusMsg::operator WvString() const { WvString dest(get_dest()); if (!dest) dest = ""; else dest = WvString("%s:", dest); if (is_reply()) { if (iserror()) return WvString("ERR#%s->%s#%s(%s)", get_serial(), dest, get_replyserial(), get_argstr()); else return WvString("REPLY#%s->%s#%s(%s)", get_serial(), dest, get_replyserial(), get_argstr()); } else { WvString s("%s%s/%s.%s(%s)#%s", dest, get_path(), get_interface(), get_member(), get_argstr(), get_serial()); s = strreplace(s, "org.freedesktop.DBus", "o.f.D"); s = strreplace(s, "org/freedesktop/DBus", "o/f/D"); return s; } } WvDBusMsg &WvDBusMsg::append(const char *s) { assert(msg); assert(s); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_STRING, &s); return *this; } WvDBusMsg &WvDBusMsg::append(bool b) { assert(msg); dbus_bool_t bb = b; dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_BOOLEAN, &bb); return *this; } WvDBusMsg &WvDBusMsg::append(signed char c) { assert(msg); dbus_unichar_t cc = c; dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_BYTE, &cc); return *this; } WvDBusMsg &WvDBusMsg::append(unsigned char c) { assert(msg); dbus_unichar_t cc = c; dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_BYTE, &cc); return *this; } WvDBusMsg &WvDBusMsg::append(int16_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_INT16, &i); return *this; } WvDBusMsg &WvDBusMsg::append(uint16_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_UINT16, &i); return *this; } WvDBusMsg &WvDBusMsg::append(int32_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_INT32, &i); return *this; } WvDBusMsg &WvDBusMsg::append(uint32_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_UINT32, &i); return *this; } WvDBusMsg &WvDBusMsg::append(int64_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_INT64, &i); return *this; } WvDBusMsg &WvDBusMsg::append(uint64_t i) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_UINT64, &i); return *this; } WvDBusMsg &WvDBusMsg::append(double d) { assert(msg); dbus_message_iter_append_basic(itlist.first(), DBUS_TYPE_DOUBLE, &d); return *this; } WvDBusMsg &WvDBusMsg::variant_start(WvStringParm element_type) { DBusMessageIter *parent = itlist.first(); DBusMessageIter *sub = new DBusMessageIter; dbus_message_iter_open_container(parent, DBUS_TYPE_VARIANT, element_type, sub); itlist.prepend(sub, true); return *this; } WvDBusMsg &WvDBusMsg::variant_end() { assert(itlist.count() >= 2); WvList::Iter i(itlist); i.rewind(); i.next(); DBusMessageIter *sub = i.ptr(); i.next(); DBusMessageIter *parent = i.ptr(); dbus_message_iter_close_container(parent, sub); itlist.unlink_first(); return *this; } WvDBusMsg &WvDBusMsg::struct_start(WvStringParm element_type) { DBusMessageIter *parent = itlist.first(); DBusMessageIter *sub = new DBusMessageIter; dbus_message_iter_open_container(parent, DBUS_TYPE_STRUCT, 0, sub); itlist.prepend(sub, true); return *this; } WvDBusMsg &WvDBusMsg::struct_end() { return array_end(); // same thing } WvDBusMsg &WvDBusMsg::array_start(WvStringParm element_type) { DBusMessageIter *parent = itlist.first(); DBusMessageIter *sub = new DBusMessageIter; dbus_message_iter_open_container(parent, DBUS_TYPE_ARRAY, element_type, sub); itlist.prepend(sub, true); return *this; } WvDBusMsg &WvDBusMsg::array_end() { return variant_end(); // same thing } WvDBusMsg &WvDBusMsg::varray_start(WvStringParm element_type) { variant_start(WvString("a%s", element_type)); return array_start(element_type); } WvDBusMsg &WvDBusMsg::varray_end() { assert(itlist.count() >= 3); array_end(); return variant_end(); } WvDBusMsg WvDBusMsg::reply() { return WvDBusReplyMsg(*this); } bool WvDBusMsg::iserror() const { return dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR; } void WvDBusMsg::send(WvDBusConn &conn) { conn.send(*this); } WvDBusReplyMsg::WvDBusReplyMsg(DBusMessage *_msg) : WvDBusMsg(dbus_message_new_method_return(_msg)) { dbus_message_unref(msg); } WvDBusSignal::WvDBusSignal(WvStringParm objectname, WvStringParm interface, WvStringParm name) : WvDBusMsg(dbus_message_new_signal(objectname, interface, name)) { dbus_message_unref(msg); } DBusMessage *WvDBusError::setup1(WvDBusMsg &in_reply_to, WvStringParm errname, WvStringParm message) { return dbus_message_new_error(in_reply_to, errname, message); } void WvDBusError::setup2() { dbus_message_unref(msg); } wvstreams-4.6.1/argp/0000755000175000001440000000000011260431131013513 5ustar wlachuserswvstreams-4.6.1/argp/configure.ac0000644000175000001440000000541111202637334016013 0ustar wlachusersdnl Process this file with autoconf to produce a configure script. dnl This configure.ac is only for building a standalone argp library. AC_PREREQ(2.54) AC_INIT(argp-ba.c) AM_INIT_AUTOMAKE(argp, standalone-1.3) AM_CONFIG_HEADER(config.h) # GNU libc defaults to supplying the ISO C library functions only. The # _GNU_SOURCE define enables these extensions, in particular we want # errno.h to declare program_invocation_name. Enable it on all # systems; no problems have been reported with it so far. AC_GNU_SOURCE # Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROGRAM_CHECK(AR,ar,ar,:) AC_PROGRAM_CHECK(AR,gar,gar,:) AM_PROG_CC_STDC AC_SUBST(AR) if test "x$am_cv_prog_cc_stdc" = xno ; then AC_ERROR([the C compiler doesn't handle ANSI-C]) fi # Checks for libraries. # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(limits.h malloc.h unistd.h) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T LSH_GCC_ATTRIBUTES # Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_VPRINTF AC_CHECK_FUNCS(strerror) AC_REPLACE_FUNCS(mempcpy strndup strchrnul) dnl ARGP_CHECK_FUNC(includes, function-call [, if-found [, if-not-found]]) AC_DEFUN([ARGP_CHECK_FUNC], [AS_VAR_PUSHDEF([ac_func], m4_substr([$2], 0, m4_index([$2], [(]))) AS_VAR_PUSHDEF([ac_var], [ac_cv_func_call_]ac_func) AH_TEMPLATE(AS_TR_CPP(HAVE_[]ac_func), [Define to 1 if you have the `]ac_func[' function.]) AC_CACHE_CHECK([for $2], ac_var, [AC_TRY_LINK([$1], [$2], [AS_VAR_SET(ac_var, yes)], [AS_VAR_SET(ac_var, no)])]) if test AS_VAR_GET(ac_var) = yes ; then ifelse([$3],, [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]ac_func))], [$3 ]) else ifelse([$4],, true, [$4]) fi AS_VAR_POPDEF([ac_var]) AS_VAR_POPDEF([ac_func]) ]) # At least on freebsd, putc_unlocked is a macro, so the standard # AC_CHECK_FUNCS doesn't work well. ARGP_CHECK_FUNC([#include ], [putc_unlocked('x', stdout)]) AC_CHECK_FUNCS(flockfile) AC_CHECK_FUNCS(fputs_unlocked fwrite_unlocked) # Used only by argp-test.c, so don't use AC_REPLACE_FUNCS. AC_CHECK_FUNCS(strdup asprintf) AC_CHECK_DECLS([program_invocation_name, program_invocation_short_name], [], [], [[#include ]]) # Set these flags *last*, or else the test programs won't compile if test x$GCC = xyes ; then # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then true else CFLAGS="$CFLAGS -ggdb3" fi CFLAGS="$CFLAGS -Wall -W \ -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ -Waggregate-return \ -Wpointer-arith -Wbad-function-cast -Wnested-externs" fi CPPFLAGS="$CPPFLAGS -I$srcdir" AC_OUTPUT(Makefile testsuite/Makefile) wvstreams-4.6.1/argp/argp-fmtstream.c0000644000175000001440000003075411077124114016627 0ustar wlachusers/* Word-wrapping and line-truncating streams Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This package emulates glibc `line_wrap_stream' semantics for systems that don't have that. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "argp-fmtstream.h" #include "argp-namefrob.h" #ifndef ARGP_FMTSTREAM_USE_LINEWRAP #ifndef isblank #define isblank(ch) ((ch)==' ' || (ch)=='\t') #endif #if defined _LIBC && defined USE_IN_LIBIO # include # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) #endif #define INIT_BUF_SIZE 200 #define PRINTF_SIZE_GUESS 150 /* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines written on it with LMARGIN spaces and limits them to RMARGIN columns total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by replacing the whitespace before them with a newline and WMARGIN spaces. Otherwise, chars beyond RMARGIN are simply dropped until a newline. Returns NULL if there was an error. */ argp_fmtstream_t __argp_make_fmtstream (FILE *stream, size_t lmargin, size_t rmargin, ssize_t wmargin) { argp_fmtstream_t fs = malloc (sizeof (struct argp_fmtstream)); if (fs) { fs->stream = stream; fs->lmargin = lmargin; fs->rmargin = rmargin; fs->wmargin = wmargin; fs->point_col = 0; fs->point_offs = 0; fs->buf = malloc (INIT_BUF_SIZE); if (! fs->buf) { free (fs); fs = 0; } else { fs->p = fs->buf; fs->end = fs->buf + INIT_BUF_SIZE; } } return fs; } #ifdef weak_alias weak_alias (__argp_make_fmtstream, argp_make_fmtstream) #endif /* Flush FS to its stream, and free it (but don't close the stream). */ void __argp_fmtstream_free (argp_fmtstream_t fs) { __argp_fmtstream_update (fs); if (fs->p > fs->buf) FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream); free (fs->buf); free (fs); } #ifdef weak_alias weak_alias (__argp_fmtstream_free, argp_fmtstream_free) #endif /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ void __argp_fmtstream_update (argp_fmtstream_t fs) { char *buf, *nl; size_t len; /* Scan the buffer for newlines. */ buf = fs->buf + fs->point_offs; while (buf < fs->p) { size_t r; if (fs->point_col == 0 && fs->lmargin != 0) { /* We are starting a new line. Print spaces to the left margin. */ const size_t pad = fs->lmargin; if (fs->p + pad < fs->end) { /* We can fit in them in the buffer by moving the buffer text up and filling in the beginning. */ memmove (buf + pad, buf, fs->p - buf); fs->p += pad; /* Compensate for bigger buffer. */ memset (buf, ' ', pad); /* Fill in the spaces. */ buf += pad; /* Don't bother searching them. */ } else { /* No buffer space for spaces. Must flush. */ size_t i; for (i = 0; i < pad; i++) PUTC_UNLOCKED (' ', fs->stream); } fs->point_col = pad; } len = fs->p - buf; nl = memchr (buf, '\n', len); if (fs->point_col < 0) fs->point_col = 0; if (!nl) { /* The buffer ends in a partial line. */ if (fs->point_col + len < fs->rmargin) { /* The remaining buffer text is a partial line and fits within the maximum line width. Advance point for the characters to be written and stop scanning. */ fs->point_col += len; break; } else /* Set the end-of-line pointer for the code below to the end of the buffer. */ nl = fs->p; } else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) { /* The buffer contains a full line that fits within the maximum line width. Reset point and scan the next line. */ fs->point_col = 0; buf = nl + 1; continue; } /* This line is too long. */ r = fs->rmargin - 1; if (fs->wmargin < 0) { /* Truncate the line by overwriting the excess with the newline and anything after it in the buffer. */ if (nl < fs->p) { memmove (buf + (r - fs->point_col), nl, fs->p - nl); fs->p -= buf + (r - fs->point_col) - nl; /* Reset point for the next line and start scanning it. */ fs->point_col = 0; buf += r + 1; /* Skip full line plus \n. */ } else { /* The buffer ends with a partial line that is beyond the maximum line width. Advance point for the characters written, and discard those past the max from the buffer. */ fs->point_col += len; fs->p -= fs->point_col - r; break; } } else { /* Do word wrap. Go to the column just past the maximum line width and scan back for the beginning of the word there. Then insert a line break. */ char *p, *nextline; int i; p = buf + (r + 1 - fs->point_col); while (p >= buf && !isblank (*p)) --p; nextline = p + 1; /* This will begin the next line. */ if (nextline > buf) { /* Swallow separating blanks. */ if (p >= buf) do --p; while (p >= buf && isblank (*p)); nl = p + 1; /* The newline will replace the first blank. */ } else { /* A single word that is greater than the maximum line width. Oh well. Put it on an overlong line by itself. */ p = buf + (r + 1 - fs->point_col); /* Find the end of the long word. */ do ++p; while (p < nl && !isblank (*p)); if (p == nl) { /* It already ends a line. No fussing required. */ fs->point_col = 0; buf = nl + 1; continue; } /* We will move the newline to replace the first blank. */ nl = p; /* Swallow separating blanks. */ do ++p; while (isblank (*p)); /* The next line will start here. */ nextline = p; } /* Note: There are a bunch of tests below for NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall at the end of the buffer, and NEXTLINE is in fact empty (and so we need not be careful to maintain its contents). */ if (nextline == buf + len + 1 ? fs->end - nl < fs->wmargin + 1 : nextline - (nl + 1) < fs->wmargin) { /* The margin needs more blanks than we removed. */ if (fs->end - fs->p > fs->wmargin + 1) /* Make some space for them. */ { size_t mv = fs->p - nextline; memmove (nl + 1 + fs->wmargin, nextline, mv); nextline = nl + 1 + fs->wmargin; len = nextline + mv - buf; *nl++ = '\n'; } else /* Output the first line so we can use the space. */ { if (nl > fs->buf) FWRITE_UNLOCKED (fs->buf, 1, nl - fs->buf, fs->stream); PUTC_UNLOCKED ('\n', fs->stream); len += buf - fs->buf; nl = buf = fs->buf; } } else /* We can fit the newline and blanks in before the next word. */ *nl++ = '\n'; if (nextline - nl >= fs->wmargin || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) /* Add blanks up to the wrap margin column. */ for (i = 0; i < fs->wmargin; ++i) *nl++ = ' '; else for (i = 0; i < fs->wmargin; ++i) PUTC_UNLOCKED (' ', fs->stream); /* Copy the tail of the original buffer into the current buffer position. */ if (nl < nextline) memmove (nl, nextline, buf + len - nextline); len -= nextline - buf; /* Continue the scan on the remaining lines in the buffer. */ buf = nl; /* Restore bufp to include all the remaining text. */ fs->p = nl + len; /* Reset the counter of what has been output this line. If wmargin is 0, we want to avoid the lmargin getting added, so we set point_col to a magic value of -1 in that case. */ fs->point_col = fs->wmargin ? fs->wmargin : -1; } } /* Remember that we've scanned as far as the end of the buffer. */ fs->point_offs = fs->p - fs->buf; } /* Ensure that FS has space for AMOUNT more bytes in its buffer, either by growing the buffer, or by flushing it. True is returned iff we succeed. */ int __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) { if ((size_t) (fs->end - fs->p) < amount) { ssize_t wrote; /* Flush FS's buffer. */ __argp_fmtstream_update (fs); wrote = FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream); if (wrote == fs->p - fs->buf) { fs->p = fs->buf; fs->point_offs = 0; } else { fs->p -= wrote; fs->point_offs -= wrote; memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); return 0; } if ((size_t) (fs->end - fs->buf) < amount) /* Gotta grow the buffer. */ { size_t new_size = fs->end - fs->buf + amount; char *new_buf = realloc (fs->buf, new_size); if (! new_buf) { __set_errno (ENOMEM); return 0; } fs->buf = new_buf; fs->end = new_buf + new_size; fs->p = fs->buf; } } return 1; } ssize_t __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) { size_t out; size_t avail; size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ do { va_list args; if (! __argp_fmtstream_ensure (fs, size_guess)) return -1; va_start (args, fmt); avail = fs->end - fs->p; out = __vsnprintf (fs->p, avail, fmt, args); va_end (args); if (out >= avail) size_guess = out + 1; } while (out >= avail); fs->p += out; return out; } #ifdef weak_alias weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) #endif /* Duplicate the inline definitions in argp-fmtstream.h, for compilers * that don't do inlining. */ size_t __argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len) { if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) { memcpy (__fs->p, __str, __len); __fs->p += __len; return __len; } else return 0; } int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str) { size_t __len = strlen (__str); if (__len) { size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); return __wrote == __len ? 0 : -1; } else return 0; } int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) { if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) return *__fs->p++ = __ch; else return EOF; } /* Set __FS's left margin to __LMARGIN and return the old value. */ size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->lmargin; __fs->lmargin = __lmargin; return __old; } /* Set __FS's right margin to __RMARGIN and return the old value. */ size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->rmargin; __fs->rmargin = __rmargin; return __old; } /* Set FS's wrap margin to __WMARGIN and return the old value. */ size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->wmargin; __fs->wmargin = __wmargin; return __old; } /* Return the column number of the current output point in __FS. */ size_t __argp_fmtstream_point (argp_fmtstream_t __fs) { if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); return __fs->point_col >= 0 ? __fs->point_col : 0; } #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ wvstreams-4.6.1/argp/missing0000755000175000001440000002466611077124114015136 0ustar wlachusers#! /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: wvstreams-4.6.1/argp/ChangeLog0000644000175000001440000002327511077124114015304 0ustar wlachusers2004-02-23 Niels Möller * configure.ac: Bumped version to standalone-1.3. Portability to Mac OS X (fixes by Akim Demaille) * argp/Makefile.am (libargp_a_SOURCES): Remove the duplicate inclusion of argp-eexst.c. * argp/argp-ba.c, argp/argp-pv.c, argp/argp-pvh.c: Initialize the variables, otherwise on Darwin linking fails if the user does not define these variables. 2003-04-28 Niels Möller * argp-parse.c: Use standard alloca blurb from the autoconf manual. * argp-help.c: Updated alloca blurb to use the same as argp-parse.c. 2003-04-24 Niels Möller * argp.h: Added workaround for __restrict. 2003-03-13 Niels Möller * Released argp-standalone-1.2. * Updated copyright years. 2003-03-03 Niels Möller * argp-fmtstream.h: Don't include config.h here, let the .c-files do that. Deleted definition of PRINTF_STYLE, that's in config.h. When defining or disabling i/o locking functions, use uppercase macro names like PUTC_UNLOCKED. This avoids conflicts if the underlying functions are really macros defined by stdio. For example on freebsd. Updated the files using these functions. 2003-03-02 Niels Möller * argp-help.c: Don't include malloc.h. If any system still needs it, we need a configure test for it. (hol_entry_help): Don't use a non-constant initializer, as that's a GNU C extension. 2003-02-23 Niels Moller * configure.ac: Use LSH_GCC_ATTRIBUTES. Deleted the definition of UNUSED from the files that used it, it's now in config.h. 2003-02-16 Niels Möller * argp-fmtstream.h: When disabling fwrite_unlocked, #undef it first. * testsuite/permute-test: diff -q is not portable. Redirect to /dev/null instead. 2003-02-12 Niels Möller * argp-fmtstream.h: When disabling putc_unlocked, #undef it first. 2003-02-10 Niels Möller * configure.ac (ARGP_CHECK_FUNC): Use AS_VAR_GET. Use AH_TEMPLATE. 2003-02-10 Niels Möller * configure.ac (ARGP_CHECK_FUNC): New macro. Use it to test for putc_unlocked. 2003-02-05 Niels Möller * argp-parse.c (argp_default_options): Fixed initializer. * argp-test.c (options): Likewise. * testsuite/permute-test (die): Fixed sh-compatible function definition. * testsuite/ex4.c: Don't use error.h and the error function. * .bootstrap: New file. 2003-02-05 Niels Möller * Makefile.am (all): Deleted the explicit all target. (LIBOBJS): Added explicit substitution. * testsuite/ex3.c, testsuite/ex4.c: Complete initializers, to avoid warnings from gcc. * configure.ac: Updated for current autoconf and automake. Fixed AC_CONFIG_HEADER call. Use AC_GNU_SOURCE. Use AC_CHECK_DECLS to check for program_invocation_name and program_invocation_short_name. * argp-test.c (sub_options): Complete initializer, to avoid warnings from gcc. (sub_argp): Likewise. (options): Likewise. * argp-parse.c (argp_default_parser): HAVE_PROGRAM_INVOCATION_SHORT_NAME renamed to HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME. (argp_default_options): Complete initializer, to avoid warnings from gcc. * argp-help.c (uparam_names): Complete initializer, to avoid warnings from gcc. (__argp_short_program_name): HAVE_PROGRAM_INVOCATION_NAME renamed to HAVE_DECL_PROGRAM_INVOCATION_NAME. Similarly for HAVE_PROGRAM_INVOCATION_SHORT_NAME. * acinclude.m4: Deleted file. 2003-02-04 Niels Möller * configure.ac: Bumped version to standalone-1.2. * argp-parse.c (parser_parse_next): Call exchange before processing the final arguments. Fixes bug reported by Akim Demaille. * Makefile.am (SUBDIRS): Added testsuite. * configure.ac: Output testsuite/Makefile. * testsuite/run-tests: Script copied from nettle. * testsuite/permute-test: New testcase, exercising argument option permuting. * testsuite/ex1-test: New testcase. * testsuite/ex1.c, testsuite/ex3.c, testsuite/ex4.c: Added glibc example programs. 2002-07-18 Niels Möller * configure.ac: Don't use -ggdb3 with gcc-2.96. 2002-05-06 Niels Möller * configure.ac: Use AH_TEMPLATE for PROGRAM_INVOCATION_NAME and PROGRAM_INVOCATION_SHORT_NAME. The third arg to AC_DEFINE_UNQUOTED seems not to work here. 2002-05-05 Niels Möller * acconfig.h: Deleted file. * configure.ac: Pass no arguments to AM_INIT_AUTOMAKE. Don't substitute LIBOBJS. * acinclude.m4: Use the three-argument form of AC_DEFINE_UNQUOTED. * configure.ac: Update for automake-1.6. * configure.ac: Renamed file, used to be configure.in. 2001-03-26 Niels Möller * configure.in: Bumped argp version to standalone-1.1. 2001-03-26 Niels Möller * configure.in (CPPFLAGS): Added -D_GNU_SOURCE. 2001-02-18 Niels Möller * argp-parse.c (argp_default_parser): Let OPT_HANG print the process id to stderr. 2001-01-15 Niels Möller * argp.h: #define PRINTF_STYLE, and use it instead of using __attribute__ directly. 2001-01-07 Niels Möller * argp.h: Added _argp_short_program_name and __argp_short_program_name. * argp-parse.c (parser_init): Use argp_short_program_name. (parser_parse_next): Removed old permutation handling code. 2001-01-06 Niels Möller * argp-namefrob.h: Added _argp_short_program_name. 2001-01-02 Niels Möller * argp-help.c (hol_entry_help): Avoid using a non-constant struct initializer. (UNUSED): Define as a macro expanding to __attribute__ ..., if compiling with gcc. * argp-fmtstream.h (PRINTF_STYLE): Define this macro, to expand to __attribute__ ... if compiling with gcc. * argp-fmtstream.c (__argp_fmtstream_write, __argp_fmtstream_puts, __argp_fmtstream_putc): Duplicate the inline definitions in argp-fmtstream.h, for compilers that don't do inlining. 2000-12-28 Niels Möller * argp-help.c (fill_in_uparams): Use unsigned char * for VAR and ARG. Fixed calls of isalnum, isspace and friends, reported by Kalle Olavi Niemitalo. (canon_doc_option): Fixed calls of isalnum, isspace and friends, reported by Kalle Olavi Niemitalo. (hol_entry_cmp): Fixed calls of tolower, reported by Kalle Olavi Niemitalo. 2000-12-23 Niels Möller * acinclude.m4: New file. * acinclude.m4: Reverted the definition of AC_CHECK_VAR to take includes as argument, and renamed it to ARGP_CHECK_VAR. 2000-12-11 Niels Möller * Removed getopt.c, getopt.h and getopt1.c from the src/argp directory. * argp-parse.c (match_option, ARGP_COMPLETE): #if:ed out completion code for long options. 2000-11-30 Niels Möller * argp-parse.c (match_option): Better abbreviations. Replaced try_getopt with args_only, changed calling convention for parser_parse_arg. * configure.in: Don't check for getopt. * argp.h: Don't include getopt.h. * argp-parse.c (calc_sizes): Updated comment. 2000-11-29 Niels Möller * configure.in: Use AC_REPLACE_FUNCS for mempcpy, strndup and strchrnul. (AC_CHECK_VAR): Changed second argument to take the type of the variable. * argp-parse.c (struct parser): New fields posixly_correct and ordering. (parser_init): Choose ordering. (enum arg_type): New value ARG_LONG_ONLY. (parser_parse_next): Added error messages similar to getopt's. * argp-help.c (STRNDUP): New macro to refer to strndup or __strndup, as appropriate. (STRERROR): Define this macro as a wrapper for strerror or sys_errlist. (__argp_basename): New function. * argp-namefrob.h (__argp_basename): Added __argp_basename. * Makefile.am (libargp_a_LIBADD): Include LIBOBJS in libargp.a. * argp.h: Added prototype for _argp_basename and __argp_basename. * strndup.c, strchrnul.c mempcpy.c: Moved replacement functions to separate files. 2000-11-28 Niels Möller * argp-parse.c: Deleted getopt-related code. (struct parser): New field nextchar. Deleted fields try_getotp and long_opts. (find_short_option): New function. (match_option): New function. (find_long_option): New function. (struct parser_convert_state): Deleted field long_end. (convert_options): Don't build getopt_long-style option array. (parser_convert): Deleted FLAGS arument. (struct parser_sizes): Deleted field long_len. (parser_init): Set short_opts to NULL, unless ARGP_LONG_ONLY is used. (classify_arg): New function. (parser_parse_next): Don't use getopt_long(). 2000-11-27 Niels Möller * argp-help.c (argp_doc): Use the name strndup, not __strndup. That probably breaks glibc builds. 2000-11-27 Niels Möller * argp-test.c (asprintf): Bug fix. * argp.h: Dummy definition of __THROW. * argp-test.c: Fixed asprintf implementation. * argp-parse.c (__argp_usage, __option_is_short, __option_is_end): Define these function, in case the user isn't inlining them. * argp-help.c: #define __mempcpy if needed. Use unsigned arguments to the ctype macros. Handle systems where program_invocation_name and program_invocation_short_name doesn't exist. * argp-help.c (short_program_name): New function. * Makefile.am: Use @LIBOBJS@ when building test program. * configure.in: Check for getopt_long. Substitute LIBOBJS. Add -I$srcdir to CPPFLAGS. * src/argp: Added getopt.h, getopt.c and getopt1.c, which are needed for separate compilation of argp. 2000-11-27 Niels Möller * Updated argp from glibc-2.2. wvstreams-4.6.1/argp/argp-help.c0000644000175000001440000015401411077124114015551 0ustar wlachusers/* Hierarchial argument parsing help output Copyright (C) 1995,96,97,98,99,2000, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #ifdef HAVE_CONFIG_H #include #endif /* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif #include #include #include #include #include #include /* Does any system still need malloc.h? If so, we'd need a configure test. */ #ifdef _WIN32 #include #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. */ # if defined HAVE_LIBINTL_H || defined _LIBC # include # ifdef _LIBC # undef dgettext # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES) # endif # else # define dgettext(domain, msgid) (msgid) # endif #endif #include "argp.h" #include "argp-fmtstream.h" #include "argp-namefrob.h" #ifndef _LIBC # ifndef __strchrnul # define __strchrnul strchrnul # endif # ifndef __mempcpy # define __mempcpy mempcpy # endif /* We need to use a different name, as __strndup is likely a macro. */ # define STRNDUP strndup # if HAVE_STRERROR # define STRERROR strerror # else # define STRERROR(x) (sys_errlist[x]) # endif #else /* _LIBC */ # define FLOCKFILE __flockfile # define FUNLOCKFILE __funlockfile # define STRNDUP __strndup # define STRERROR strerror #endif #if !_LIBC # if !HAVE_STRNDUP char *strndup (const char *s, size_t size); # endif /* !HAVE_STRNDUP */ # if !HAVE_MEMPCPY void *mempcpy (void *to, const void *from, size_t size); # endif /* !HAVE_MEMPCPY */ # if !HAVE_STRCHRNUL char *strchrnul(const char *s, int c); # endif /* !HAVE_STRCHRNUL */ #endif /* !_LIBC */ /* User-selectable (using an environment variable) formatting parameters. These may be specified in an environment variable called `ARGP_HELP_FMT', with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 Where VALn must be a positive integer. The list of variables is in the UPARAM_NAMES vector, below. */ /* Default parameters. */ #define DUP_ARGS 0 /* True if option argument can be duplicated. */ #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ #define SHORT_OPT_COL 2 /* column in which short options start */ #define LONG_OPT_COL 6 /* column in which long options start */ #define DOC_OPT_COL 2 /* column in which doc options start */ #define OPT_DOC_COL 29 /* column in which option text starts */ #define HEADER_COL 1 /* column in which group headers are printed */ #define USAGE_INDENT 12 /* indentation of wrapped usage lines */ #define RMARGIN 79 /* right margin used for wrapping */ /* User-selectable (using an environment variable) formatting parameters. They must all be of type `int' for the parsing code to work. */ struct uparams { /* If true, arguments for an option are shown with both short and long options, even when a given option has both, e.g. `-x ARG, --longx=ARG'. If false, then if an option has both, the argument is only shown with the long one, e.g., `-x, --longx=ARG', and a message indicating that this really means both is printed below the options. */ int dup_args; /* This is true if when DUP_ARGS is false, and some duplicate arguments have been suppressed, an explanatory message should be printed. */ int dup_args_note; /* Various output columns. */ int short_opt_col; int long_opt_col; int doc_opt_col; int opt_doc_col; int header_col; int usage_indent; int rmargin; int valid; /* True when the values in here are valid. */ }; /* This is a global variable, as user options are only ever read once. */ static struct uparams uparams = { DUP_ARGS, DUP_ARGS_NOTE, SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, USAGE_INDENT, RMARGIN, 0 }; /* A particular uparam, and what the user name is. */ struct uparam_name { const char *name; /* User name. */ int is_bool; /* Whether it's `boolean'. */ size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ }; /* The name-field mappings we know about. */ static const struct uparam_name uparam_names[] = { { "dup-args", 1, offsetof (struct uparams, dup_args) }, { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, { "header-col", 0, offsetof (struct uparams, header_col) }, { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, { "rmargin", 0, offsetof (struct uparams, rmargin) }, { 0, 0, 0 } }; /* Read user options from the environment, and fill in UPARAMS appropiately. */ static void fill_in_uparams (const struct argp_state *state) { /* FIXME: Can we get away without an explicit cast? */ const unsigned char *var = (unsigned char *) getenv ("ARGP_HELP_FMT"); #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0); if (var) /* Parse var. */ while (*var) { SKIPWS (var); if (isalpha (*var)) { size_t var_len; const struct uparam_name *un; int unspec = 0, val = 0; const unsigned char *arg = var; while (isalnum (*arg) || *arg == '-' || *arg == '_') arg++; var_len = arg - var; SKIPWS (arg); if (*arg == '\0' || *arg == ',') unspec = 1; else if (*arg == '=') { arg++; SKIPWS (arg); } if (unspec) { if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') { val = 0; var += 3; var_len -= 3; } else val = 1; } else if (isdigit (*arg)) { val = atoi (arg); while (isdigit (*arg)) arg++; SKIPWS (arg); } for (un = uparam_names; un->name; un++) if (strlen (un->name) == var_len && strncmp (var, un->name, var_len) == 0) { if (unspec && !un->is_bool) __argp_failure (state, 0, 0, dgettext (state->root_argp->argp_domain, "\ %.*s: ARGP_HELP_FMT parameter requires a value"), (int) var_len, var); else *(int *)((char *)&uparams + un->uparams_offs) = val; break; } if (! un->name) __argp_failure (state, 0, 0, dgettext (state->root_argp->argp_domain, "\ %.*s: Unknown ARGP_HELP_FMT parameter"), (int) var_len, var); var = arg; if (*var == ',') var++; } else if (*var) { __argp_failure (state, 0, 0, dgettext (state->root_argp->argp_domain, "Garbage in ARGP_HELP_FMT: %s"), var); break; } } } /* Returns true if OPT hasn't been marked invisible. Visibility only affects whether OPT is displayed or used in sorting, not option shadowing. */ #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) /* Returns true if OPT is an alias for an earlier option. */ #define oalias(opt) ((opt)->flags & OPTION_ALIAS) /* Returns true if OPT is an documentation-only entry. */ #define odoc(opt) ((opt)->flags & OPTION_DOC) /* Returns true if OPT is the end-of-list marker for a list of options. */ #define oend(opt) __option_is_end (opt) /* Returns true if OPT has a short option. */ #define oshort(opt) __option_is_short (opt) /* The help format for a particular option is like: -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... Where ARG will be omitted if there's no argument, for this option, or will be surrounded by "[" and "]" appropiately if the argument is optional. The documentation string is word-wrapped appropiately, and if the list of options is long enough, it will be started on a separate line. If there are no short options for a given option, the first long option is indented slighly in a way that's supposed to make most long options appear to be in a separate column. For example, the following output (from ps): -p PID, --pid=PID List the process PID --pgrp=PGRP List processes in the process group PGRP -P, -x, --no-parent Include processes without parents -Q, --all-fields Don't elide unusable fields (normally if there's some reason ps can't print a field for any process, it's removed from the output entirely) -r, --reverse, --gratuitously-long-reverse-option Reverse the order of any sort --session[=SID] Add the processes from the session SID (which defaults to the sid of the current process) Here are some more options: -f ZOT, --foonly=ZOT Glork a foonly -z, --zaza Snit a zar -?, --help Give this help list --usage Give a short usage message -V, --version Print program version The struct argp_option array for the above could look like: { {"pid", 'p', "PID", 0, "List the process PID"}, {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, {"no-parent", 'P', 0, 0, "Include processes without parents"}, {0, 'x', 0, OPTION_ALIAS}, {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" " if there's some reason ps can't" " print a field for any process, it's" " removed from the output entirely)" }, {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, "Add the processes from the session" " SID (which defaults to the sid of" " the current process)" }, {0,0,0,0, "Here are some more options:"}, {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, {"zaza", 'z', 0, 0, "Snit a zar"}, {0} } Note that the last three options are automatically supplied by argp_parse, unless you tell it not to with ARGP_NO_HELP. */ /* Returns true if CH occurs between BEG and END. */ static int find_char (char ch, char *beg, char *end) { while (beg < end) if (*beg == ch) return 1; else beg++; return 0; } struct hol_cluster; /* fwd decl */ struct hol_entry { /* First option. */ const struct argp_option *opt; /* Number of options (including aliases). */ unsigned num; /* A pointers into the HOL's short_options field, to the first short option letter for this entry. The order of the characters following this point corresponds to the order of options pointed to by OPT, and there are at most NUM. A short option recorded in a option following OPT is only valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's probably been shadowed by some other entry). */ char *short_options; /* Entries are sorted by their group first, in the order: 1, 2, ..., n, 0, -m, ..., -2, -1 and then alphabetically within each group. The default is 0. */ int group; /* The cluster of options this entry belongs to, or 0 if none. */ struct hol_cluster *cluster; /* The argp from which this option came. */ const struct argp *argp; }; /* A cluster of entries to reflect the argp tree structure. */ struct hol_cluster { /* A descriptive header printed before options in this cluster. */ const char *header; /* Used to order clusters within the same group with the same parent, according to the order in which they occurred in the parent argp's child list. */ int index; /* How to sort this cluster with respect to options and other clusters at the same depth (clusters always follow options in the same group). */ int group; /* The cluster to which this cluster belongs, or 0 if it's at the base level. */ struct hol_cluster *parent; /* The argp from which this cluster is (eventually) derived. */ const struct argp *argp; /* The distance this cluster is from the root. */ int depth; /* Clusters in a given hol are kept in a linked list, to make freeing them possible. */ struct hol_cluster *next; }; /* A list of options for help. */ struct hol { /* An array of hol_entry's. */ struct hol_entry *entries; /* The number of entries in this hol. If this field is zero, the others are undefined. */ unsigned num_entries; /* A string containing all short options in this HOL. Each entry contains pointers into this string, so the order can't be messed with blindly. */ char *short_options; /* Clusters of entries in this hol. */ struct hol_cluster *clusters; }; /* Create a struct hol from the options in ARGP. CLUSTER is the hol_cluster in which these entries occur, or 0, if at the root. */ static struct hol * make_hol (const struct argp *argp, struct hol_cluster *cluster) { char *so; const struct argp_option *o; const struct argp_option *opts = argp->options; struct hol_entry *entry; unsigned num_short_options = 0; struct hol *hol = malloc (sizeof (struct hol)); assert (hol); hol->num_entries = 0; hol->clusters = 0; if (opts) { int cur_group = 0; /* The first option must not be an alias. */ assert (! oalias (opts)); /* Calculate the space needed. */ for (o = opts; ! oend (o); o++) { if (! oalias (o)) hol->num_entries++; if (oshort (o)) num_short_options++; /* This is an upper bound. */ } hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); hol->short_options = malloc (num_short_options + 1); assert (hol->entries && hol->short_options); /* Fill in the entries. */ so = hol->short_options; for (o = opts, entry = hol->entries; ! oend (o); entry++) { entry->opt = o; entry->num = 0; entry->short_options = so; entry->group = cur_group = o->group ? o->group : ((!o->name && !o->key) ? cur_group + 1 : cur_group); entry->cluster = cluster; entry->argp = argp; do { entry->num++; if (oshort (o) && ! find_char (o->key, hol->short_options, so)) /* O has a valid short option which hasn't already been used.*/ *so++ = o->key; o++; } while (! oend (o) && oalias (o)); } *so = '\0'; /* null terminated so we can find the length */ } return hol; } /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the associated argp child list entry), INDEX, and PARENT, and return a pointer to it. ARGP is the argp that this cluster results from. */ static struct hol_cluster * hol_add_cluster (struct hol *hol, int group, const char *header, int index, struct hol_cluster *parent, const struct argp *argp) { struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); if (cl) { cl->group = group; cl->header = header; cl->index = index; cl->parent = parent; cl->argp = argp; cl->depth = parent ? parent->depth + 1 : 0; cl->next = hol->clusters; hol->clusters = cl; } return cl; } /* Free HOL and any resources it uses. */ static void hol_free (struct hol *hol) { struct hol_cluster *cl = hol->clusters; while (cl) { struct hol_cluster *next = cl->next; free (cl); cl = next; } if (hol->num_entries > 0) { free (hol->entries); free (hol->short_options); } free (hol); } static inline int hol_entry_short_iterate (const struct hol_entry *entry, int (*func)(const struct argp_option *opt, const struct argp_option *real, const char *domain, void *cookie), const char *domain, void *cookie) { unsigned nopts; int val = 0; const struct argp_option *opt, *real = entry->opt; char *so = entry->short_options; for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) if (oshort (opt) && *so == opt->key) { if (!oalias (opt)) real = opt; if (ovisible (opt)) val = (*func)(opt, real, domain, cookie); so++; } return val; } static inline int hol_entry_long_iterate (const struct hol_entry *entry, int (*func)(const struct argp_option *opt, const struct argp_option *real, const char *domain, void *cookie), const char *domain, void *cookie) { unsigned nopts; int val = 0; const struct argp_option *opt, *real = entry->opt; for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) if (opt->name) { if (!oalias (opt)) real = opt; if (ovisible (opt)) val = (*func)(opt, real, domain, cookie); } return val; } /* Iterator that returns true for the first short option. */ static inline int until_short (const struct argp_option *opt, const struct argp_option *real UNUSED, const char *domain UNUSED, void *cookie UNUSED) { return oshort (opt) ? opt->key : 0; } /* Returns the first valid short option in ENTRY, or 0 if there is none. */ static char hol_entry_first_short (const struct hol_entry *entry) { return hol_entry_short_iterate (entry, until_short, entry->argp->argp_domain, 0); } /* Returns the first valid long option in ENTRY, or 0 if there is none. */ static const char * hol_entry_first_long (const struct hol_entry *entry) { const struct argp_option *opt; unsigned num; for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) if (opt->name && ovisible (opt)) return opt->name; return 0; } /* Returns the entry in HOL with the long option name NAME, or 0 if there is none. */ static struct hol_entry * hol_find_entry (struct hol *hol, const char *name) { struct hol_entry *entry = hol->entries; unsigned num_entries = hol->num_entries; while (num_entries-- > 0) { const struct argp_option *opt = entry->opt; unsigned num_opts = entry->num; while (num_opts-- > 0) if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) return entry; else opt++; entry++; } return 0; } /* If an entry with the long option NAME occurs in HOL, set it's special sort position to GROUP. */ static void hol_set_group (struct hol *hol, const char *name, int group) { struct hol_entry *entry = hol_find_entry (hol, name); if (entry) entry->group = group; } /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. EQ is what to return if GROUP1 and GROUP2 are the same. */ static int group_cmp (int group1, int group2, int eq) { if (group1 == group2) return eq; else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) return group1 - group2; else return group2 - group1; } /* Compare clusters CL1 & CL2 by the order that they should appear in output. */ static int hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) { /* If one cluster is deeper than the other, use its ancestor at the same level, so that finding the common ancestor is straightforward. */ while (cl1->depth < cl2->depth) cl1 = cl1->parent; while (cl2->depth < cl1->depth) cl2 = cl2->parent; /* Now reduce both clusters to their ancestors at the point where both have a common parent; these can be directly compared. */ while (cl1->parent != cl2->parent) cl1 = cl1->parent, cl2 = cl2->parent; return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); } /* Return the ancestor of CL that's just below the root (i.e., has a parent of 0). */ static struct hol_cluster * hol_cluster_base (struct hol_cluster *cl) { while (cl->parent) cl = cl->parent; return cl; } /* Return true if CL1 is a child of CL2. */ static int hol_cluster_is_child (const struct hol_cluster *cl1, const struct hol_cluster *cl2) { while (cl1 && cl1 != cl2) cl1 = cl1->parent; return cl1 == cl2; } /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail that should be used for comparisons, and returns true iff it should be treated as a non-option. */ /* FIXME: Can we use unsigned char * for the argument? */ static int canon_doc_option (const char **name) { int non_opt; /* Skip initial whitespace. */ while (isspace ( (unsigned char) **name)) (*name)++; /* Decide whether this looks like an option (leading `-') or not. */ non_opt = (**name != '-'); /* Skip until part of name used for sorting. */ while (**name && !isalnum ( (unsigned char) **name)) (*name)++; return non_opt; } /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help listing. */ static int hol_entry_cmp (const struct hol_entry *entry1, const struct hol_entry *entry2) { /* The group numbers by which the entries should be ordered; if either is in a cluster, then this is just the group within the cluster. */ int group1 = entry1->group, group2 = entry2->group; if (entry1->cluster != entry2->cluster) { /* The entries are not within the same cluster, so we can't compare them directly, we have to use the appropiate clustering level too. */ if (! entry1->cluster) /* ENTRY1 is at the `base level', not in a cluster, so we have to compare it's group number with that of the base cluster in which ENTRY2 resides. Note that if they're in the same group, the clustered option always comes laster. */ return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); else if (! entry2->cluster) /* Likewise, but ENTRY2's not in a cluster. */ return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); else /* Both entries are in clusters, we can just compare the clusters. */ return hol_cluster_cmp (entry1->cluster, entry2->cluster); } else if (group1 == group2) /* The entries are both in the same cluster and group, so compare them alphabetically. */ { int short1 = hol_entry_first_short (entry1); int short2 = hol_entry_first_short (entry2); int doc1 = odoc (entry1->opt); int doc2 = odoc (entry2->opt); /* FIXME: Can we use unsigned char * instead? */ const char *long1 = hol_entry_first_long (entry1); const char *long2 = hol_entry_first_long (entry2); if (doc1) doc1 = canon_doc_option (&long1); if (doc2) doc2 = canon_doc_option (&long2); if (doc1 != doc2) /* `documentation' options always follow normal options (or documentation options that *look* like normal options). */ return doc1 - doc2; else if (!short1 && !short2 && long1 && long2) /* Only long options. */ return __strcasecmp (long1, long2); else /* Compare short/short, long/short, short/long, using the first character of long options. Entries without *any* valid options (such as options with OPTION_HIDDEN set) will be put first, but as they're not displayed, it doesn't matter where they are. */ { unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0; unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0; #ifdef _tolower int lower_cmp = _tolower (first1) - _tolower (first2); #else int lower_cmp = tolower (first1) - tolower (first2); #endif /* Compare ignoring case, except when the options are both the same letter, in which case lower-case always comes first. */ /* NOTE: The subtraction below does the right thing even with eight-bit chars: first1 and first2 are converted to int *before* the subtraction. */ return lower_cmp ? lower_cmp : first2 - first1; } } else /* Within the same cluster, but not the same group, so just compare groups. */ return group_cmp (group1, group2, 0); } /* Version of hol_entry_cmp with correct signature for qsort. */ static int hol_entry_qcmp (const void *entry1_v, const void *entry2_v) { return hol_entry_cmp (entry1_v, entry2_v); } /* Sort HOL by group and alphabetically by option name (with short options taking precedence over long). Since the sorting is for display purposes only, the shadowing of options isn't effected. */ static void hol_sort (struct hol *hol) { if (hol->num_entries > 0) qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), hol_entry_qcmp); } /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow any in MORE with the same name. */ static void hol_append (struct hol *hol, struct hol *more) { struct hol_cluster **cl_end = &hol->clusters; /* Steal MORE's cluster list, and add it to the end of HOL's. */ while (*cl_end) cl_end = &(*cl_end)->next; *cl_end = more->clusters; more->clusters = 0; /* Merge entries. */ if (more->num_entries > 0) { if (hol->num_entries == 0) { hol->num_entries = more->num_entries; hol->entries = more->entries; hol->short_options = more->short_options; more->num_entries = 0; /* Mark MORE's fields as invalid. */ } else /* Append the entries in MORE to those in HOL, taking care to only add non-shadowed SHORT_OPTIONS values. */ { unsigned left; char *so, *more_so; struct hol_entry *e; unsigned num_entries = hol->num_entries + more->num_entries; struct hol_entry *entries = malloc (num_entries * sizeof (struct hol_entry)); unsigned hol_so_len = strlen (hol->short_options); char *short_options = malloc (hol_so_len + strlen (more->short_options) + 1); __mempcpy (__mempcpy (entries, hol->entries, hol->num_entries * sizeof (struct hol_entry)), more->entries, more->num_entries * sizeof (struct hol_entry)); __mempcpy (short_options, hol->short_options, hol_so_len); /* Fix up the short options pointers from HOL. */ for (e = entries, left = hol->num_entries; left > 0; e++, left--) e->short_options += (short_options - hol->short_options); /* Now add the short options from MORE, fixing up its entries too. */ so = short_options + hol_so_len; more_so = more->short_options; for (left = more->num_entries; left > 0; e++, left--) { int opts_left; const struct argp_option *opt; e->short_options = so; for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) { int ch = *more_so; if (oshort (opt) && ch == opt->key) /* The next short option in MORE_SO, CH, is from OPT. */ { if (! find_char (ch, short_options, short_options + hol_so_len)) /* The short option CH isn't shadowed by HOL's options, so add it to the sum. */ *so++ = ch; more_so++; } } } *so = '\0'; free (hol->entries); free (hol->short_options); hol->entries = entries; hol->num_entries = num_entries; hol->short_options = short_options; } } hol_free (more); } /* Inserts enough spaces to make sure STREAM is at column COL. */ static void indent_to (argp_fmtstream_t stream, unsigned col) { int needed = col - __argp_fmtstream_point (stream); while (needed-- > 0) __argp_fmtstream_putc (stream, ' '); } /* Output to STREAM either a space, or a newline if there isn't room for at least ENSURE characters before the right margin. */ static void space (argp_fmtstream_t stream, size_t ensure) { if (__argp_fmtstream_point (stream) + ensure >= __argp_fmtstream_rmargin (stream)) __argp_fmtstream_putc (stream, '\n'); else __argp_fmtstream_putc (stream, ' '); } /* If the option REAL has an argument, we print it in using the printf format REQ_FMT or OPT_FMT depending on whether it's a required or optional argument. */ static void arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, const char *domain UNUSED, argp_fmtstream_t stream) { if (real->arg) { if (real->flags & OPTION_ARG_OPTIONAL) __argp_fmtstream_printf (stream, opt_fmt, dgettext (domain, real->arg)); else __argp_fmtstream_printf (stream, req_fmt, dgettext (domain, real->arg)); } } /* Helper functions for hol_entry_help. */ /* State used during the execution of hol_help. */ struct hol_help_state { /* PREV_ENTRY should contain the previous entry printed, or 0. */ struct hol_entry *prev_entry; /* If an entry is in a different group from the previous one, and SEP_GROUPS is true, then a blank line will be printed before any output. */ int sep_groups; /* True if a duplicate option argument was suppressed (only ever set if UPARAMS.dup_args is false). */ int suppressed_dup_arg; }; /* Some state used while printing a help entry (used to communicate with helper functions). See the doc for hol_entry_help for more info, as most of the fields are copied from its arguments. */ struct pentry_state { const struct hol_entry *entry; argp_fmtstream_t stream; struct hol_help_state *hhstate; /* True if nothing's been printed so far. */ int first; /* If non-zero, the state that was used to print this help. */ const struct argp_state *state; }; /* If a user doc filter should be applied to DOC, do so. */ static const char * filter_doc (const char *doc, int key, const struct argp *argp, const struct argp_state *state) { if (argp->help_filter) /* We must apply a user filter to this output. */ { void *input = __argp_input (argp, state); return (*argp->help_filter) (key, doc, input); } else /* No filter. */ return doc; } /* Prints STR as a header line, with the margin lines set appropiately, and notes the fact that groups should be separated with a blank line. ARGP is the argp that should dictate any user doc filtering to take place. Note that the previous wrap margin isn't restored, but the left margin is reset to 0. */ static void print_header (const char *str, const struct argp *argp, struct pentry_state *pest) { const char *tstr = dgettext (argp->argp_domain, str); const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); if (fstr) { if (*fstr) { if (pest->hhstate->prev_entry) /* Precede with a blank line. */ __argp_fmtstream_putc (pest->stream, '\n'); indent_to (pest->stream, uparams.header_col); __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); __argp_fmtstream_puts (pest->stream, fstr); __argp_fmtstream_set_lmargin (pest->stream, 0); __argp_fmtstream_putc (pest->stream, '\n'); } pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ } if (fstr != tstr) free ((char *) fstr); } /* Inserts a comma if this isn't the first item on the line, and then makes sure we're at least to column COL. If this *is* the first item on a line, prints any pending whitespace/headers that should precede this line. Also clears FIRST. */ static void comma (unsigned col, struct pentry_state *pest) { if (pest->first) { const struct hol_entry *pe = pest->hhstate->prev_entry; const struct hol_cluster *cl = pest->entry->cluster; if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) __argp_fmtstream_putc (pest->stream, '\n'); if (cl && cl->header && *cl->header && (!pe || (pe->cluster != cl && !hol_cluster_is_child (pe->cluster, cl)))) /* If we're changing clusters, then this must be the start of the ENTRY's cluster unless that is an ancestor of the previous one (in which case we had just popped into a sub-cluster for a bit). If so, then print the cluster's header line. */ { int old_wm = __argp_fmtstream_wmargin (pest->stream); print_header (cl->header, cl->argp, pest); __argp_fmtstream_set_wmargin (pest->stream, old_wm); } pest->first = 0; } else __argp_fmtstream_puts (pest->stream, ", "); indent_to (pest->stream, col); } /* Print help for ENTRY to STREAM. */ static void hol_entry_help (struct hol_entry *entry, const struct argp_state *state, argp_fmtstream_t stream, struct hol_help_state *hhstate) { unsigned num; const struct argp_option *real = entry->opt, *opt; char *so = entry->short_options; int have_long_opt = 0; /* We have any long options. */ /* Saved margins. */ int old_lm = __argp_fmtstream_set_lmargin (stream, 0); int old_wm = __argp_fmtstream_wmargin (stream); /* PEST is a state block holding some of our variables that we'd like to share with helper functions. */ /* Decent initializers are a GNU extension, so don't use it here. */ struct pentry_state pest; pest.entry = entry; pest.stream = stream; pest.hhstate = hhstate; pest.first = 1; pest.state = state; if (! odoc (real)) for (opt = real, num = entry->num; num > 0; opt++, num--) if (opt->name && ovisible (opt)) { have_long_opt = 1; break; } /* First emit short options. */ __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ for (opt = real, num = entry->num; num > 0; opt++, num--) if (oshort (opt) && opt->key == *so) /* OPT has a valid (non shadowed) short option. */ { if (ovisible (opt)) { comma (uparams.short_opt_col, &pest); __argp_fmtstream_putc (stream, '-'); __argp_fmtstream_putc (stream, *so); if (!have_long_opt || uparams.dup_args) arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); else if (real->arg) hhstate->suppressed_dup_arg = 1; } so++; } /* Now, long options. */ if (odoc (real)) /* A `documentation' option. */ { __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); for (opt = real, num = entry->num; num > 0; opt++, num--) if (opt->name && ovisible (opt)) { comma (uparams.doc_opt_col, &pest); /* Calling gettext here isn't quite right, since sorting will have been done on the original; but documentation options should be pretty rare anyway... */ __argp_fmtstream_puts (stream, dgettext (state->root_argp->argp_domain, opt->name)); } } else /* A real long option. */ { int first_long_opt = 1; __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); for (opt = real, num = entry->num; num > 0; opt++, num--) if (opt->name && ovisible (opt)) { comma (uparams.long_opt_col, &pest); __argp_fmtstream_printf (stream, "--%s", opt->name); if (first_long_opt || uparams.dup_args) arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, stream); else if (real->arg) hhstate->suppressed_dup_arg = 1; } } /* Next, documentation strings. */ __argp_fmtstream_set_lmargin (stream, 0); if (pest.first) { /* Didn't print any switches, what's up? */ if (!oshort (real) && !real->name) /* This is a group header, print it nicely. */ print_header (real->doc, entry->argp, &pest); else /* Just a totally shadowed option or null header; print nothing. */ goto cleanup; /* Just return, after cleaning up. */ } else { const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, real->doc) : 0; const char *fstr = filter_doc (tstr, real->key, entry->argp, state); if (fstr && *fstr) { unsigned int col = __argp_fmtstream_point (stream); __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); if (col > (unsigned int) (uparams.opt_doc_col + 3)) __argp_fmtstream_putc (stream, '\n'); else if (col >= (unsigned int) uparams.opt_doc_col) __argp_fmtstream_puts (stream, " "); else indent_to (stream, uparams.opt_doc_col); __argp_fmtstream_puts (stream, fstr); } if (fstr && fstr != tstr) free ((char *) fstr); /* Reset the left margin. */ __argp_fmtstream_set_lmargin (stream, 0); __argp_fmtstream_putc (stream, '\n'); } hhstate->prev_entry = entry; cleanup: __argp_fmtstream_set_lmargin (stream, old_lm); __argp_fmtstream_set_wmargin (stream, old_wm); } /* Output a long help message about the options in HOL to STREAM. */ static void hol_help (struct hol *hol, const struct argp_state *state, argp_fmtstream_t stream) { unsigned num; struct hol_entry *entry; struct hol_help_state hhstate = { 0, 0, 0 }; for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) hol_entry_help (entry, state, stream, &hhstate); if (hhstate.suppressed_dup_arg && uparams.dup_args_note) { const char *tstr = dgettext (state->root_argp->argp_domain, "\ Mandatory or optional arguments to long options are also mandatory or \ optional for any corresponding short options."); const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, state ? state->root_argp : 0, state); if (fstr && *fstr) { __argp_fmtstream_putc (stream, '\n'); __argp_fmtstream_puts (stream, fstr); __argp_fmtstream_putc (stream, '\n'); } if (fstr && fstr != tstr) free ((char *) fstr); } } /* Helper functions for hol_usage. */ /* If OPT is a short option without an arg, append its key to the string pointer pointer to by COOKIE, and advance the pointer. */ static int add_argless_short_opt (const struct argp_option *opt, const struct argp_option *real, const char *domain UNUSED, void *cookie) { char **snao_end = cookie; if (!(opt->arg || real->arg) && !((opt->flags | real->flags) & OPTION_NO_USAGE)) *(*snao_end)++ = opt->key; return 0; } /* If OPT is a short option with an arg, output a usage entry for it to the stream pointed at by COOKIE. */ static int usage_argful_short_opt (const struct argp_option *opt, const struct argp_option *real, const char *domain UNUSED, void *cookie) { argp_fmtstream_t stream = cookie; const char *arg = opt->arg; int flags = opt->flags | real->flags; if (! arg) arg = real->arg; if (arg && !(flags & OPTION_NO_USAGE)) { arg = dgettext (domain, arg); if (flags & OPTION_ARG_OPTIONAL) __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); else { /* Manually do line wrapping so that it (probably) won't get wrapped at the embedded space. */ space (stream, 6 + strlen (arg)); __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); } } return 0; } /* Output a usage entry for the long option opt to the stream pointed at by COOKIE. */ static int usage_long_opt (const struct argp_option *opt, const struct argp_option *real, const char *domain UNUSED, void *cookie) { argp_fmtstream_t stream = cookie; const char *arg = opt->arg; int flags = opt->flags | real->flags; if (! arg) arg = real->arg; if (! (flags & OPTION_NO_USAGE)) { if (arg) { arg = dgettext (domain, arg); if (flags & OPTION_ARG_OPTIONAL) __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); else __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); } else __argp_fmtstream_printf (stream, " [--%s]", opt->name); } return 0; } /* Print a short usage description for the arguments in HOL to STREAM. */ static void hol_usage (struct hol *hol, argp_fmtstream_t stream) { if (hol->num_entries > 0) { unsigned nentries; struct hol_entry *entry; char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); char *snao_end = short_no_arg_opts; /* First we put a list of short options without arguments. */ for (entry = hol->entries, nentries = hol->num_entries ; nentries > 0 ; entry++, nentries--) hol_entry_short_iterate (entry, add_argless_short_opt, entry->argp->argp_domain, &snao_end); if (snao_end > short_no_arg_opts) { *snao_end++ = 0; __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); } /* Now a list of short options *with* arguments. */ for (entry = hol->entries, nentries = hol->num_entries ; nentries > 0 ; entry++, nentries--) hol_entry_short_iterate (entry, usage_argful_short_opt, entry->argp->argp_domain, stream); /* Finally, a list of long options (whew!). */ for (entry = hol->entries, nentries = hol->num_entries ; nentries > 0 ; entry++, nentries--) hol_entry_long_iterate (entry, usage_long_opt, entry->argp->argp_domain, stream); } } /* Make a HOL containing all levels of options in ARGP. CLUSTER is the cluster in which ARGP's entries should be clustered, or 0. */ static struct hol * argp_hol (const struct argp *argp, struct hol_cluster *cluster) { const struct argp_child *child = argp->children; struct hol *hol = make_hol (argp, cluster); if (child) while (child->argp) { struct hol_cluster *child_cluster = ((child->group || child->header) /* Put CHILD->argp within its own cluster. */ ? hol_add_cluster (hol, child->group, child->header, child - argp->children, cluster, argp) /* Just merge it into the parent's cluster. */ : cluster); hol_append (hol, argp_hol (child->argp, child_cluster)) ; child++; } return hol; } /* Calculate how many different levels with alternative args strings exist in ARGP. */ static size_t argp_args_levels (const struct argp *argp) { size_t levels = 0; const struct argp_child *child = argp->children; if (argp->args_doc && strchr (argp->args_doc, '\n')) levels++; if (child) while (child->argp) levels += argp_args_levels ((child++)->argp); return levels; } /* Print all the non-option args documented in ARGP to STREAM. Any output is preceded by a space. LEVELS is a pointer to a byte vector the length returned by argp_args_levels; it should be initialized to zero, and updated by this routine for the next call if ADVANCE is true. True is returned as long as there are more patterns to output. */ static int argp_args_usage (const struct argp *argp, const struct argp_state *state, char **levels, int advance, argp_fmtstream_t stream) { char *our_level = *levels; int multiple = 0; const struct argp_child *child = argp->children; const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); if (fdoc) { const char *cp = fdoc; nl = __strchrnul (cp, '\n'); if (*nl != '\0') /* This is a `multi-level' args doc; advance to the correct position as determined by our state in LEVELS, and update LEVELS. */ { int i; multiple = 1; for (i = 0; i < *our_level; i++) cp = nl + 1, nl = __strchrnul (cp, '\n'); (*levels)++; } /* Manually do line wrapping so that it (probably) won't get wrapped at any embedded spaces. */ space (stream, 1 + nl - cp); __argp_fmtstream_write (stream, cp, nl - cp); } if (fdoc && fdoc != tdoc) free ((char *)fdoc); /* Free user's modified doc string. */ if (child) while (child->argp) advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); if (advance && multiple) { /* Need to increment our level. */ if (*nl) /* There's more we can do here. */ { (*our_level)++; advance = 0; /* Our parent shouldn't advance also. */ } else if (*our_level > 0) /* We had multiple levels, but used them up; reset to zero. */ *our_level = 0; } return !advance; } /* Print the documentation for ARGP to STREAM; if POST is false, then everything preceeding a `\v' character in the documentation strings (or the whole string, for those with none) is printed, otherwise, everything following the `\v' character (nothing for strings without). Each separate bit of documentation is separated a blank line, and if PRE_BLANK is true, then the first is as well. If FIRST_ONLY is true, only the first occurrence is output. Returns true if anything was output. */ static int argp_doc (const struct argp *argp, const struct argp_state *state, int post, int pre_blank, int first_only, argp_fmtstream_t stream) { const char *text; const char *inp_text; void *input = 0; int anything = 0; size_t inp_text_limit = 0; const char *doc = dgettext (argp->argp_domain, argp->doc); const struct argp_child *child = argp->children; if (doc) { char *vt = strchr (doc, '\v'); inp_text = post ? (vt ? vt + 1 : 0) : doc; inp_text_limit = (!post && vt) ? (vt - doc) : 0; } else inp_text = 0; if (argp->help_filter) /* We have to filter the doc strings. */ { if (inp_text_limit) /* Copy INP_TEXT so that it's nul-terminated. */ inp_text = STRNDUP (inp_text, inp_text_limit); input = __argp_input (argp, state); text = (*argp->help_filter) (post ? ARGP_KEY_HELP_POST_DOC : ARGP_KEY_HELP_PRE_DOC, inp_text, input); } else text = (const char *) inp_text; if (text) { if (pre_blank) __argp_fmtstream_putc (stream, '\n'); if (text == inp_text && inp_text_limit) __argp_fmtstream_write (stream, inp_text, inp_text_limit); else __argp_fmtstream_puts (stream, text); if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) __argp_fmtstream_putc (stream, '\n'); anything = 1; } if (text && text != inp_text) free ((char *) text); /* Free TEXT returned from the help filter. */ if (inp_text && inp_text_limit && argp->help_filter) free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ if (post && argp->help_filter) /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */ { text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); if (text) { if (anything || pre_blank) __argp_fmtstream_putc (stream, '\n'); __argp_fmtstream_puts (stream, text); free ((char *) text); if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) __argp_fmtstream_putc (stream, '\n'); anything = 1; } } if (child) while (child->argp && !(first_only && anything)) anything |= argp_doc ((child++)->argp, state, post, anything || pre_blank, first_only, stream); return anything; } /* Output a usage message for ARGP to STREAM. If called from argp_state_help, STATE is the relevent parsing state. FLAGS are from the set ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */ static void _help (const struct argp *argp, const struct argp_state *state, FILE *stream, unsigned flags, const char *name) { int anything = 0; /* Whether we've output anything. */ struct hol *hol = 0; argp_fmtstream_t fs; if (! stream) return; FLOCKFILE (stream); if (! uparams.valid) fill_in_uparams (state); fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); if (! fs) { FUNLOCKFILE (stream); return; } if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) { hol = argp_hol (argp, 0); /* If present, these options always come last. */ hol_set_group (hol, "help", -1); hol_set_group (hol, "version", -1); hol_sort (hol); } if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) /* Print a short `Usage:' message. */ { int first_pattern = 1, more_patterns; size_t num_pattern_levels = argp_args_levels (argp); char *pattern_levels = alloca (num_pattern_levels); memset (pattern_levels, 0, num_pattern_levels); do { int old_lm; int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); char *levels = pattern_levels; if (first_pattern) __argp_fmtstream_printf (fs, "%s %s", dgettext (argp->argp_domain, "Usage:"), name); else __argp_fmtstream_printf (fs, "%s %s", dgettext (argp->argp_domain, " or: "), name); /* We set the lmargin as well as the wmargin, because hol_usage manually wraps options with newline to avoid annoying breaks. */ old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); if (flags & ARGP_HELP_SHORT_USAGE) /* Just show where the options go. */ { if (hol->num_entries > 0) __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, " [OPTION...]")); } else /* Actually print the options. */ { hol_usage (hol, fs); flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ } more_patterns = argp_args_usage (argp, state, &levels, 1, fs); __argp_fmtstream_set_wmargin (fs, old_wm); __argp_fmtstream_set_lmargin (fs, old_lm); __argp_fmtstream_putc (fs, '\n'); anything = 1; first_pattern = 0; } while (more_patterns); } if (flags & ARGP_HELP_PRE_DOC) anything |= argp_doc (argp, state, 0, 0, 1, fs); if (flags & ARGP_HELP_SEE) { __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ Try `%s --help' or `%s --usage' for more information.\n"), name, name); anything = 1; } if (flags & ARGP_HELP_LONG) /* Print a long, detailed help message. */ { /* Print info about all the options. */ if (hol->num_entries > 0) { if (anything) __argp_fmtstream_putc (fs, '\n'); hol_help (hol, state, fs); anything = 1; } } if (flags & ARGP_HELP_POST_DOC) /* Print any documentation strings at the end. */ anything |= argp_doc (argp, state, 1, anything, 0, fs); if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) { if (anything) __argp_fmtstream_putc (fs, '\n'); __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "Report bugs to %s.\n"), argp_program_bug_address); anything = 1; } FUNLOCKFILE (stream); if (hol) hol_free (hol); __argp_fmtstream_free (fs); } /* Output a usage message for ARGP to STREAM. FLAGS are from the set ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */ void __argp_help (const struct argp *argp, FILE *stream, unsigned flags, char *name) { _help (argp, 0, stream, flags, name); } #ifdef weak_alias weak_alias (__argp_help, argp_help) #endif char *__argp_basename(char *name) { char *short_name = strrchr(name, '/'); return short_name ? short_name + 1 : name; } char * __argp_short_program_name(const struct argp_state *state) { if (state) return state->name; #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME return program_invocation_short_name; #elif HAVE_DECL_PROGRAM_INVOCATION_NAME return __argp_basename(program_invocation_name); #else /* !HAVE_DECL_PROGRAM_INVOCATION_NAME */ /* FIXME: What now? Miles suggests that it is better to use NULL, but currently the value is passed on directly to fputs_unlocked, so that requires more changes. */ # if __GNUC__ # warning No reasonable value to return return ""; # endif /* __GNUC__ */ #endif /* !HAVE_DECL_PROGRAM_INVOCATION_NAME */ } /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are from the set ARGP_HELP_*. */ void __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) { if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) { if (state && (state->flags & ARGP_LONG_ONLY)) flags |= ARGP_HELP_LONG_ONLY; _help (state ? state->root_argp : 0, state, stream, flags, __argp_short_program_name(state)); if (!state || ! (state->flags & ARGP_NO_EXIT)) { if (flags & ARGP_HELP_EXIT_ERR) exit (argp_err_exit_status); if (flags & ARGP_HELP_EXIT_OK) exit (0); } } } #ifdef weak_alias weak_alias (__argp_state_help, argp_state_help) #endif /* If appropriate, print the printf string FMT and following args, preceded by the program name and `:', to stderr, and followed by a `Try ... --help' message, then exit (1). */ void __argp_error (const struct argp_state *state, const char *fmt, ...) { if (!state || !(state->flags & ARGP_NO_ERRS)) { FILE *stream = state ? state->err_stream : stderr; if (stream) { va_list ap; FLOCKFILE (stream); FPUTS_UNLOCKED (__argp_short_program_name(state), stream); PUTC_UNLOCKED (':', stream); PUTC_UNLOCKED (' ', stream); va_start (ap, fmt); vfprintf (stream, fmt, ap); va_end (ap); PUTC_UNLOCKED ('\n', stream); __argp_state_help (state, stream, ARGP_HELP_STD_ERR); FUNLOCKFILE (stream); } } } #ifdef weak_alias weak_alias (__argp_error, argp_error) #endif /* Similar to the standard gnu error-reporting function error(), but will respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print to STATE->err_stream. This is useful for argument parsing code that is shared between program startup (when exiting is desired) and runtime option parsing (when typically an error code is returned instead). The difference between this function and argp_error is that the latter is for *parsing errors*, and the former is for other problems that occur during parsing but don't reflect a (syntactic) problem with the input. */ void __argp_failure (const struct argp_state *state, int status, int errnum, const char *fmt, ...) { if (!state || !(state->flags & ARGP_NO_ERRS)) { FILE *stream = state ? state->err_stream : stderr; if (stream) { FLOCKFILE (stream); FPUTS_UNLOCKED (__argp_short_program_name(state), stream); if (fmt) { va_list ap; PUTC_UNLOCKED (':', stream); PUTC_UNLOCKED (' ', stream); va_start (ap, fmt); vfprintf (stream, fmt, ap); va_end (ap); } if (errnum) { PUTC_UNLOCKED (':', stream); PUTC_UNLOCKED (' ', stream); fputs (STRERROR (errnum), stream); } PUTC_UNLOCKED ('\n', stream); FUNLOCKFILE (stream); if (status && (!state || !(state->flags & ARGP_NO_EXIT))) exit (status); } } } #ifdef weak_alias weak_alias (__argp_failure, argp_failure) #endif wvstreams-4.6.1/argp/argp-namefrob.h0000644000175000001440000000704611077124114016421 0ustar wlachusers/* Name frobnication for compiling argp outside of glibc Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !_LIBC /* This code is written for inclusion in gnu-libc, and uses names in the namespace reserved for libc. If we're not compiling in libc, define those names to be the normal ones instead. */ /* argp-parse functions */ #undef __argp_parse #define __argp_parse argp_parse #undef __option_is_end #define __option_is_end _option_is_end #undef __option_is_short #define __option_is_short _option_is_short #undef __argp_input #define __argp_input _argp_input /* argp-help functions */ #undef __argp_help #define __argp_help argp_help #undef __argp_error #define __argp_error argp_error #undef __argp_failure #define __argp_failure argp_failure #undef __argp_state_help #define __argp_state_help argp_state_help #undef __argp_usage #define __argp_usage argp_usage #undef __argp_basename #define __argp_basename _argp_basename #undef __argp_short_program_name #define __argp_short_program_name _argp_short_program_name /* argp-fmtstream functions */ #undef __argp_make_fmtstream #define __argp_make_fmtstream argp_make_fmtstream #undef __argp_fmtstream_free #define __argp_fmtstream_free argp_fmtstream_free #undef __argp_fmtstream_putc #define __argp_fmtstream_putc argp_fmtstream_putc #undef __argp_fmtstream_puts #define __argp_fmtstream_puts argp_fmtstream_puts #undef __argp_fmtstream_write #define __argp_fmtstream_write argp_fmtstream_write #undef __argp_fmtstream_printf #define __argp_fmtstream_printf argp_fmtstream_printf #undef __argp_fmtstream_set_lmargin #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin #undef __argp_fmtstream_set_rmargin #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin #undef __argp_fmtstream_set_wmargin #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin #undef __argp_fmtstream_point #define __argp_fmtstream_point argp_fmtstream_point #undef __argp_fmtstream_update #define __argp_fmtstream_update _argp_fmtstream_update #undef __argp_fmtstream_ensure #define __argp_fmtstream_ensure _argp_fmtstream_ensure #undef __argp_fmtstream_lmargin #define __argp_fmtstream_lmargin argp_fmtstream_lmargin #undef __argp_fmtstream_rmargin #define __argp_fmtstream_rmargin argp_fmtstream_rmargin #undef __argp_fmtstream_wmargin #define __argp_fmtstream_wmargin argp_fmtstream_wmargin /* normal libc functions we call */ #undef __sleep #ifndef _WIN32 #define __sleep sleep #else #define WIN32_LEAN_AND_MEAN #include #define __sleep(x) Sleep(x * 1000) #endif #undef __strcasecmp #define __strcasecmp strcasecmp #undef __vsnprintf #define __vsnprintf vsnprintf #endif /* !_LIBC */ #ifndef __set_errno #define __set_errno(e) (errno = (e)) #endif wvstreams-4.6.1/argp/Makefile.am0000644000175000001440000000253411077124114015561 0ustar wlachusers# From glibc # Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # The GNU C Library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public # License along with the GNU C Library; see the file COPYING.LIB. If # not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. AUTOMAKE_OPTIONS = foreign SUBDIRS = . testsuite LIBOBJS = @LIBOBJS@ noinst_LIBRARIES = libargp.a noinst_PROGRAMS = argp-test noinst_HEADERS = argp.h argp-fmtstream.h argp-namefrob.h # argp-comp.h EXTRA_DIST = mempcpy.c strchrnul.c strndup.c Versions # Leaves out argp-fs-xinl.c and argp-xinl.c libargp_a_SOURCES = argp-ba.c argp-eexst.c argp-fmtstream.c \ argp-help.c argp-parse.c argp-pv.c \ argp-pvh.c libargp_a_LIBADD = $(LIBOBJS) argp_test_LDADD = libargp.a wvstreams-4.6.1/argp/argp-ba.c0000644000175000001440000000251411077124114015200 0ustar wlachusers/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* If set by the user program, it should point to string that is the bug-reporting address for the program. It will be printed by argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help messages), embedded in a sentence that says something like `Report bugs to ADDR.'. */ const char *argp_program_bug_address = 0; wvstreams-4.6.1/argp/mempcpy.c0000644000175000001440000000041511077124114015337 0ustar wlachusers/* strndup.c * */ /* Written by Niels Möller * * This file is hereby placed in the public domain. */ #include void * mempcpy (void *to, const void *from, size_t size) { memcpy(to, from, size); return (char *) to + size; } wvstreams-4.6.1/argp/strchrnul.c0000644000175000001440000000067111077124114015715 0ustar wlachusers/* strchrnul.c * */ /* Written by Niels Möller * * This file is hereby placed in the public domain. */ /* FIXME: What is this function supposed to do? My guess is that it is * like strchr, but returns a pointer to the NUL character, not a NULL * pointer, if the character isn't found. */ char *strchrnul(const char *s, int c) { const char *p = s; while (*p && (*p != c)) p++; return (char *) p; } wvstreams-4.6.1/argp/depcomp0000755000175000001440000003477111077124114015112 0ustar wlachusers#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2003-11-08.23 # Copyright (C) 1999, 2000, 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. # 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'. 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 # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi 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 tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" 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: wvstreams-4.6.1/argp/config.h.in0000644000175000001440000001044611077124114015551 0ustar wlachusers/* config.h.in. Generated from configure.ac by autoheader. */ /* 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 to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the declaration of `program_invocation_name', and to 0 if you don't. */ #undef HAVE_DECL_PROGRAM_INVOCATION_NAME /* Define to 1 if you have the declaration of `program_invocation_short_name', and to 0 if you don't. */ #undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the `flockfile' function. */ #undef HAVE_FLOCKFILE /* Define to 1 if you have the `fputs_unlocked' function. */ #undef HAVE_FPUTS_UNLOCKED /* Define to 1 if you have the `fwrite_unlocked' function. */ #undef HAVE_FWRITE_UNLOCKED /* Define if the compiler understands __attribute__ */ #undef HAVE_GCC_ATTRIBUTE /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* 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 `mempcpy' function. */ #undef HAVE_MEMPCPY /* Define to 1 if you have the `putc_unlocked' function. */ #undef HAVE_PUTC_UNLOCKED /* 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 `strchrnul' function. */ #undef HAVE_STRCHRNUL /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* 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 `strndup' function. */ #undef HAVE_STRNDUP /* 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 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Name of package */ #undef PACKAGE /* 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 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 run-time. 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 /* Version number of package */ #undef VERSION /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned' if does not define. */ #undef size_t #if __GNUC__ && HAVE_GCC_ATTRIBUTE # define NORETURN __attribute__ ((__noreturn__)) # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) # define UNUSED __attribute__ ((__unused__)) #else # define NORETURN # define PRINTF_STYLE(f, a) # define UNUSED #endif wvstreams-4.6.1/argp/argp-test.c0000644000175000001440000001455111077124114015601 0ustar wlachusers/* Test program for argp argument parser Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "argp.h" #if !HAVE_ASPRINTF #include #ifdef _WIN32 /* We all know rand sucks, but it's not like we're going to be running tests */ #define random rand #endif static int asprintf (char **result, const char *format, ...) { size_t size; char *p; for (size = 200, p = NULL;; size *= 2) { va_list args; int written; p = realloc(p, size + 1); if (!p) { fprintf(stderr, "Virtual memory exhausted.\n"); abort(); } p[size] = '\0'; va_start(args, format); written = vsnprintf(p, size, format, args); va_end(args); if (written >= 0) { *result = p; return written; } } } #endif /* !HAVE_ASPRINTF */ const char *argp_program_version = "argp-test 1.0"; struct argp_option sub_options[] = { {"subopt1", 's', 0, 0, "Nested option 1", 0}, {"subopt2", 'S', 0, 0, "Nested option 2", 0}, { 0, 0, 0, 0, "Some more nested options:", 10}, {"subopt3", 'p', 0, 0, "Nested option 3", 0}, {"subopt4", 'q', 0, 0, "Nested option 4", 1}, {0, 0, 0, 0, 0, 0} }; static const char sub_args_doc[] = "STRING...\n-"; static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser."; static error_t sub_parse_opt (int key, char *arg, struct argp_state *state UNUSED) { switch (key) { case ARGP_KEY_NO_ARGS: printf ("NO SUB ARGS\n"); break; case ARGP_KEY_ARG: printf ("SUB ARG: %s\n", arg); break; case 's' : case 'S': case 'p': case 'q': printf ("SUB KEY %c\n", key); break; default: return ARGP_ERR_UNKNOWN; } return 0; } static char * sub_help_filter (int key, const char *text, void *input UNUSED) { if (key == ARGP_KEY_HELP_EXTRA) return strdup ("This is some extra text from the sub parser (note that it \ is preceded by a blank line)."); else return (char *)text; } static struct argp sub_argp = { sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter, 0 }; /* Structure used to communicate with the parsing functions. */ struct params { unsigned foonly; /* Value parsed for foonly. */ unsigned foonly_default; /* Default value for it. */ }; #define OPT_PGRP 1 #define OPT_SESS 2 struct argp_option options[] = { {"pid", 'p', "PID", 0, "List the process PID", 0}, {"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP", 0}, {"no-parent", 'P', 0, 0, "Include processes without parents", 0}, {0, 'x', 0, OPTION_ALIAS, NULL, 0}, {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" " if there's some reason ps can't" " print a field for any process, it's" " removed from the output entirely)", 0}, {"reverse", 'r', 0, 0, "Reverse the order of any sort", 0}, {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS, NULL, 0}, {"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL, "Add the processes from the session" " SID (which defaults to the sid of" " the current process)", 0}, {0,0,0,0, "Here are some more options:", 0}, {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly", 0}, {"zaza", 'z', 0, 0, "Snit a zar", 0}, {0, 0, 0, 0, 0, 0} }; static const char args_doc[] = "STRING"; static const char doc[] = "Test program for argp." "\vThis doc string comes after the options." "\nHey! Some manual formatting!" "\nThe current time is: %s"; static void popt (int key, char *arg) { char buf[10]; if (isprint (key)) sprintf (buf, "%c", key); else sprintf (buf, "%d", key); if (arg) printf ("KEY %s: %s\n", buf, arg); else printf ("KEY %s\n", buf); } static error_t parse_opt (int key, char *arg, struct argp_state *state) { struct params *params = state->input; switch (key) { case ARGP_KEY_NO_ARGS: printf ("NO ARGS\n"); break; case ARGP_KEY_ARG: if (state->arg_num > 0) return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */ printf ("ARG: %s\n", arg); break; case 'f': if (arg) params->foonly = atoi (arg); else params->foonly = params->foonly_default; popt (key, arg); break; case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q': case 'r': case OPT_SESS: case 'z': popt (key, arg); break; default: return ARGP_ERR_UNKNOWN; } return 0; } static char * help_filter (int key, const char *text, void *input) { char *new_text; struct params *params = input; if (key == ARGP_KEY_HELP_POST_DOC && text) { time_t now = time (0); asprintf (&new_text, text, ctime (&now)); } else if (key == 'f') /* Show the default for the --foonly option. */ asprintf (&new_text, "%s (ZOT defaults to %x)", text, params->foonly_default); else new_text = (char *)text; return new_text; } static struct argp_child argp_children[] = { { &sub_argp, 0, 0, 0 }, { 0, 0, 0, 0 } }; static struct argp argp = { options, parse_opt, args_doc, doc, argp_children, help_filter, 0 }; int main (int argc, char **argv) { struct params params; params.foonly = 0; params.foonly_default = random (); argp_parse (&argp, argc, argv, 0, 0, ¶ms); printf ("After parsing: foonly = %x\n", params.foonly); return 0; } wvstreams-4.6.1/argp/mkinstalldirs0000755000175000001440000000556111077124114016336 0ustar wlachusers#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2003-11-08.23 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit 0 ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec 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. test -d ./-p && rmdir ./-p test -d ./-- && rmdir ./-- fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./-- "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # 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: wvstreams-4.6.1/argp/autom4te.cache/0000755000175000001440000000000011260431131016317 5ustar wlachuserswvstreams-4.6.1/argp/autom4te.cache/requests0000644000175000001440000000535311260431131020123 0ustar wlachusers# This file was generated. # It contains the lists of macros which have been traced. # It can be safely removed. @request = ( bless( [ '0', 1, [ '/usr/share/autoconf' ], [ '/usr/share/autoconf/autoconf/autoconf.m4f', 'aclocal.m4', 'configure.ac' ], { '_LT_AC_TAGCONFIG' => 1, 'AM_PROG_F77_C_O' => 1, 'AC_INIT' => 1, 'm4_pattern_forbid' => 1, '_AM_COND_IF' => 1, 'AC_CANONICAL_TARGET' => 1, 'AC_SUBST' => 1, 'AC_CONFIG_LIBOBJ_DIR' => 1, 'AC_FC_SRCEXT' => 1, 'AC_CANONICAL_HOST' => 1, 'AC_PROG_LIBTOOL' => 1, 'AM_INIT_AUTOMAKE' => 1, 'AC_CONFIG_SUBDIRS' => 1, 'AM_AUTOMAKE_VERSION' => 1, 'LT_CONFIG_LTDL_DIR' => 1, 'AC_REQUIRE_AUX_FILE' => 1, 'AC_CONFIG_LINKS' => 1, 'm4_sinclude' => 1, 'LT_SUPPORTED_TAG' => 1, 'AM_MAINTAINER_MODE' => 1, 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1, '_m4_warn' => 1, 'AM_PROG_CXX_C_O' => 1, '_AM_COND_ENDIF' => 1, 'AM_ENABLE_MULTILIB' => 1, 'AC_CONFIG_FILES' => 1, 'include' => 1, 'LT_INIT' => 1, 'AM_GNU_GETTEXT' => 1, 'AC_LIBSOURCE' => 1, 'AM_PROG_FC_C_O' => 1, 'AC_CANONICAL_BUILD' => 1, 'AC_FC_FREEFORM' => 1, 'AH_OUTPUT' => 1, '_AM_SUBST_NOTMAKE' => 1, 'AC_CONFIG_AUX_DIR' => 1, 'sinclude' => 1, 'm4_pattern_allow' => 1, 'AM_PROG_CC_C_O' => 1, 'AC_CANONICAL_SYSTEM' => 1, 'AM_CONDITIONAL' => 1, 'AC_CONFIG_HEADERS' => 1, 'AC_DEFINE_TRACE_LITERAL' => 1, 'm4_include' => 1, '_AM_COND_ELSE' => 1, 'AC_SUBST_TRACE' => 1 } ], 'Autom4te::Request' ) ); wvstreams-4.6.1/argp/autom4te.cache/traces.00000644000175000001440000011227111260431131017665 0ustar wlachusersm4trace:aclocal.m4:952: -1- m4_include([acinclude.m4]) m4trace:configure.ac:5: -1- AC_INIT([argp-ba.c]) m4trace:configure.ac:5: -1- m4_pattern_forbid([^_?A[CHUM]_]) m4trace:configure.ac:5: -1- m4_pattern_forbid([_AC_]) m4trace:configure.ac:5: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) m4trace:configure.ac:5: -1- m4_pattern_allow([^AS_FLAGS$]) m4trace:configure.ac:5: -1- m4_pattern_forbid([^_?m4_]) m4trace:configure.ac:5: -1- m4_pattern_forbid([^dnl$]) m4trace:configure.ac:5: -1- m4_pattern_forbid([^_?AS_]) m4trace:configure.ac:5: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([SHELL]) m4trace:configure.ac:5: -1- m4_pattern_allow([^SHELL$]) m4trace:configure.ac:5: -1- AC_SUBST([PATH_SEPARATOR]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PATH_SEPARATOR]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PATH_SEPARATOR$]) m4trace:configure.ac:5: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PACKAGE_NAME]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:5: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PACKAGE_TARNAME]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:5: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PACKAGE_VERSION]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:5: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PACKAGE_STRING]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:5: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:5: -1- AC_SUBST([exec_prefix], [NONE]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([exec_prefix]) m4trace:configure.ac:5: -1- m4_pattern_allow([^exec_prefix$]) m4trace:configure.ac:5: -1- AC_SUBST([prefix], [NONE]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([prefix]) m4trace:configure.ac:5: -1- m4_pattern_allow([^prefix$]) m4trace:configure.ac:5: -1- AC_SUBST([program_transform_name], [s,x,x,]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([program_transform_name]) m4trace:configure.ac:5: -1- m4_pattern_allow([^program_transform_name$]) m4trace:configure.ac:5: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([bindir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^bindir$]) m4trace:configure.ac:5: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([sbindir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^sbindir$]) m4trace:configure.ac:5: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([libexecdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^libexecdir$]) m4trace:configure.ac:5: -1- AC_SUBST([datarootdir], ['${prefix}/share']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([datarootdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^datarootdir$]) m4trace:configure.ac:5: -1- AC_SUBST([datadir], ['${datarootdir}']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([datadir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^datadir$]) m4trace:configure.ac:5: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([sysconfdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^sysconfdir$]) m4trace:configure.ac:5: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([sharedstatedir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^sharedstatedir$]) m4trace:configure.ac:5: -1- AC_SUBST([localstatedir], ['${prefix}/var']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([localstatedir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^localstatedir$]) m4trace:configure.ac:5: -1- AC_SUBST([includedir], ['${prefix}/include']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([includedir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^includedir$]) m4trace:configure.ac:5: -1- AC_SUBST([oldincludedir], ['/usr/include']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([oldincludedir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^oldincludedir$]) m4trace:configure.ac:5: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], ['${datarootdir}/doc/${PACKAGE_TARNAME}'], ['${datarootdir}/doc/${PACKAGE}'])]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([docdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^docdir$]) m4trace:configure.ac:5: -1- AC_SUBST([infodir], ['${datarootdir}/info']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([infodir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^infodir$]) m4trace:configure.ac:5: -1- AC_SUBST([htmldir], ['${docdir}']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([htmldir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^htmldir$]) m4trace:configure.ac:5: -1- AC_SUBST([dvidir], ['${docdir}']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([dvidir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^dvidir$]) m4trace:configure.ac:5: -1- AC_SUBST([pdfdir], ['${docdir}']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([pdfdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^pdfdir$]) m4trace:configure.ac:5: -1- AC_SUBST([psdir], ['${docdir}']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([psdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^psdir$]) m4trace:configure.ac:5: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([libdir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^libdir$]) m4trace:configure.ac:5: -1- AC_SUBST([localedir], ['${datarootdir}/locale']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([localedir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^localedir$]) m4trace:configure.ac:5: -1- AC_SUBST([mandir], ['${datarootdir}/man']) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([mandir]) m4trace:configure.ac:5: -1- m4_pattern_allow([^mandir$]) m4trace:configure.ac:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_NAME$]) m4trace:configure.ac:5: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ #undef PACKAGE_NAME]) m4trace:configure.ac:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_TARNAME$]) m4trace:configure.ac:5: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME]) m4trace:configure.ac:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_VERSION$]) m4trace:configure.ac:5: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ #undef PACKAGE_VERSION]) m4trace:configure.ac:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_STRING$]) m4trace:configure.ac:5: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ #undef PACKAGE_STRING]) m4trace:configure.ac:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) m4trace:configure.ac:5: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$]) m4trace:configure.ac:5: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT]) m4trace:configure.ac:5: -1- AC_SUBST([DEFS]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([DEFS]) m4trace:configure.ac:5: -1- m4_pattern_allow([^DEFS$]) m4trace:configure.ac:5: -1- AC_SUBST([ECHO_C]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([ECHO_C]) m4trace:configure.ac:5: -1- m4_pattern_allow([^ECHO_C$]) m4trace:configure.ac:5: -1- AC_SUBST([ECHO_N]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([ECHO_N]) m4trace:configure.ac:5: -1- m4_pattern_allow([^ECHO_N$]) m4trace:configure.ac:5: -1- AC_SUBST([ECHO_T]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([ECHO_T]) m4trace:configure.ac:5: -1- m4_pattern_allow([^ECHO_T$]) m4trace:configure.ac:5: -1- AC_SUBST([LIBS]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:5: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:5: -1- AC_SUBST([build_alias]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([build_alias]) m4trace:configure.ac:5: -1- m4_pattern_allow([^build_alias$]) m4trace:configure.ac:5: -1- AC_SUBST([host_alias]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([host_alias]) m4trace:configure.ac:5: -1- m4_pattern_allow([^host_alias$]) m4trace:configure.ac:5: -1- AC_SUBST([target_alias]) m4trace:configure.ac:5: -1- AC_SUBST_TRACE([target_alias]) m4trace:configure.ac:5: -1- m4_pattern_allow([^target_alias$]) m4trace:configure.ac:6: -1- AM_INIT_AUTOMAKE([argp], [standalone-1.3]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) m4trace:configure.ac:6: -1- AM_AUTOMAKE_VERSION([1.8.2]) m4trace:configure.ac:6: -1- AC_REQUIRE_AUX_FILE([install-sh]) m4trace:configure.ac:6: -1- AC_SUBST([INSTALL_PROGRAM]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([INSTALL_PROGRAM]) m4trace:configure.ac:6: -1- m4_pattern_allow([^INSTALL_PROGRAM$]) m4trace:configure.ac:6: -1- AC_SUBST([INSTALL_SCRIPT]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([INSTALL_SCRIPT]) m4trace:configure.ac:6: -1- m4_pattern_allow([^INSTALL_SCRIPT$]) m4trace:configure.ac:6: -1- AC_SUBST([INSTALL_DATA]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([INSTALL_DATA]) m4trace:configure.ac:6: -1- m4_pattern_allow([^INSTALL_DATA$]) m4trace:configure.ac:6: -1- AC_SUBST([CYGPATH_W]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([CYGPATH_W]) m4trace:configure.ac:6: -1- m4_pattern_allow([^CYGPATH_W$]) m4trace:configure.ac:6: -1- AC_SUBST([PACKAGE], [argp]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([PACKAGE]) m4trace:configure.ac:6: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:6: -1- AC_SUBST([VERSION], [standalone-1.3]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([VERSION]) m4trace:configure.ac:6: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:6: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE]) m4trace:configure.ac:6: -1- m4_pattern_allow([^PACKAGE$]) m4trace:configure.ac:6: -1- AH_OUTPUT([PACKAGE], [/* Name of package */ #undef PACKAGE]) m4trace:configure.ac:6: -1- AC_DEFINE_TRACE_LITERAL([VERSION]) m4trace:configure.ac:6: -1- m4_pattern_allow([^VERSION$]) m4trace:configure.ac:6: -1- AH_OUTPUT([VERSION], [/* Version number of package */ #undef VERSION]) m4trace:configure.ac:6: -1- AC_SUBST([ACLOCAL]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([ACLOCAL]) m4trace:configure.ac:6: -1- m4_pattern_allow([^ACLOCAL$]) m4trace:configure.ac:6: -1- AC_SUBST([AUTOCONF]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([AUTOCONF]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AUTOCONF$]) m4trace:configure.ac:6: -1- AC_SUBST([AUTOMAKE]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([AUTOMAKE]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AUTOMAKE$]) m4trace:configure.ac:6: -1- AC_SUBST([AUTOHEADER]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([AUTOHEADER]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AUTOHEADER$]) m4trace:configure.ac:6: -1- AC_SUBST([MAKEINFO]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([MAKEINFO]) m4trace:configure.ac:6: -1- m4_pattern_allow([^MAKEINFO$]) m4trace:configure.ac:6: -1- AC_SUBST([AMTAR]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([AMTAR]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AMTAR$]) m4trace:configure.ac:6: -1- AC_SUBST([install_sh]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([install_sh]) m4trace:configure.ac:6: -1- m4_pattern_allow([^install_sh$]) m4trace:configure.ac:6: -1- AC_SUBST([STRIP]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([STRIP]) m4trace:configure.ac:6: -1- m4_pattern_allow([^STRIP$]) m4trace:configure.ac:6: -1- AC_SUBST([INSTALL_STRIP_PROGRAM]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([INSTALL_STRIP_PROGRAM]) m4trace:configure.ac:6: -1- m4_pattern_allow([^INSTALL_STRIP_PROGRAM$]) m4trace:configure.ac:6: -1- AC_SUBST([mkdir_p]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([mkdir_p]) m4trace:configure.ac:6: -1- m4_pattern_allow([^mkdir_p$]) m4trace:configure.ac:6: -1- AC_SUBST([AWK]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([AWK]) m4trace:configure.ac:6: -1- m4_pattern_allow([^AWK$]) m4trace:configure.ac:6: -1- AC_SUBST([SET_MAKE]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([SET_MAKE]) m4trace:configure.ac:6: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:6: -1- AC_SUBST([am__leading_dot]) m4trace:configure.ac:6: -1- AC_SUBST_TRACE([am__leading_dot]) m4trace:configure.ac:6: -1- m4_pattern_allow([^am__leading_dot$]) m4trace:configure.ac:7: -1- _m4_warn([obsolete], [The macro `AM_CONFIG_HEADER' is obsolete. You should run autoupdate.], [aclocal.m4:453: AM_CONFIG_HEADER is expanded from... configure.ac:7: the top level]) m4trace:configure.ac:7: -1- AC_CONFIG_HEADERS([config.h]) m4trace:configure.ac:13: -1- _m4_warn([obsolete], [The macro `AC_GNU_SOURCE' is obsolete. You should run autoupdate.], [../../lib/autoconf/specific.m4:332: AC_GNU_SOURCE is expanded from... configure.ac:13: the top level]) m4trace:configure.ac:13: -1- AC_SUBST([CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:13: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:13: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:13: -1- AC_SUBST([LIBS]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:13: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:13: -1- AC_SUBST([CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:13: -1- AC_SUBST([CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:13: -1- AC_SUBST([CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:13: -1- AC_SUBST([CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:13: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:13: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:13: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([EXEEXT]) m4trace:configure.ac:13: -1- m4_pattern_allow([^EXEEXT$]) m4trace:configure.ac:13: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([OBJEXT]) m4trace:configure.ac:13: -1- m4_pattern_allow([^OBJEXT$]) m4trace:configure.ac:13: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([DEPDIR]) m4trace:configure.ac:13: -1- m4_pattern_allow([^DEPDIR$]) m4trace:configure.ac:13: -1- AC_SUBST([am__include]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([am__include]) m4trace:configure.ac:13: -1- m4_pattern_allow([^am__include$]) m4trace:configure.ac:13: -1- AC_SUBST([am__quote]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([am__quote]) m4trace:configure.ac:13: -1- m4_pattern_allow([^am__quote$]) m4trace:configure.ac:13: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) m4trace:configure.ac:13: -1- AC_SUBST([AMDEP_TRUE]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([AMDEP_TRUE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^AMDEP_TRUE$]) m4trace:configure.ac:13: -1- AC_SUBST([AMDEP_FALSE]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([AMDEP_FALSE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^AMDEP_FALSE$]) m4trace:configure.ac:13: -1- AC_SUBST([AMDEPBACKSLASH]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([AMDEPBACKSLASH]) m4trace:configure.ac:13: -1- m4_pattern_allow([^AMDEPBACKSLASH$]) m4trace:configure.ac:13: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CCDEPMODE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:13: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:13: -1- AC_SUBST([am__fastdepCC_TRUE]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:13: -1- AC_SUBST([am__fastdepCC_FALSE]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:13: -1- AC_SUBST([CPP]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:13: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:13: -1- AC_SUBST([CPP]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([CPP]) m4trace:configure.ac:13: -1- m4_pattern_allow([^CPP$]) m4trace:configure.ac:13: -1- AC_SUBST([GREP]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([GREP]) m4trace:configure.ac:13: -1- m4_pattern_allow([^GREP$]) m4trace:configure.ac:13: -1- AC_SUBST([EGREP]) m4trace:configure.ac:13: -1- AC_SUBST_TRACE([EGREP]) m4trace:configure.ac:13: -1- m4_pattern_allow([^EGREP$]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:13: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRING_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H]) m4trace:configure.ac:13: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_SOURCE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_POSIX_SOURCE$]) m4trace:configure.ac:13: -1- AH_OUTPUT([_POSIX_SOURCE], [/* Define to 1 if you need to in order for `stat\' and other things to work. */ #undef _POSIX_SOURCE]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_1_SOURCE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_POSIX_1_SOURCE$]) m4trace:configure.ac:13: -1- AH_OUTPUT([_POSIX_1_SOURCE], [/* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_MINIX]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_MINIX$]) m4trace:configure.ac:13: -1- AH_OUTPUT([_MINIX], [/* Define to 1 if on MINIX. */ #undef _MINIX]) m4trace:configure.ac:13: -1- AH_OUTPUT([USE_SYSTEM_EXTENSIONS], [/* 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 ]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([__EXTENSIONS__]) m4trace:configure.ac:13: -1- m4_pattern_allow([^__EXTENSIONS__$]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_ALL_SOURCE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_ALL_SOURCE$]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_GNU_SOURCE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_GNU_SOURCE$]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_PTHREAD_SEMANTICS]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_POSIX_PTHREAD_SEMANTICS$]) m4trace:configure.ac:13: -1- AC_DEFINE_TRACE_LITERAL([_TANDEM_SOURCE]) m4trace:configure.ac:13: -1- m4_pattern_allow([^_TANDEM_SOURCE$]) m4trace:configure.ac:16: -1- AC_SUBST([CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:16: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:16: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:16: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:16: -1- AC_SUBST([LIBS]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:16: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:16: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:16: -1- AC_SUBST([CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:16: -1- AC_SUBST([CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:16: -1- AC_SUBST([CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:16: -1- AC_SUBST([CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:16: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:16: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:16: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([CCDEPMODE]) m4trace:configure.ac:16: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:16: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:16: -1- AC_SUBST([am__fastdepCC_TRUE]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) m4trace:configure.ac:16: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:16: -1- AC_SUBST([am__fastdepCC_FALSE]) m4trace:configure.ac:16: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) m4trace:configure.ac:16: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:17: -1- AC_SUBST([SET_MAKE]) m4trace:configure.ac:17: -1- AC_SUBST_TRACE([SET_MAKE]) m4trace:configure.ac:17: -1- m4_pattern_allow([^SET_MAKE$]) m4trace:configure.ac:18: -1- AC_SUBST([RANLIB]) m4trace:configure.ac:18: -1- AC_SUBST_TRACE([RANLIB]) m4trace:configure.ac:18: -1- m4_pattern_allow([^RANLIB$]) m4trace:configure.ac:19: -1- _m4_warn([obsolete], [The macro `AC_PROGRAM_CHECK' is obsolete. You should run autoupdate.], [../../lib/autoconf/oldnames.m4:62: AC_PROGRAM_CHECK is expanded from... configure.ac:19: the top level]) m4trace:configure.ac:19: -1- AC_SUBST([AR]) m4trace:configure.ac:19: -1- AC_SUBST_TRACE([AR]) m4trace:configure.ac:19: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:20: -1- _m4_warn([obsolete], [The macro `AC_PROGRAM_CHECK' is obsolete. You should run autoupdate.], [../../lib/autoconf/oldnames.m4:62: AC_PROGRAM_CHECK is expanded from... configure.ac:20: the top level]) m4trace:configure.ac:20: -1- AC_SUBST([AR]) m4trace:configure.ac:20: -1- AC_SUBST_TRACE([AR]) m4trace:configure.ac:20: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:21: -1- _m4_warn([obsolete], [The macro `AM_PROG_CC_STDC' is obsolete. You should run autoupdate.], [aclocal.m4:132: AM_PROG_CC_STDC is expanded from... configure.ac:21: the top level]) m4trace:configure.ac:21: -1- AC_SUBST([CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:21: -1- AC_SUBST([CFLAGS]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CFLAGS]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CFLAGS$]) m4trace:configure.ac:21: -1- AC_SUBST([LDFLAGS]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([LDFLAGS]) m4trace:configure.ac:21: -1- m4_pattern_allow([^LDFLAGS$]) m4trace:configure.ac:21: -1- AC_SUBST([LIBS]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([LIBS]) m4trace:configure.ac:21: -1- m4_pattern_allow([^LIBS$]) m4trace:configure.ac:21: -1- AC_SUBST([CPPFLAGS]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CPPFLAGS]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CPPFLAGS$]) m4trace:configure.ac:21: -1- AC_SUBST([CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:21: -1- AC_SUBST([CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:21: -1- AC_SUBST([CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:21: -1- AC_SUBST([CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CC$]) m4trace:configure.ac:21: -1- AC_SUBST([ac_ct_CC]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([ac_ct_CC]) m4trace:configure.ac:21: -1- m4_pattern_allow([^ac_ct_CC$]) m4trace:configure.ac:21: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([CCDEPMODE]) m4trace:configure.ac:21: -1- m4_pattern_allow([^CCDEPMODE$]) m4trace:configure.ac:21: -1- AM_CONDITIONAL([am__fastdepCC], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) m4trace:configure.ac:21: -1- AC_SUBST([am__fastdepCC_TRUE]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([am__fastdepCC_TRUE]) m4trace:configure.ac:21: -1- m4_pattern_allow([^am__fastdepCC_TRUE$]) m4trace:configure.ac:21: -1- AC_SUBST([am__fastdepCC_FALSE]) m4trace:configure.ac:21: -1- AC_SUBST_TRACE([am__fastdepCC_FALSE]) m4trace:configure.ac:21: -1- m4_pattern_allow([^am__fastdepCC_FALSE$]) m4trace:configure.ac:21: -1- _m4_warn([obsolete], [AM_PROG_CC_STDC: your code should no longer depend upon `am_cv_prog_cc_stdc', but upon `ac_cv_prog_cc_stdc'. Remove this warning and the assignment when you adjust the code. You can also remove the above call to AC_PROG_CC if you already called it elsewhere.], [aclocal.m4:132: AM_PROG_CC_STDC is expanded from... configure.ac:21: the top level]) m4trace:configure.ac:23: -1- AC_SUBST([AR]) m4trace:configure.ac:23: -1- AC_SUBST_TRACE([AR]) m4trace:configure.ac:23: -1- m4_pattern_allow([^AR$]) m4trace:configure.ac:26: -1- _m4_warn([obsolete], [The macro `AC_ERROR' is obsolete. You should run autoupdate.], [../../lib/autoconf/oldnames.m4:55: AC_ERROR is expanded from... configure.ac:26: the top level]) m4trace:configure.ac:32: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) m4trace:configure.ac:32: -1- m4_pattern_allow([^STDC_HEADERS$]) m4trace:configure.ac:32: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS]) m4trace:configure.ac:33: -1- AH_OUTPUT([HAVE_LIMITS_H], [/* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H]) m4trace:configure.ac:33: -1- AH_OUTPUT([HAVE_MALLOC_H], [/* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H]) m4trace:configure.ac:33: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H]) m4trace:configure.ac:36: -1- AC_DEFINE_TRACE_LITERAL([const]) m4trace:configure.ac:36: -1- m4_pattern_allow([^const$]) m4trace:configure.ac:36: -1- AH_OUTPUT([const], [/* Define to empty if `const\' does not conform to ANSI C. */ #undef const]) m4trace:configure.ac:37: -1- AH_OUTPUT([inline], [/* Define to `__inline__\' or `__inline\' if that\'s what the C compiler calls it, or to nothing if \'inline\' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif]) m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([size_t]) m4trace:configure.ac:38: -1- m4_pattern_allow([^size_t$]) m4trace:configure.ac:38: -1- AH_OUTPUT([size_t], [/* Define to `unsigned int\' if does not define. */ #undef size_t]) m4trace:configure.ac:40: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2470: AC_TRY_COMPILE is expanded from... ../../lib/m4sugar/m4sh.m4:505: AS_IF is expanded from... ../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from... ../../lib/autoconf/general.m4:1994: AC_CACHE_CHECK is expanded from... acinclude.m4:282: LSH_GCC_ATTRIBUTES is expanded from... configure.ac:40: the top level]) m4trace:configure.ac:40: -1- AH_OUTPUT([HAVE_GCC_ATTRIBUTE], [/* Define if the compiler understands __attribute__ */ #undef HAVE_GCC_ATTRIBUTE]) m4trace:configure.ac:40: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GCC_ATTRIBUTE]) m4trace:configure.ac:40: -1- m4_pattern_allow([^HAVE_GCC_ATTRIBUTE$]) m4trace:configure.ac:40: -1- AH_OUTPUT([zzzz1], [#if __GNUC__ && HAVE_GCC_ATTRIBUTE # define NORETURN __attribute__ ((__noreturn__)) # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) # define UNUSED __attribute__ ((__unused__)) #else # define NORETURN # define PRINTF_STYLE(f, a) # define UNUSED #endif ]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ALLOCA_H]) m4trace:configure.ac:43: -1- m4_pattern_allow([^HAVE_ALLOCA_H$]) m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_ALLOCA_H], [/* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ALLOCA]) m4trace:configure.ac:43: -1- m4_pattern_allow([^HAVE_ALLOCA$]) m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_ALLOCA], [/* Define to 1 if you have `alloca\', as a function or macro. */ #undef HAVE_ALLOCA]) m4trace:configure.ac:43: -1- AC_LIBSOURCE([alloca.c]) m4trace:configure.ac:43: -1- AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext]) m4trace:configure.ac:43: -1- AC_SUBST_TRACE([ALLOCA]) m4trace:configure.ac:43: -1- m4_pattern_allow([^ALLOCA$]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([C_ALLOCA]) m4trace:configure.ac:43: -1- m4_pattern_allow([^C_ALLOCA$]) m4trace:configure.ac:43: -1- AH_OUTPUT([C_ALLOCA], [/* Define to 1 if using `alloca.c\'. */ #undef C_ALLOCA]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([CRAY_STACKSEG_END]) m4trace:configure.ac:43: -1- m4_pattern_allow([^CRAY_STACKSEG_END$]) m4trace:configure.ac:43: -1- AH_OUTPUT([CRAY_STACKSEG_END], [/* 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]) m4trace:configure.ac:43: -1- AH_OUTPUT([STACK_DIRECTION], [/* 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]) m4trace:configure.ac:43: -1- AC_DEFINE_TRACE_LITERAL([STACK_DIRECTION]) m4trace:configure.ac:43: -1- m4_pattern_allow([^STACK_DIRECTION$]) m4trace:configure.ac:44: -1- AH_OUTPUT([HAVE_VPRINTF], [/* Define to 1 if you have the `vprintf\' function. */ #undef HAVE_VPRINTF]) m4trace:configure.ac:44: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DOPRNT]) m4trace:configure.ac:44: -1- m4_pattern_allow([^HAVE_DOPRNT$]) m4trace:configure.ac:44: -1- AH_OUTPUT([HAVE_DOPRNT], [/* Define to 1 if you don\'t have `vprintf\' but do have `_doprnt.\' */ #undef HAVE_DOPRNT]) m4trace:configure.ac:45: -1- AH_OUTPUT([HAVE_STRERROR], [/* Define to 1 if you have the `strerror\' function. */ #undef HAVE_STRERROR]) m4trace:configure.ac:47: -1- AC_LIBSOURCE([mempcpy.c]) m4trace:configure.ac:47: -1- AC_LIBSOURCE([strndup.c]) m4trace:configure.ac:47: -1- AC_LIBSOURCE([strchrnul.c]) m4trace:configure.ac:47: -1- AH_OUTPUT([HAVE_MEMPCPY], [/* Define to 1 if you have the `mempcpy\' function. */ #undef HAVE_MEMPCPY]) m4trace:configure.ac:47: -1- AH_OUTPUT([HAVE_STRNDUP], [/* Define to 1 if you have the `strndup\' function. */ #undef HAVE_STRNDUP]) m4trace:configure.ac:47: -1- AH_OUTPUT([HAVE_STRCHRNUL], [/* Define to 1 if you have the `strchrnul\' function. */ #undef HAVE_STRCHRNUL]) m4trace:configure.ac:47: -1- AC_SUBST([LIB@&t@OBJS], ["$LIB@&t@OBJS $ac_func.$ac_objext"]) m4trace:configure.ac:47: -1- AC_SUBST_TRACE([LIB@&t@OBJS]) m4trace:configure.ac:47: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:73: -1- AH_OUTPUT([HAVE_PUTC_UNLOCKED], [/* Define to 1 if you have the `putc_unlocked\' function. */ #undef HAVE_PUTC_UNLOCKED]) m4trace:configure.ac:73: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [../../lib/autoconf/general.m4:2527: AC_TRY_LINK is expanded from... ../../lib/m4sugar/m4sh.m4:505: AS_IF is expanded from... ../../lib/autoconf/general.m4:1974: AC_CACHE_VAL is expanded from... ../../lib/autoconf/general.m4:1994: AC_CACHE_CHECK is expanded from... configure.ac:50: ARGP_CHECK_FUNC is expanded from... configure.ac:73: the top level]) m4trace:configure.ac:73: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PUTC_UNLOCKED]) m4trace:configure.ac:73: -1- m4_pattern_allow([^HAVE_PUTC_UNLOCKED$]) m4trace:configure.ac:75: -1- AH_OUTPUT([HAVE_FLOCKFILE], [/* Define to 1 if you have the `flockfile\' function. */ #undef HAVE_FLOCKFILE]) m4trace:configure.ac:76: -1- AH_OUTPUT([HAVE_FPUTS_UNLOCKED], [/* Define to 1 if you have the `fputs_unlocked\' function. */ #undef HAVE_FPUTS_UNLOCKED]) m4trace:configure.ac:76: -1- AH_OUTPUT([HAVE_FWRITE_UNLOCKED], [/* Define to 1 if you have the `fwrite_unlocked\' function. */ #undef HAVE_FWRITE_UNLOCKED]) m4trace:configure.ac:79: -1- AH_OUTPUT([HAVE_STRDUP], [/* Define to 1 if you have the `strdup\' function. */ #undef HAVE_STRDUP]) m4trace:configure.ac:79: -1- AH_OUTPUT([HAVE_ASPRINTF], [/* Define to 1 if you have the `asprintf\' function. */ #undef HAVE_ASPRINTF]) m4trace:configure.ac:81: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_PROGRAM_INVOCATION_NAME]) m4trace:configure.ac:81: -1- m4_pattern_allow([^HAVE_DECL_PROGRAM_INVOCATION_NAME$]) m4trace:configure.ac:81: -1- AH_OUTPUT([HAVE_DECL_PROGRAM_INVOCATION_NAME], [/* Define to 1 if you have the declaration of `program_invocation_name\', and to 0 if you don\'t. */ #undef HAVE_DECL_PROGRAM_INVOCATION_NAME]) m4trace:configure.ac:81: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_PROGRAM_INVOCATION_NAME]) m4trace:configure.ac:81: -1- m4_pattern_allow([^HAVE_DECL_PROGRAM_INVOCATION_NAME$]) m4trace:configure.ac:81: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME]) m4trace:configure.ac:81: -1- m4_pattern_allow([^HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME$]) m4trace:configure.ac:81: -1- AH_OUTPUT([HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME], [/* Define to 1 if you have the declaration of `program_invocation_short_name\', and to 0 if you don\'t. */ #undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME]) m4trace:configure.ac:81: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME]) m4trace:configure.ac:81: -1- m4_pattern_allow([^HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME$]) m4trace:configure.ac:100: -1- AC_CONFIG_FILES([Makefile testsuite/Makefile]) m4trace:configure.ac:100: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments. You should run autoupdate.], []) m4trace:configure.ac:100: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([LIB@&t@OBJS]) m4trace:configure.ac:100: -1- m4_pattern_allow([^LIB@&t@OBJS$]) m4trace:configure.ac:100: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([LTLIBOBJS]) m4trace:configure.ac:100: -1- m4_pattern_allow([^LTLIBOBJS$]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([top_builddir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([top_build_prefix]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([srcdir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([abs_srcdir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([top_srcdir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([abs_top_srcdir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([builddir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([abs_builddir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([abs_top_builddir]) m4trace:configure.ac:100: -1- AC_SUBST_TRACE([INSTALL]) wvstreams-4.6.1/argp/autom4te.cache/output.00000644000175000001440000100512111260431131017740 0ustar wlachusers@%:@! /bin/sh @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.63. @%:@ @%:@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @%:@ 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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=. LIB@&t@OBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="argp-ba.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 LIB@&t@OBJS ALLOCA AR RANLIB EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__leading_dot SET_MAKE AWK mkdir_p INSTALL_STRIP_PROGRAM STRIP install_sh AMTAR MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM 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_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking ' 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _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] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors 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. _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.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # 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:$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= ;; #( *) $as_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'; { (exit 1); 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 # 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 # 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:$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:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 am__api_version="1.8" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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:$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:$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' { $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # 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". { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` 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= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p -- . 2>/dev/null; then # Keeping the `.' argument allows $(mkdir_p) to be used without # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more # expensive solution, as it forces Make to start a sub-shell.) 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 ./--; 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 for ac_prog in gawk mawk nawk awk 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # 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_AWK="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi 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 # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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 # Define the identity of the package. PACKAGE=argp VERSION=standalone-1.3 cat >>confdefs.h <<_ACEOF @%:@define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF @%:@define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # 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. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. ac_config_headers="$ac_config_headers config.h" # GNU libc defaults to supplying the ISO C library functions only. The # _GNU_SOURCE define enables these extensions, in particular we want # errno.h to declare program_invocation_name. Enable it on all # systems; no problems have been reported with it so far. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" 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. { $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } 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 { $as_echo "$as_me:$LINENO: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf @%:@ Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= 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 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } 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:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@ifdef __STDC__ @%:@ include @%:@else @%:@ include @%:@endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF @%:@define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 if test "${ac_cv_header_minix_config_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking minix/config.h usability" >&5 $as_echo_n "checking minix/config.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking minix/config.h presence" >&5 $as_echo_n "checking minix/config.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_minix_config_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } fi if test "x$ac_cv_header_minix_config_h" = x""yes; then MINIX=yes else MINIX= fi if test "$MINIX" = yes; then cat >>confdefs.h <<\_ACEOF @%:@define _POSIX_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _POSIX_1_SOURCE 2 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _MINIX 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_safe_to_define___extensions__=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$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 && cat >>confdefs.h <<\_ACEOF @%:@define __EXTENSIONS__ 1 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _ALL_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _GNU_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF cat >>confdefs.h <<\_ACEOF @%:@define _TANDEM_SOURCE 1 _ACEOF # Checks for programs. 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" 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:$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:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 # 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:$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:$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=":" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gar", so it can be a program name with args. set dummy gar; ac_word=$2 { $as_echo "$as_me:$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="gar" $as_echo "$as_me:$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=":" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } 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 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc if test "x$am_cv_prog_cc_stdc" = xno ; then { { $as_echo "$as_me:$LINENO: error: the C compiler doesn't handle ANSI-C" >&5 $as_echo "$as_me: error: the C compiler doesn't handle ANSI-C" >&2;} { (exit 1); exit 1; }; } fi # Checks for libraries. # Checks for header files. { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF @%:@define STDC_HEADERS 1 _ACEOF fi for ac_header in limits.h malloc.h unistd.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default @%:@include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF @%:@define const /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } 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:$LINENO: checking for __attribute__" >&5 $as_echo_n "checking for __attribute__... " >&6; } if test "${lsh_cv_c_attribute+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { static void foo(void) __attribute__ ((noreturn)); static void __attribute__ ((noreturn)) foo(void) { exit(1); } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then lsh_cv_c_attribute=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lsh_cv_c_attribute=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $lsh_cv_c_attribute" >&5 $as_echo "$lsh_cv_c_attribute" >&6; } if test "x$lsh_cv_c_attribute" = "xyes"; then cat >>confdefs.h <<\_ACEOF @%:@define HAVE_GCC_ATTRIBUTE 1 _ACEOF fi # Checks for library functions. # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ @%:@include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_working_alloca_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF @%:@define HAVE_ALLOCA_H 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_alloca_works=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF @%:@define HAVE_ALLOCA 1 _ACEOF 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 cat >>confdefs.h <<\_ACEOF @%:@define C_ALLOCA 1 _ACEOF { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 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 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$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 for ac_func in vprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { $as_echo "$as_me:$LINENO: checking for _doprnt" >&5 $as_echo_n "checking for _doprnt... " >&6; } if test "${ac_cv_func__doprnt+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _doprnt to an innocuous variant, in case declares _doprnt. For example, HP-UX 11i declares gettimeofday. */ #define _doprnt innocuous__doprnt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _doprnt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _doprnt /* 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 _doprnt (); /* 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__doprnt || defined __stub____doprnt choke me #endif int main () { return _doprnt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func__doprnt=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__doprnt=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 $as_echo "$ac_cv_func__doprnt" >&6; } if test "x$ac_cv_func__doprnt" = x""yes; then cat >>confdefs.h <<\_ACEOF @%:@define HAVE_DOPRNT 1 _ACEOF fi fi done for ac_func in strerror do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 for ac_func in mempcpy strndup strchrnul do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIB@&t@OBJS " in *" $ac_func.$ac_objext "* ) ;; *) LIB@&t@OBJS="$LIB@&t@OBJS $ac_func.$ac_objext" ;; esac fi done # At least on freebsd, putc_unlocked is a macro, so the standard # AC_CHECK_FUNCS doesn't work well. { $as_echo "$as_me:$LINENO: checking for putc_unlocked('x', stdout)" >&5 $as_echo_n "checking for putc_unlocked('x', stdout)... " >&6; } if test "${ac_cv_func_call_putc_unlocked+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { putc_unlocked('x', stdout) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_call_putc_unlocked=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_call_putc_unlocked=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_call_putc_unlocked" >&5 $as_echo "$ac_cv_func_call_putc_unlocked" >&6; } if test $ac_cv_func_call_putc_unlocked = yes ; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_PUTC_UNLOCKED 1 _ACEOF else true fi for ac_func in flockfile do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 for ac_func in fputs_unlocked fwrite_unlocked do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 # Used only by argp-test.c, so don't use AC_REPLACE_FUNCS. for ac_func in strdup asprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$LINENO: checking whether program_invocation_name is declared" >&5 $as_echo_n "checking whether program_invocation_name is declared... " >&6; } if test "${ac_cv_have_decl_program_invocation_name+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef program_invocation_name (void) program_invocation_name; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_program_invocation_name=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_program_invocation_name=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_program_invocation_name" >&5 $as_echo "$ac_cv_have_decl_program_invocation_name" >&6; } if test "x$ac_cv_have_decl_program_invocation_name" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 _ACEOF else cat >>confdefs.h <<_ACEOF @%:@define HAVE_DECL_PROGRAM_INVOCATION_NAME 0 _ACEOF fi { $as_echo "$as_me:$LINENO: checking whether program_invocation_short_name is declared" >&5 $as_echo_n "checking whether program_invocation_short_name is declared... " >&6; } if test "${ac_cv_have_decl_program_invocation_short_name+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef program_invocation_short_name (void) program_invocation_short_name; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_program_invocation_short_name=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_program_invocation_short_name=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_program_invocation_short_name" >&5 $as_echo "$ac_cv_have_decl_program_invocation_short_name" >&6; } if test "x$ac_cv_have_decl_program_invocation_short_name" = x""yes; then cat >>confdefs.h <<_ACEOF @%:@define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 _ACEOF else cat >>confdefs.h <<_ACEOF @%:@define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 0 _ACEOF fi # Set these flags *last*, or else the test programs won't compile if test x$GCC = xyes ; then # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then true else CFLAGS="$CFLAGS -ggdb3" fi CFLAGS="$CFLAGS -Wall -W \ -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ -Waggregate-return \ -Wpointer-arith -Wbad-function-cast -Wnested-externs" fi CPPFLAGS="$CPPFLAGS -I$srcdir" ac_config_files="$ac_config_files Makefile testsuite/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:$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= ;; #( *) $as_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:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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 : $LIB@&t@OBJS; 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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIB@&t@OBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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 # 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.63. 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" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -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 Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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' AWK='$AWK' 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 CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _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" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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 test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands 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 '{ (exit 1); 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_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _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_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } 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 ;; :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || 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" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ @%:@]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # 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 -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //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_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi wvstreams-4.6.1/argp/Versions0000644000175000001440000000053511077124114015257 0ustar wlachuserslibc { GLIBC_2.1 { # variables in normal name space argp_err_exit_status; argp_program_bug_address; argp_program_version; argp_program_version_hook; # a* argp_error; argp_failure; argp_help; argp_parse; argp_state_help; argp_usage; # kludge for recursive argp callers that know the magic. _argp_unlock_xxx; } } wvstreams-4.6.1/argp/aclocal.m40000644000175000001440000010561711077124114015373 0ustar wlachusers# generated automatically by aclocal 1.8.2 -*- 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.8"]) # 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.8.2])]) # 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` ]) # Copyright (C) 1996, 1997, 1999, 2000, 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 3 # This was merged into AC_PROG_CC in Autoconf. AU_DEFUN([AM_PROG_CC_STDC], [AC_PROG_CC AC_DIAGNOSE([obsolete], [$0: your code should no longer depend upon `am_cv_prog_cc_stdc', but upon `ac_cv_prog_cc_stdc'. Remove this warning and the assignment when you adjust the code. You can also remove the above call to AC_PROG_CC if you already called it elsewhere.]) am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc ]) AU_DEFUN([fp_PROG_CC_STDC]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 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 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 6 -*- 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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' 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 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 grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # 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 -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //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 # 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_MISSING_PROG(AMTAR, tar) 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([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. AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p -- . 2>/dev/null; then # Keeping the `.' argument allows $(mkdir_p) to be used without # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more # expensive solution, as it forces Make to start a sub-shell.) 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 ./--; 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])]) m4_include([acinclude.m4]) wvstreams-4.6.1/argp/configure0000755000175000001440000100401211260431131015420 0ustar wlachusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="argp-ba.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 ALLOCA AR RANLIB EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__leading_dot SET_MAKE AWK mkdir_p INSTALL_STRIP_PROGRAM STRIP install_sh AMTAR MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM 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_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking ' 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _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] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors 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. _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.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # 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:$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= ;; #( *) $as_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'; { (exit 1); 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 # 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 # 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:$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:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 am__api_version="1.8" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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:$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:$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' { $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # 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". { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` 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= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p -- . 2>/dev/null; then # Keeping the `.' argument allows $(mkdir_p) to be used without # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more # expensive solution, as it forces Make to start a sub-shell.) 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 ./--; 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 for ac_prog in gawk mawk nawk awk 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # 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_AWK="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi 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 # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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 # Define the identity of the package. PACKAGE=argp VERSION=standalone-1.3 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # 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. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. ac_config_headers="$ac_config_headers config.h" # GNU libc defaults to supplying the ISO C library functions only. The # _GNU_SOURCE define enables these extensions, in particular we want # errno.h to declare program_invocation_name. Enable it on all # systems; no problems have been reported with it so far. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" 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. { $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } 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 { $as_echo "$as_me:$LINENO: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= 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 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } 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:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 if test "${ac_cv_header_minix_config_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking minix/config.h usability" >&5 $as_echo_n "checking minix/config.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking minix/config.h presence" >&5 $as_echo_n "checking minix/config.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_minix_config_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } fi if test "x$ac_cv_header_minix_config_h" = x""yes; then MINIX=yes else MINIX= fi if test "$MINIX" = yes; then cat >>confdefs.h <<\_ACEOF #define _POSIX_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_1_SOURCE 2 _ACEOF cat >>confdefs.h <<\_ACEOF #define _MINIX 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_safe_to_define___extensions__=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$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 && cat >>confdefs.h <<\_ACEOF #define __EXTENSIONS__ 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _ALL_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _GNU_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _TANDEM_SOURCE 1 _ACEOF # Checks for programs. 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" 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:$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:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 # 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:$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:$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=":" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gar", so it can be a program name with args. set dummy gar; ac_word=$2 { $as_echo "$as_me:$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="gar" $as_echo "$as_me:$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=":" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } 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 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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$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:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then $as_echo_n "(cached) " >&6 else 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_CC_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 : > 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 # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc if test "x$am_cv_prog_cc_stdc" = xno ; then { { $as_echo "$as_me:$LINENO: error: the C compiler doesn't handle ANSI-C" >&5 $as_echo "$as_me: error: the C compiler doesn't handle ANSI-C" >&2;} { (exit 1); exit 1; }; } fi # Checks for libraries. # Checks for header files. { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi for ac_header in limits.h malloc.h unistd.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` 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 # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } 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:$LINENO: checking for __attribute__" >&5 $as_echo_n "checking for __attribute__... " >&6; } if test "${lsh_cv_c_attribute+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { static void foo(void) __attribute__ ((noreturn)); static void __attribute__ ((noreturn)) foo(void) { exit(1); } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then lsh_cv_c_attribute=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lsh_cv_c_attribute=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $lsh_cv_c_attribute" >&5 $as_echo "$lsh_cv_c_attribute" >&6; } if test "x$lsh_cv_c_attribute" = "xyes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_GCC_ATTRIBUTE 1 _ACEOF fi # Checks for library functions. # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_working_alloca_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_alloca_works=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF 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 cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF { $as_echo "$as_me:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 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 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$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 for ac_func in vprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { $as_echo "$as_me:$LINENO: checking for _doprnt" >&5 $as_echo_n "checking for _doprnt... " >&6; } if test "${ac_cv_func__doprnt+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _doprnt to an innocuous variant, in case declares _doprnt. For example, HP-UX 11i declares gettimeofday. */ #define _doprnt innocuous__doprnt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _doprnt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _doprnt /* 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 _doprnt (); /* 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__doprnt || defined __stub____doprnt choke me #endif int main () { return _doprnt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func__doprnt=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__doprnt=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 $as_echo "$ac_cv_func__doprnt" >&6; } if test "x$ac_cv_func__doprnt" = x""yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DOPRNT 1 _ACEOF fi fi done for ac_func in strerror do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 for ac_func in mempcpy strndup strchrnul do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else case " $LIBOBJS " in *" $ac_func.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; esac fi done # At least on freebsd, putc_unlocked is a macro, so the standard # AC_CHECK_FUNCS doesn't work well. { $as_echo "$as_me:$LINENO: checking for putc_unlocked('x', stdout)" >&5 $as_echo_n "checking for putc_unlocked('x', stdout)... " >&6; } if test "${ac_cv_func_call_putc_unlocked+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { putc_unlocked('x', stdout) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_call_putc_unlocked=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_call_putc_unlocked=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_call_putc_unlocked" >&5 $as_echo "$ac_cv_func_call_putc_unlocked" >&6; } if test $ac_cv_func_call_putc_unlocked = yes ; then cat >>confdefs.h <<_ACEOF #define HAVE_PUTC_UNLOCKED 1 _ACEOF else true fi for ac_func in flockfile do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 for ac_func in fputs_unlocked fwrite_unlocked do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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 # Used only by argp-test.c, so don't use AC_REPLACE_FUNCS. for ac_func in strdup asprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` 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:$LINENO: checking whether program_invocation_name is declared" >&5 $as_echo_n "checking whether program_invocation_name is declared... " >&6; } if test "${ac_cv_have_decl_program_invocation_name+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef program_invocation_name (void) program_invocation_name; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_program_invocation_name=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_program_invocation_name=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_program_invocation_name" >&5 $as_echo "$ac_cv_have_decl_program_invocation_name" >&6; } if test "x$ac_cv_have_decl_program_invocation_name" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PROGRAM_INVOCATION_NAME 0 _ACEOF fi { $as_echo "$as_me:$LINENO: checking whether program_invocation_short_name is declared" >&5 $as_echo_n "checking whether program_invocation_short_name is declared... " >&6; } if test "${ac_cv_have_decl_program_invocation_short_name+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef program_invocation_short_name (void) program_invocation_short_name; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_have_decl_program_invocation_short_name=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_program_invocation_short_name=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_program_invocation_short_name" >&5 $as_echo "$ac_cv_have_decl_program_invocation_short_name" >&6; } if test "x$ac_cv_have_decl_program_invocation_short_name" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 0 _ACEOF fi # Set these flags *last*, or else the test programs won't compile if test x$GCC = xyes ; then # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then true else CFLAGS="$CFLAGS -ggdb3" fi CFLAGS="$CFLAGS -Wall -W \ -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ -Waggregate-return \ -Wpointer-arith -Wbad-function-cast -Wnested-externs" fi CPPFLAGS="$CPPFLAGS -I$srcdir" ac_config_files="$ac_config_files Makefile testsuite/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:$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= ;; #( *) $as_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:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits 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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 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=: 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 # 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.63. 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" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -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 Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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' AWK='$AWK' 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 CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _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" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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 test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands 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 '{ (exit 1); 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_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _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_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } 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:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } 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 ;; :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || 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" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # 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 -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //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_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi wvstreams-4.6.1/argp/TODO0000644000175000001440000000012311077124114014205 0ustar wlachusersFigure out what to do about extern inline, as it's not supported by newer gcc-3.x. wvstreams-4.6.1/argp/argp.h0000644000175000001440000006352311077124114014634 0ustar wlachusers/* Hierarchial argument parsing. Copyright (C) 1995, 96, 97, 98, 99, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ARGP_H #define _ARGP_H #include #include #define __need_error_t #include #ifndef __THROW # define __THROW #endif #ifndef __const # define __const const #endif #ifndef __error_t_defined typedef int error_t; # define __error_t_defined #endif /* FIXME: What's the right way to check for __restrict? Sun's cc seems not to have it. Perhaps it's easiest to just delete the use of __restrict from the prototypes. */ #ifndef __restrict # ifndef __GNUC___ # define __restrict # endif #endif /* NOTE: We can't use the autoconf tests, since this is supposed to be an installed header file and argp's config.h is of course not installed. */ #ifndef PRINTF_STYLE # if __GNUC__ >= 2 # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) # else # define PRINTF_STYLE(f, a) # endif #endif #ifdef __cplusplus extern "C" { #endif /* A description of a particular option. A pointer to an array of these is passed in the OPTIONS field of an argp structure. Each option entry can correspond to one long option and/or one short option; more names for the same option can be added by following an entry in an option array with options having the OPTION_ALIAS flag set. */ struct argp_option { /* The long option name. For more than one name for the same option, you can use following options with the OPTION_ALIAS flag set. */ __const char *name; /* What key is returned for this option. If > 0 and printable, then it's also accepted as a short option. */ int key; /* If non-NULL, this is the name of the argument associated with this option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ __const char *arg; /* OPTION_ flags. */ int flags; /* The doc string for this option. If both NAME and KEY are 0, This string will be printed outdented from the normal option column, making it useful as a group header (it will be the first thing printed in its group); in this usage, it's conventional to end the string with a `:'. */ __const char *doc; /* The group this option is in. In a long help message, options are sorted alphabetically within each group, and the groups presented in the order 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with if this field 0 will inherit the group number of the previous entry, or zero if it's the first one, unless its a group header (NAME and KEY both 0), in which case, the previous entry + 1 is the default. Automagic options such as --help are put into group -1. */ int group; }; /* The argument associated with this option is optional. */ #define OPTION_ARG_OPTIONAL 0x1 /* This option isn't displayed in any help messages. */ #define OPTION_HIDDEN 0x2 /* This option is an alias for the closest previous non-alias option. This means that it will be displayed in the same help entry, and will inherit fields other than NAME and KEY from the aliased option. */ #define OPTION_ALIAS 0x4 /* This option isn't actually an option (and so should be ignored by the actual option parser), but rather an arbitrary piece of documentation that should be displayed in much the same manner as the options. If this flag is set, then the option NAME field is displayed unmodified (e.g., no `--' prefix is added) at the left-margin (where a *short* option would normally be displayed), and the documentation string in the normal place. For purposes of sorting, any leading whitespace and puncuation is ignored, except that if the first non-whitespace character is not `-', this entry is displayed after all options (and OPTION_DOC entries with a leading `-') in the same group. */ #define OPTION_DOC 0x8 /* This option shouldn't be included in `long' usage messages (but is still included in help messages). This is mainly intended for options that are completely documented in an argp's ARGS_DOC field, in which case including the option in the generic usage list would be redundant. For instance, if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to distinguish these two cases, -x should probably be marked OPTION_NO_USAGE. */ #define OPTION_NO_USAGE 0x10 struct argp; /* fwd declare this type */ struct argp_state; /* " */ struct argp_child; /* " */ /* The type of a pointer to an argp parsing function. */ typedef error_t (*argp_parser_t) (int key, char *arg, struct argp_state *state); /* What to return for unrecognized keys. For special ARGP_KEY_ keys, such returns will simply be ignored. For user keys, this error will be turned into EINVAL (if the call to argp_parse is such that errors are propagated back to the user instead of exiting); returning EINVAL itself would result in an immediate stop to parsing in *all* cases. */ #define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ /* Special values for the KEY argument to an argument parsing function. ARGP_ERR_UNKNOWN should be returned if they aren't understood. The sequence of keys to a parsing function is either (where each uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized The third case is where every parser returned ARGP_KEY_UNKNOWN for an argument, in which case parsing stops at that argument (returning the unparsed arguments to the caller of argp_parse if requested, or stopping with an error message if not). If an error occurs (either detected by argp, or because the parsing function returned an error value), then the parser is called with ARGP_KEY_ERROR, and no further calls are made. */ /* This is not an option at all, but rather a command line argument. If a parser receiving this key returns success, the fact is recorded, and the ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the argument, a parser function decrements the NEXT field of the state it's passed, the option won't be considered processed; this is to allow you to actually modify the argument (perhaps into an option), and have it processed again. */ #define ARGP_KEY_ARG 0 /* There are remaining arguments not parsed by any parser, which may be found starting at (STATE->argv + STATE->next). If success is returned, but STATE->next left untouched, it's assumed that all arguments were consume, otherwise, the parser should adjust STATE->next to reflect any arguments consumed. */ #define ARGP_KEY_ARGS 0x1000006 /* There are no more command line arguments at all. */ #define ARGP_KEY_END 0x1000001 /* Because it's common to want to do some special processing if there aren't any non-option args, user parsers are called with this key if they didn't successfully process any non-option arguments. Called just before ARGP_KEY_END (where more general validity checks on previously parsed arguments can take place). */ #define ARGP_KEY_NO_ARGS 0x1000002 /* Passed in before any parsing is done. Afterwards, the values of each element of the CHILD_INPUT field, if any, in the state structure is copied to each child's state to be the initial value of the INPUT field. */ #define ARGP_KEY_INIT 0x1000003 /* Use after all other keys, including SUCCESS & END. */ #define ARGP_KEY_FINI 0x1000007 /* Passed in when parsing has successfully been completed (even if there are still arguments remaining). */ #define ARGP_KEY_SUCCESS 0x1000004 /* Passed in if an error occurs. */ #define ARGP_KEY_ERROR 0x1000005 /* An argp structure contains a set of options declarations, a function to deal with parsing one, documentation string, a possible vector of child argp's, and perhaps a function to filter help output. When actually parsing options, getopt is called with the union of all the argp structures chained together through their CHILD pointers, with conflicts being resolved in favor of the first occurrence in the chain. */ struct argp { /* An array of argp_option structures, terminated by an entry with both NAME and KEY having a value of 0. */ __const struct argp_option *options; /* What to do with an option from this structure. KEY is the key associated with the option, and ARG is any associated argument (NULL if none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then parsing is stopped immediately, and that value is returned from argp_parse(). For special (non-user-supplied) values of KEY, see the ARGP_KEY_ definitions below. */ argp_parser_t parser; /* A string describing what other arguments are wanted by this program. It is only used by argp_usage to print the `Usage:' message. If it contains newlines, the strings separated by them are considered alternative usage patterns, and printed on separate lines (lines after the first are prefix by ` or: ' instead of `Usage:'). */ __const char *args_doc; /* If non-NULL, a string containing extra text to be printed before and after the options in a long help message (separated by a vertical tab `\v' character). */ __const char *doc; /* A vector of argp_children structures, terminated by a member with a 0 argp field, pointing to child argps should be parsed with this one. Any conflicts are resolved in favor of this argp, or early argps in the CHILDREN list. This field is useful if you use libraries that supply their own argp structure, which you want to use in conjunction with your own. */ __const struct argp_child *children; /* If non-zero, this should be a function to filter the output of help messages. KEY is either a key from an option, in which case TEXT is that option's help text, or a special key from the ARGP_KEY_HELP_ defines, below, describing which other help text TEXT is. The function should return either TEXT, if it should be used as-is, a replacement string, which should be malloced, and will be freed by argp, or NULL, meaning `print nothing'. The value for TEXT is *after* any translation has been done, so if any of the replacement text also needs translation, that should be done by the filter function. INPUT is either the input supplied to argp_parse, or NULL, if argp_help was called directly. */ char *(*help_filter) (int __key, __const char *__text, void *__input); /* If non-zero the strings used in the argp library are translated using the domain described by this string. Otherwise the currently installed default domain is used. */ const char *argp_domain; }; /* Possible KEY arguments to a help filter function. */ #define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ #define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ #define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ #define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; TEXT is NULL for this key. */ /* Explanatory note emitted when duplicate option arguments have been suppressed. */ #define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 #define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ /* When an argp has a non-zero CHILDREN field, it should point to a vector of argp_child structures, each of which describes a subsidiary argp. */ struct argp_child { /* The child parser. */ __const struct argp *argp; /* Flags for this child. */ int flags; /* If non-zero, an optional header to be printed in help output before the child options. As a side-effect, a non-zero value forces the child options to be grouped together; to achieve this effect without actually printing a header string, use a value of "". */ __const char *header; /* Where to group the child options relative to the other (`consolidated') options in the parent argp; the values are the same as the GROUP field in argp_option structs, but all child-groupings follow parent options at a particular group level. If both this field and HEADER are zero, then they aren't grouped at all, but rather merged with the parent options (merging the child's grouping levels with the parents). */ int group; }; /* Parsing state. This is provided to parsing functions called by argp, which may examine and, as noted, modify fields. */ struct argp_state { /* The top level ARGP being parsed. */ __const struct argp *root_argp; /* The argument vector being parsed. May be modified. */ int argc; char **argv; /* The index in ARGV of the next arg that to be parsed. May be modified. */ int next; /* The flags supplied to argp_parse. May be modified. */ unsigned flags; /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the number of the current arg, starting at zero, and incremented after each such call returns. At all other times, this is the number of such arguments that have been processed. */ unsigned arg_num; /* If non-zero, the index in ARGV of the first argument following a special `--' argument (which prevents anything following being interpreted as an option). Only set once argument parsing has proceeded past this point. */ int quoted; /* An arbitrary pointer passed in from the user. */ void *input; /* Values to pass to child parsers. This vector will be the same length as the number of children for the current parser. */ void **child_inputs; /* For the parser's use. Initialized to 0. */ void *hook; /* The name used when printing messages. This is initialized to ARGV[0], or PROGRAM_INVOCATION_NAME if that is unavailable. */ char *name; /* Streams used when argp prints something. */ FILE *err_stream; /* For errors; initialized to stderr. */ FILE *out_stream; /* For information; initialized to stdout. */ void *pstate; /* Private, for use by argp. */ }; /* Flags for argp_parse (note that the defaults are those that are convenient for program command line parsing): */ /* Don't ignore the first element of ARGV. Normally (and always unless ARGP_NO_ERRS is set) the first element of the argument vector is skipped for option parsing purposes, as it corresponds to the program name in a command line. */ #define ARGP_PARSE_ARGV0 0x01 /* Don't print error messages for unknown options to stderr; unless this flag is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program name in the error messages. This flag implies ARGP_NO_EXIT (on the assumption that silent exiting upon errors is bad behaviour). */ #define ARGP_NO_ERRS 0x02 /* Don't parse any non-option args. Normally non-option args are parsed by calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg as the value. Since it's impossible to know which parse function wants to handle it, each one is called in turn, until one returns 0 or an error other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the argp_parse returns prematurely (but with a return value of 0). If all args have been parsed without error, all parsing functions are called one last time with a key of ARGP_KEY_END. This flag needn't normally be set, as the normal behavior is to stop parsing as soon as some argument can't be handled. */ #define ARGP_NO_ARGS 0x04 /* Parse options and arguments in the same order they occur on the command line -- normally they're rearranged so that all options come first. */ #define ARGP_IN_ORDER 0x08 /* Don't provide the standard long option --help, which causes usage and option help information to be output to stdout, and exit (0) called. */ #define ARGP_NO_HELP 0x10 /* Don't exit on errors (they may still result in error messages). */ #define ARGP_NO_EXIT 0x20 /* Use the gnu getopt `long-only' rules for parsing arguments. */ #define ARGP_LONG_ONLY 0x40 /* Turns off any message-printing/exiting options. */ #define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) /* Parse the options strings in ARGC & ARGV according to the options in ARGP. FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the index in ARGV of the first unparsed option is returned in it. If an unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser routine returned a non-zero value, it is returned; otherwise 0 is returned. This function may also call exit unless the ARGP_NO_HELP flag is set. INPUT is a pointer to a value to be passed in to the parser. */ extern error_t argp_parse (__const struct argp *__restrict __argp, int /*argc*/, char **__restrict /*argv*/, unsigned __flags, int *__restrict __arg_index, void *__restrict __input) __THROW; extern error_t __argp_parse (__const struct argp *__restrict __argp, int /*argc*/, char **__restrict /*argv*/, unsigned __flags, int *__restrict __arg_index, void *__restrict __input) __THROW; /* Global variables. */ /* If defined or set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which will print this string followed by a newline and exit (unless the ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ extern __const char *argp_program_version; /* If defined or set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which calls this function with a stream to print the version to and a pointer to the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ extern void (*argp_program_version_hook) (FILE *__restrict __stream, struct argp_state *__restrict __state); /* If defined or set by the user program, it should point to string that is the bug-reporting address for the program. It will be printed by argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help messages), embedded in a sentence that says something like `Report bugs to ADDR.'. */ extern __const char *argp_program_bug_address; /* The exit status that argp will use when exiting due to a parsing error. If not defined or set by the user program, this defaults to EX_USAGE from . */ extern error_t argp_err_exit_status; /* Flags for argp_help. */ #define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ #define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ #define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ #define ARGP_HELP_LONG 0x08 /* a long help message. */ #define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ #define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ #define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) #define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ #define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to reflect ARGP_LONG_ONLY mode. */ /* These ARGP_HELP flags are only understood by argp_state_help. */ #define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ #define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ /* The standard thing to do after a program command line parsing error, if an error message has already been printed. */ #define ARGP_HELP_STD_ERR \ (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) /* The standard thing to do after a program command line parsing error, if no more specific error message has been printed. */ #define ARGP_HELP_STD_USAGE \ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) /* The standard thing to do in response to a --help option. */ #define ARGP_HELP_STD_HELP \ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) /* Output a usage message for ARGP to STREAM. FLAGS are from the set ARGP_HELP_*. */ extern void argp_help (__const struct argp *__restrict __argp, FILE *__restrict __stream, unsigned __flags, char *__restrict __name) __THROW; extern void __argp_help (__const struct argp *__restrict __argp, FILE *__restrict __stream, unsigned __flags, char *__name) __THROW; /* The following routines are intended to be called from within an argp parsing routine (thus taking an argp_state structure as the first argument). They may or may not print an error message and exit, depending on the flags in STATE -- in any case, the caller should be prepared for them *not* to exit, and should return an appropiate error after calling them. [argp_usage & argp_error should probably be called argp_state_..., but they're used often enough that they should be short] */ /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are from the set ARGP_HELP_*. */ extern void argp_state_help (__const struct argp_state *__restrict __state, FILE *__restrict __stream, unsigned int __flags) __THROW; extern void __argp_state_help (__const struct argp_state *__restrict __state, FILE *__restrict __stream, unsigned int __flags) __THROW; /* Possibly output the standard usage message for ARGP to stderr and exit. */ extern void argp_usage (__const struct argp_state *__state) __THROW; extern void __argp_usage (__const struct argp_state *__state) __THROW; /* If appropriate, print the printf string FMT and following args, preceded by the program name and `:', to stderr, and followed by a `Try ... --help' message, then exit (1). */ extern void argp_error (__const struct argp_state *__restrict __state, __const char *__restrict __fmt, ...) __THROW PRINTF_STYLE(2,3); extern void __argp_error (__const struct argp_state *__restrict __state, __const char *__restrict __fmt, ...) __THROW PRINTF_STYLE(2,3); /* Similar to the standard gnu error-reporting function error(), but will respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print to STATE->err_stream. This is useful for argument parsing code that is shared between program startup (when exiting is desired) and runtime option parsing (when typically an error code is returned instead). The difference between this function and argp_error is that the latter is for *parsing errors*, and the former is for other problems that occur during parsing but don't reflect a (syntactic) problem with the input. */ extern void argp_failure (__const struct argp_state *__restrict __state, int __status, int __errnum, __const char *__restrict __fmt, ...) __THROW PRINTF_STYLE(4,5); extern void __argp_failure (__const struct argp_state *__restrict __state, int __status, int __errnum, __const char *__restrict __fmt, ...) __THROW PRINTF_STYLE(4,5); /* Returns true if the option OPT is a valid short option. */ extern int _option_is_short (__const struct argp_option *__opt) __THROW; extern int __option_is_short (__const struct argp_option *__opt) __THROW; /* Returns true if the option OPT is in fact the last (unused) entry in an options array. */ extern int _option_is_end (__const struct argp_option *__opt) __THROW; extern int __option_is_end (__const struct argp_option *__opt) __THROW; /* Return the input field for ARGP in the parser corresponding to STATE; used by the help routines. */ extern void *_argp_input (__const struct argp *__restrict __argp, __const struct argp_state *__restrict __state) __THROW; extern void *__argp_input (__const struct argp *__restrict __argp, __const struct argp_state *__restrict __state) __THROW; /* Used for extracting the program name from argv[0] */ extern char *_argp_basename(char *name) __THROW; extern char *__argp_basename(char *name) __THROW; /* Getting the program name given an argp state */ extern char * _argp_short_program_name(const struct argp_state *state) __THROW; extern char * __argp_short_program_name(const struct argp_state *state) __THROW; #ifdef __USE_EXTERN_INLINES # if !_LIBC # define __argp_usage argp_usage # define __argp_state_help argp_state_help # define __option_is_short _option_is_short # define __option_is_end _option_is_end # endif # ifndef ARGP_EI # define ARGP_EI extern __inline__ # endif ARGP_EI void __argp_usage (__const struct argp_state *__state) { __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); } ARGP_EI int __option_is_short (__const struct argp_option *__opt) { if (__opt->flags & OPTION_DOC) return 0; else { int __key = __opt->key; return __key > 0 && isprint (__key); } } ARGP_EI int __option_is_end (__const struct argp_option *__opt) { return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; } # if !_LIBC # undef __argp_usage # undef __argp_state_help # undef __option_is_short # undef __option_is_end # endif #endif /* Use extern inlines. */ #ifdef __cplusplus } #endif #endif /* argp.h */ wvstreams-4.6.1/argp/argp-pvh.c0000644000175000001440000000275711077124114015424 0ustar wlachusers/* Default definition for ARGP_PROGRAM_VERSION_HOOK. Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "argp.h" /* If set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which calls this function with a stream to print the version to and a pointer to the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = 0; wvstreams-4.6.1/argp/argp-fmtstream.h0000644000175000001440000002623611077124114016634 0ustar wlachusers/* Word-wrapping and line-truncating streams. Copyright (C) 1997, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This package emulates glibc `line_wrap_stream' semantics for systems that don't have that. If the system does have it, it is just a wrapper for that. This header file is only used internally while compiling argp, and shouldn't be installed. */ #ifndef _ARGP_FMTSTREAM_H #define _ARGP_FMTSTREAM_H #include #include #include #if _LIBC || (defined (HAVE_FLOCKFILE) && defined(HAVE_PUTC_UNLOCKED) \ && defined (HAVE_FPUTS_UNLOCKED) && defined (HAVE_FWRITE_UNLOCKED) ) /* Use locking funxtions */ # define FLOCKFILE(f) flockfile(f) # define FUNLOCKFILE(f) funlockfile(f) # define PUTC_UNLOCKED(c, f) putc_unlocked((c), (f)) # define FPUTS_UNLOCKED(s, f) fputs_unlocked((s), (f)) # define FWRITE_UNLOCKED(b, s, n, f) fwrite_unlocked((b), (s), (n), (f)) #else /* Disable stdio locking */ # define FLOCKFILE(f) # define FUNLOCKFILE(f) #ifndef _WIN32 # define PUTC_UNLOCKED(c, f) putc((c), (f)) #else /* Mingw does something really dumb with putc (probably evaluating the 'stream' * argument to it, which putc can technically do by the spec), which causes it * to fatally abort. If we use fputc, this problem goes away */ # define PUTC_UNLOCKED(c, f) fputc((c), (f)) #endif # define FPUTS_UNLOCKED(s, f) fputs((s), (f)) # define FWRITE_UNLOCKED(b, s, n, f) fwrite((b), (s), (n), (f)) #endif /* No thread safe i/o */ #if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) /* line_wrap_stream is available, so use that. */ #define ARGP_FMTSTREAM_USE_LINEWRAP #endif #ifdef ARGP_FMTSTREAM_USE_LINEWRAP /* Just be a simple wrapper for line_wrap_stream; the semantics are *slightly* different, as line_wrap_stream doesn't actually make a new object, it just modifies the given stream (reversibly) to do line-wrapping. Since we control who uses this code, it doesn't matter. */ #include typedef FILE *argp_fmtstream_t; #define argp_make_fmtstream line_wrap_stream #define __argp_make_fmtstream line_wrap_stream #define argp_fmtstream_free line_unwrap_stream #define __argp_fmtstream_free line_unwrap_stream #define __argp_fmtstream_putc(fs,ch) putc(ch,fs) #define argp_fmtstream_putc(fs,ch) putc(ch,fs) #define __argp_fmtstream_puts(fs,str) fputs(str,fs) #define argp_fmtstream_puts(fs,str) fputs(str,fs) #define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) #define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) #define __argp_fmtstream_printf fprintf #define argp_fmtstream_printf fprintf #define __argp_fmtstream_lmargin line_wrap_lmargin #define argp_fmtstream_lmargin line_wrap_lmargin #define __argp_fmtstream_set_lmargin line_wrap_set_lmargin #define argp_fmtstream_set_lmargin line_wrap_set_lmargin #define __argp_fmtstream_rmargin line_wrap_rmargin #define argp_fmtstream_rmargin line_wrap_rmargin #define __argp_fmtstream_set_rmargin line_wrap_set_rmargin #define argp_fmtstream_set_rmargin line_wrap_set_rmargin #define __argp_fmtstream_wmargin line_wrap_wmargin #define argp_fmtstream_wmargin line_wrap_wmargin #define __argp_fmtstream_set_wmargin line_wrap_set_wmargin #define argp_fmtstream_set_wmargin line_wrap_set_wmargin #define __argp_fmtstream_point line_wrap_point #define argp_fmtstream_point line_wrap_point #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ /* Guess we have to define our own version. */ #ifndef __const #define __const const #endif struct argp_fmtstream { FILE *stream; /* The stream we're outputting to. */ size_t lmargin, rmargin; /* Left and right margins. */ ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ /* Point in buffer to which we've processed for wrapping, but not output. */ size_t point_offs; /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ ssize_t point_col; char *buf; /* Output buffer. */ char *p; /* Current end of text in BUF. */ char *end; /* Absolute end of BUF. */ }; typedef struct argp_fmtstream *argp_fmtstream_t; /* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines written on it with LMARGIN spaces and limits them to RMARGIN columns total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by replacing the whitespace before them with a newline and WMARGIN spaces. Otherwise, chars beyond RMARGIN are simply dropped until a newline. Returns NULL if there was an error. */ extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, size_t __lmargin, size_t __rmargin, ssize_t __wmargin); extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, size_t __lmargin, size_t __rmargin, ssize_t __wmargin); /* Flush __FS to its stream, and free it (but don't close the stream). */ extern void __argp_fmtstream_free (argp_fmtstream_t __fs); extern void argp_fmtstream_free (argp_fmtstream_t __fs); extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, __const char *__fmt, ...) PRINTF_STYLE(2,3); extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, __const char *__fmt, ...) PRINTF_STYLE(2,3); extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str); extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str); extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len); extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len); /* Access macros for various bits of state. */ #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) #define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) #define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) #define __argp_fmtstream_lmargin argp_fmtstream_lmargin #define __argp_fmtstream_rmargin argp_fmtstream_rmargin #define __argp_fmtstream_wmargin argp_fmtstream_wmargin /* Set __FS's left margin to LMARGIN and return the old value. */ extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin); extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin); /* Set __FS's right margin to __RMARGIN and return the old value. */ extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin); extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin); /* Set __FS's wrap margin to __WMARGIN and return the old value. */ extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin); extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin); /* Return the column number of the current output point in __FS. */ extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); /* Internal routines. */ extern void _argp_fmtstream_update (argp_fmtstream_t __fs); extern void __argp_fmtstream_update (argp_fmtstream_t __fs); extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); #ifdef __OPTIMIZE__ /* Inline versions of above routines. */ #if !_LIBC #define __argp_fmtstream_putc argp_fmtstream_putc #define __argp_fmtstream_puts argp_fmtstream_puts #define __argp_fmtstream_write argp_fmtstream_write #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin #define __argp_fmtstream_point argp_fmtstream_point #define __argp_fmtstream_update _argp_fmtstream_update #define __argp_fmtstream_ensure _argp_fmtstream_ensure #endif #ifndef ARGP_FS_EI #define ARGP_FS_EI extern inline #endif ARGP_FS_EI size_t __argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len) { if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) { memcpy (__fs->p, __str, __len); __fs->p += __len; return __len; } else return 0; } ARGP_FS_EI int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str) { size_t __len = strlen (__str); if (__len) { size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); return __wrote == __len ? 0 : -1; } else return 0; } ARGP_FS_EI int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) { if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) return *__fs->p++ = __ch; else return EOF; } /* Set __FS's left margin to __LMARGIN and return the old value. */ ARGP_FS_EI size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->lmargin; __fs->lmargin = __lmargin; return __old; } /* Set __FS's right margin to __RMARGIN and return the old value. */ ARGP_FS_EI size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->rmargin; __fs->rmargin = __rmargin; return __old; } /* Set FS's wrap margin to __WMARGIN and return the old value. */ ARGP_FS_EI size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) { size_t __old; if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); __old = __fs->wmargin; __fs->wmargin = __wmargin; return __old; } /* Return the column number of the current output point in __FS. */ ARGP_FS_EI size_t __argp_fmtstream_point (argp_fmtstream_t __fs) { if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) __argp_fmtstream_update (__fs); return __fs->point_col >= 0 ? __fs->point_col : 0; } #if !_LIBC #undef __argp_fmtstream_putc #undef __argp_fmtstream_puts #undef __argp_fmtstream_write #undef __argp_fmtstream_set_lmargin #undef __argp_fmtstream_set_rmargin #undef __argp_fmtstream_set_wmargin #undef __argp_fmtstream_point #undef __argp_fmtstream_update #undef __argp_fmtstream_ensure #endif #endif /* __OPTIMIZE__ */ #endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ #endif /* argp-fmtstream.h */ wvstreams-4.6.1/argp/argp-eexst.c0000644000175000001440000000254511077124114015752 0ustar wlachusers/* Default definition for ARGP_ERR_EXIT_STATUS Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifndef _WIN32 #include #else /* Stolen right from sysexits.h in Ubuntu 8.04 */ #define EX_USAGE 64 #endif #include "argp.h" /* The exit status that argp will use when exiting due to a parsing error. If not defined or set by the user program, this defaults to EX_USAGE from . */ error_t argp_err_exit_status = EX_USAGE; wvstreams-4.6.1/argp/strndup.c0000644000175000001440000000066411077124114015372 0ustar wlachusers/* strndup.c * */ /* Written by Niels Möller * * This file is hereby placed in the public domain. */ #include #include char * strndup (const char *s, size_t size) { char *r; char *end = memchr(s, 0, size); if (end) /* Length + 1 */ size = end - s + 1; r = malloc(size); if (size) { memcpy(r, s, size-1); r[size-1] = '\0'; } return r; } wvstreams-4.6.1/argp/argp-parse.c0000644000175000001440000010755311077124114015741 0ustar wlachusers/* Hierarchial argument parsing Copyright (C) 1995, 96, 97, 98, 99, 2000,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #ifdef HAVE_CONFIG_H #include #endif /* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif #include #include #include #include #include #ifdef _WIN32 #include #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # if defined HAVE_LIBINTL_H || defined _LIBC # include # ifdef _LIBC # undef dgettext # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES) # endif # else # define dgettext(domain, msgid) (msgid) # define gettext(msgid) (msgid) # endif #endif #ifndef N_ # define N_(msgid) (msgid) #endif #if _LIBC - 0 #include #else #ifdef HAVE_CTHREADS_H #include #endif #endif /* _LIBC */ #include "argp.h" #include "argp-namefrob.h" /* The meta-argument used to prevent any further arguments being interpreted as options. */ #define QUOTE "--" /* EZ alias for ARGP_ERR_UNKNOWN. */ #define EBADKEY ARGP_ERR_UNKNOWN /* Default options. */ /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep for one second intervals, decrementing _ARGP_HANG until it's zero. Thus you can force the program to continue by attaching a debugger and setting it to 0 yourself. */ volatile int _argp_hang; #define OPT_PROGNAME -2 #define OPT_USAGE -3 #define OPT_HANG -4 static const struct argp_option argp_default_options[] = { {"help", '?', 0, 0, N_("Give this help list"), -1}, {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0 }, {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0}, {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, N_("Hang for SECS seconds (default 3600)"), 0 }, {0, 0, 0, 0, 0, 0} }; static error_t argp_default_parser (int key, char *arg, struct argp_state *state) { switch (key) { case '?': __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); break; case OPT_USAGE: __argp_state_help (state, state->out_stream, ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); break; case OPT_PROGNAME: /* Set the program name. */ #if HAVE_DECL_PROGRAM_INVOCATION_NAME program_invocation_name = arg; #endif /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined to be that, so we have to be a bit careful here.] */ /* Update what we use for messages. */ state->name = __argp_basename(arg); #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME program_invocation_short_name = state->name; #endif if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) == ARGP_PARSE_ARGV0) /* Update what getopt uses too. */ state->argv[0] = arg; break; case OPT_HANG: _argp_hang = atoi (arg ? arg : "3600"); fprintf(state->err_stream, "%s: pid = %ld\n", state->name, (long) getpid()); while (_argp_hang-- > 0) __sleep(1); break; default: return EBADKEY; } return 0; } static const struct argp argp_default_argp = {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; static const struct argp_option argp_version_options[] = { {"version", 'V', 0, 0, N_("Print program version"), -1}, {0, 0, 0, 0, 0, 0 } }; static error_t argp_version_parser (int key, char *arg UNUSED, struct argp_state *state) { switch (key) { case 'V': if (argp_program_version_hook) (*argp_program_version_hook) (state->out_stream, state); else if (argp_program_version) fprintf (state->out_stream, "%s\n", argp_program_version); else __argp_error (state, dgettext (state->root_argp->argp_domain, "(PROGRAM ERROR) No version known!?")); if (! (state->flags & ARGP_NO_EXIT)) exit (0); break; default: return EBADKEY; } return 0; } static const struct argp argp_version_argp = {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; /* The state of a `group' during parsing. Each group corresponds to a particular argp structure from the tree of such descending from the top level argp passed to argp_parse. */ struct group { /* This group's parsing function. */ argp_parser_t parser; /* Which argp this group is from. */ const struct argp *argp; /* The number of non-option args sucessfully handled by this parser. */ unsigned args_processed; /* This group's parser's parent's group. */ struct group *parent; unsigned parent_index; /* And the our position in the parent. */ /* These fields are swapped into and out of the state structure when calling this group's parser. */ void *input, **child_inputs; void *hook; }; /* Call GROUP's parser with KEY and ARG, swapping any group-specific info from STATE before calling, and back into state afterwards. If GROUP has no parser, EBADKEY is returned. */ static error_t group_parse (struct group *group, struct argp_state *state, int key, char *arg) { if (group->parser) { error_t err; state->hook = group->hook; state->input = group->input; state->child_inputs = group->child_inputs; state->arg_num = group->args_processed; err = (*group->parser)(key, arg, state); group->hook = state->hook; return err; } else return EBADKEY; } struct parser { const struct argp *argp; const char *posixly_correct; /* True if there are only no-option arguments left, which are just passed verbatim with ARGP_KEY_ARG. This is set if we encounter a quote, or the end of the proper options, but may be cleared again if the user moves the next argument pointer backwards. */ int args_only; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. */ enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* A segment of non-option arguments that have been skipped for later processing, after all options. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. If quoted or args_only is non-zero, this segment should be empty. */ /* FIXME: I'd prefer to use unsigned, but it's more consistent to use the same type as for state.next. */ int first_nonopt; int last_nonopt; /* String of all recognized short options. Needed for ARGP_LONG_ONLY. */ /* FIXME: Perhaps change to a pointer to a suitable bitmap instead? */ char *short_opts; /* For parsing combined short options. */ char *nextchar; /* States of the various parsing groups. */ struct group *groups; /* The end of the GROUPS array. */ struct group *egroup; /* An vector containing storage for the CHILD_INPUTS field in all groups. */ void **child_inputs; /* State block supplied to parsing routines. */ struct argp_state state; /* Memory used by this parser. */ void *storage; }; /* Search for a group defining a short option. */ static const struct argp_option * find_short_option(struct parser *parser, int key, struct group **p) { struct group *group; assert(key >= 0); assert(isascii(key)); for (group = parser->groups; group < parser->egroup; group++) { const struct argp_option *opts; for (opts = group->argp->options; !__option_is_end(opts); opts++) if (opts->key == key) { *p = group; return opts; } } return NULL; } enum match_result { MATCH_EXACT, MATCH_PARTIAL, MATCH_NO }; /* If defined, allow complete.el-like abbreviations of long options. */ #ifndef ARGP_COMPLETE #define ARGP_COMPLETE 0 #endif /* Matches an encountern long-option argument ARG against an option NAME. * ARG is terminated by NUL or '='. */ static enum match_result match_option(const char *arg, const char *name) { unsigned i, j; for (i = j = 0;; i++, j++) { switch(arg[i]) { case '\0': case '=': return name[j] ? MATCH_PARTIAL : MATCH_EXACT; #if ARGP_COMPLETE case '-': while (name[j] != '-') if (!name[j++]) return MATCH_NO; break; #endif default: if (arg[i] != name[j]) return MATCH_NO; } } } static const struct argp_option * find_long_option(struct parser *parser, const char *arg, struct group **p) { struct group *group; /* Partial match found so far. */ struct group *matched_group = NULL; const struct argp_option *matched_option = NULL; /* Number of partial matches. */ int num_partial = 0; for (group = parser->groups; group < parser->egroup; group++) { const struct argp_option *opts; for (opts = group->argp->options; !__option_is_end(opts); opts++) { if (!opts->name) continue; switch (match_option(arg, opts->name)) { case MATCH_NO: break; case MATCH_PARTIAL: num_partial++; matched_group = group; matched_option = opts; break; case MATCH_EXACT: /* Exact match. */ *p = group; return opts; } } } if (num_partial == 1) { *p = matched_group; return matched_option; } return NULL; } /* The next usable entries in the various parser tables being filled in by convert_options. */ struct parser_convert_state { struct parser *parser; char *short_end; void **child_inputs_end; }; /* Initialize GROUP from ARGP. If CVT->SHORT_END is non-NULL, short options are recorded in the short options string. Returns the next unused group entry. CVT holds state used during the conversion. */ static struct group * convert_options (const struct argp *argp, struct group *parent, unsigned parent_index, struct group *group, struct parser_convert_state *cvt) { const struct argp_option *opt = argp->options; const struct argp_child *children = argp->children; if (opt || argp->parser) { /* This parser needs a group. */ if (cvt->short_end) { /* Record any short options. */ for ( ; !__option_is_end (opt); opt++) if (__option_is_short(opt)) *cvt->short_end++ = opt->key; } group->parser = argp->parser; group->argp = argp; group->args_processed = 0; group->parent = parent; group->parent_index = parent_index; group->input = 0; group->hook = 0; group->child_inputs = 0; if (children) /* Assign GROUP's CHILD_INPUTS field some space from CVT->child_inputs_end.*/ { unsigned num_children = 0; while (children[num_children].argp) num_children++; group->child_inputs = cvt->child_inputs_end; cvt->child_inputs_end += num_children; } parent = group++; } else parent = 0; if (children) { unsigned index = 0; while (children->argp) group = convert_options (children++->argp, parent, index++, group, cvt); } return group; } /* Allocate and initialize the group structures, so that they are ordered as if by traversing the corresponding argp parser tree in pre-order. Also build the list of short options, if that is needed. */ static void parser_convert (struct parser *parser, const struct argp *argp) { struct parser_convert_state cvt; cvt.parser = parser; cvt.short_end = parser->short_opts; cvt.child_inputs_end = parser->child_inputs; parser->argp = argp; if (argp) parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); else parser->egroup = parser->groups; /* No parsers at all! */ if (parser->short_opts) *cvt.short_end ='\0'; } /* Lengths of various parser fields which we will allocated. */ struct parser_sizes { /* Needed only ARGP_LONG_ONLY */ size_t short_len; /* Number of short options. */ size_t num_groups; /* Group structures we allocate. */ size_t num_child_inputs; /* Child input slots. */ }; /* For ARGP, increments the NUM_GROUPS field in SZS by the total number of argp structures descended from it, and the SHORT_LEN by the total number of short options. */ static void calc_sizes (const struct argp *argp, struct parser_sizes *szs) { const struct argp_child *child = argp->children; const struct argp_option *opt = argp->options; if (opt || argp->parser) { /* This parser needs a group. */ szs->num_groups++; if (opt) { while (__option_is_short (opt++)) szs->short_len++; } } if (child) while (child->argp) { calc_sizes ((child++)->argp, szs); szs->num_child_inputs++; } } /* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ static error_t parser_init (struct parser *parser, const struct argp *argp, int argc, char **argv, int flags, void *input) { error_t err = 0; struct group *group; struct parser_sizes szs; parser->posixly_correct = getenv ("POSIXLY_CORRECT"); if (flags & ARGP_IN_ORDER) parser->ordering = RETURN_IN_ORDER; else if (flags & ARGP_NO_ARGS) parser->ordering = REQUIRE_ORDER; else if (parser->posixly_correct) parser->ordering = REQUIRE_ORDER; else parser->ordering = PERMUTE; szs.short_len = 0; szs.num_groups = 0; szs.num_child_inputs = 0; if (argp) calc_sizes (argp, &szs); if (!(flags & ARGP_LONG_ONLY)) /* We have no use for the short option array. */ szs.short_len = 0; /* Lengths of the various bits of storage used by PARSER. */ #define GLEN (szs.num_groups + 1) * sizeof (struct group) #define CLEN (szs.num_child_inputs * sizeof (void *)) #define SLEN (szs.short_len + 1) #define STORAGE(offset) ((void *) (((char *) parser->storage) + (offset))) parser->storage = malloc (GLEN + CLEN + SLEN); if (! parser->storage) return ENOMEM; parser->groups = parser->storage; parser->child_inputs = STORAGE(GLEN); memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *)); if (flags & ARGP_LONG_ONLY) parser->short_opts = STORAGE(GLEN + CLEN); else parser->short_opts = NULL; parser_convert (parser, argp); memset (&parser->state, 0, sizeof (struct argp_state)); parser->state.root_argp = parser->argp; parser->state.argc = argc; parser->state.argv = argv; parser->state.flags = flags; parser->state.err_stream = stderr; parser->state.out_stream = stdout; parser->state.pstate = parser; parser->args_only = 0; parser->nextchar = NULL; parser->first_nonopt = parser->last_nonopt = 0; /* Call each parser for the first time, giving it a chance to propagate values to child parsers. */ if (parser->groups < parser->egroup) parser->groups->input = input; for (group = parser->groups; group < parser->egroup && (!err || err == EBADKEY); group++) { if (group->parent) /* If a child parser, get the initial input value from the parent. */ group->input = group->parent->child_inputs[group->parent_index]; if (!group->parser && group->argp->children && group->argp->children->argp) /* For the special case where no parsing function is supplied for an argp, propagate its input to its first child, if any (this just makes very simple wrapper argps more convenient). */ group->child_inputs[0] = group->input; err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); } if (err == EBADKEY) err = 0; /* Some parser didn't understand. */ if (err) return err; if (argv[0] && !(parser->state.flags & ARGP_PARSE_ARGV0)) /* There's an argv[0]; use it for messages. */ { parser->state.name = __argp_basename(argv[0]); /* Don't parse it as an argument. */ parser->state.next = 1; } else parser->state.name = __argp_short_program_name(NULL); return 0; } /* Free any storage consumed by PARSER (but not PARSER itself). */ static error_t parser_finalize (struct parser *parser, error_t err, int arg_ebadkey, int *end_index) { struct group *group; if (err == EBADKEY && arg_ebadkey) /* Suppress errors generated by unparsed arguments. */ err = 0; if (! err) { if (parser->state.next == parser->state.argc) /* We successfully parsed all arguments! Call all the parsers again, just a few more times... */ { for (group = parser->groups; group < parser->egroup && (!err || err==EBADKEY); group++) if (group->args_processed == 0) err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); for (group = parser->egroup - 1; group >= parser->groups && (!err || err==EBADKEY); group--) err = group_parse (group, &parser->state, ARGP_KEY_END, 0); if (err == EBADKEY) err = 0; /* Some parser didn't understand. */ /* Tell the user that all arguments are parsed. */ if (end_index) *end_index = parser->state.next; } else if (end_index) /* Return any remaining arguments to the user. */ *end_index = parser->state.next; else /* No way to return the remaining arguments, they must be bogus. */ { if (!(parser->state.flags & ARGP_NO_ERRS) && parser->state.err_stream) fprintf (parser->state.err_stream, dgettext (parser->argp->argp_domain, "%s: Too many arguments\n"), parser->state.name); err = EBADKEY; } } /* Okay, we're all done, with either an error or success; call the parsers to indicate which one. */ if (err) { /* Maybe print an error message. */ if (err == EBADKEY) /* An appropriate message describing what the error was should have been printed earlier. */ __argp_state_help (&parser->state, parser->state.err_stream, ARGP_HELP_STD_ERR); /* Since we didn't exit, give each parser an error indication. */ for (group = parser->groups; group < parser->egroup; group++) group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); } else /* Notify parsers of success, and propagate back values from parsers. */ { /* We pass over the groups in reverse order so that child groups are given a chance to do there processing before passing back a value to the parent. */ for (group = parser->egroup - 1 ; group >= parser->groups && (!err || err == EBADKEY) ; group--) err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); if (err == EBADKEY) err = 0; /* Some parser didn't understand. */ } /* Call parsers once more, to do any final cleanup. Errors are ignored. */ for (group = parser->egroup - 1; group >= parser->groups; group--) group_parse (group, &parser->state, ARGP_KEY_FINI, 0); if (err == EBADKEY) err = EINVAL; free (parser->storage); return err; } /* Call the user parsers to parse the non-option argument VAL, at the current position, returning any error. The state NEXT pointer should point to the argument; this function will adjust it correctly to reflect however many args actually end up being consumed. */ static error_t parser_parse_arg (struct parser *parser, char *val) { /* Save the starting value of NEXT */ int index = parser->state.next; error_t err = EBADKEY; struct group *group; int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ /* Try to parse the argument in each parser. */ for (group = parser->groups ; group < parser->egroup && err == EBADKEY ; group++) { parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ key = ARGP_KEY_ARG; err = group_parse (group, &parser->state, key, val); if (err == EBADKEY) /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ { parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ key = ARGP_KEY_ARGS; err = group_parse (group, &parser->state, key, 0); } } if (! err) { if (key == ARGP_KEY_ARGS) /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't changed by the user, *all* arguments should be considered consumed. */ parser->state.next = parser->state.argc; if (parser->state.next > index) /* Remember that we successfully processed a non-option argument -- but only if the user hasn't gotten tricky and set the clock back. */ (--group)->args_processed += (parser->state.next - index); else /* The user wants to reparse some args, so try looking for options again. */ parser->args_only = 0; } return err; } /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,next), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (struct parser *parser) { int bottom = parser->first_nonopt; int middle = parser->last_nonopt; int top = parser->state.next; char **argv = parser->state.argv; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ parser->first_nonopt += (parser->state.next - parser->last_nonopt); parser->last_nonopt = parser->state.next; } enum arg_type { ARG_ARG, ARG_SHORT_OPTION, ARG_LONG_OPTION, ARG_LONG_ONLY_OPTION, ARG_QUOTE }; static enum arg_type classify_arg(struct parser *parser, char *arg, char **opt) { if (arg[0] == '-') /* Looks like an option... */ switch (arg[1]) { case '\0': /* "-" is not an option. */ return ARG_ARG; case '-': /* Long option, or quote. */ if (!arg[2]) return ARG_QUOTE; /* A long option. */ if (opt) *opt = arg + 2; return ARG_LONG_OPTION; default: /* Short option. But if ARGP_LONG_ONLY, it can also be a long option. */ if (opt) *opt = arg + 1; if (parser->state.flags & ARGP_LONG_ONLY) { /* Rules from getopt.c: If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ assert(parser->short_opts); if (arg[2] || !strchr(parser->short_opts, arg[1])) return ARG_LONG_ONLY_OPTION; } return ARG_SHORT_OPTION; } else return ARG_ARG; } /* Parse the next argument in PARSER (as indicated by PARSER->state.next). Any error from the parsers is returned, and *ARGP_EBADKEY indicates whether a value of EBADKEY is due to an unrecognized argument (which is generally not fatal). */ static error_t parser_parse_next (struct parser *parser, int *arg_ebadkey) { if (parser->state.quoted && parser->state.next < parser->state.quoted) /* The next argument pointer has been moved to before the quoted region, so pretend we never saw the quoting `--', and start looking for options again. If the `--' is still there we'll just process it one more time. */ parser->state.quoted = parser->args_only = 0; /* Give FIRST_NONOPT & LAST_NONOPT rational values if NEXT has been moved back by the user (who may also have changed the arguments). */ if (parser->last_nonopt > parser->state.next) parser->last_nonopt = parser->state.next; if (parser->first_nonopt > parser->state.next) parser->first_nonopt = parser->state.next; if (parser->nextchar) /* Deal with short options. */ { struct group *group; char c; const struct argp_option *option; char *value = NULL;; assert(!parser->args_only); c = *parser->nextchar++; option = find_short_option(parser, c, &group); if (!option) { if (parser->posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: illegal option -- %c\n"), parser->state.name, c); else fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: invalid option -- %c\n"), parser->state.name, c); *arg_ebadkey = 0; return EBADKEY; } if (!*parser->nextchar) parser->nextchar = NULL; if (option->arg) { value = parser->nextchar; parser->nextchar = NULL; if (!value && !(option->flags & OPTION_ARG_OPTIONAL)) /* We need an mandatory argument. */ { if (parser->state.next == parser->state.argc) /* Missing argument */ { /* 1003.2 specifies the format of this message. */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: option requires an argument -- %c\n"), parser->state.name, c); *arg_ebadkey = 0; return EBADKEY; } value = parser->state.argv[parser->state.next++]; } } return group_parse(group, &parser->state, option->key, value); } else /* Advance to the next ARGV-element. */ { if (parser->args_only) { *arg_ebadkey = 1; if (parser->state.next >= parser->state.argc) /* We're done. */ return EBADKEY; else return parser_parse_arg(parser, parser->state.argv[parser->state.next]); } if (parser->state.next >= parser->state.argc) /* Almost done. If there are non-options that we skipped previously, we should process them now. */ { *arg_ebadkey = 1; if (parser->first_nonopt != parser->last_nonopt) { exchange(parser); /* Start processing the arguments we skipped previously. */ parser->state.next = parser->first_nonopt; parser->first_nonopt = parser->last_nonopt = 0; parser->args_only = 1; return 0; } else /* Indicate that we're really done. */ return EBADKEY; } else /* Look for options. */ { char *arg = parser->state.argv[parser->state.next]; char *optstart; enum arg_type token = classify_arg(parser, arg, &optstart); switch (token) { case ARG_ARG: switch (parser->ordering) { case PERMUTE: if (parser->first_nonopt == parser->last_nonopt) /* Skipped sequence is empty; start a new one. */ parser->first_nonopt = parser->last_nonopt = parser->state.next; else if (parser->last_nonopt != parser->state.next) /* We have a non-empty skipped sequence, and we're not at the end-point, so move it. */ exchange(parser); assert(parser->last_nonopt == parser->state.next); /* Skip this argument for now. */ parser->state.next++; parser->last_nonopt = parser->state.next; return 0; case REQUIRE_ORDER: /* Implicit quote before the first argument. */ parser->args_only = 1; return 0; case RETURN_IN_ORDER: *arg_ebadkey = 1; return parser_parse_arg(parser, arg); default: abort(); } case ARG_QUOTE: /* Skip it, then exchange with any previous non-options. */ parser->state.next++; assert (parser->last_nonopt != parser->state.next); if (parser->first_nonopt != parser->last_nonopt) { exchange(parser); /* Start processing the skipped and the quoted arguments. */ parser->state.quoted = parser->state.next = parser->first_nonopt; /* Also empty the skipped-list, to avoid confusion if the user resets the next pointer. */ parser->first_nonopt = parser->last_nonopt = 0; } else parser->state.quoted = parser->state.next; parser->args_only = 1; return 0; case ARG_LONG_ONLY_OPTION: case ARG_LONG_OPTION: { struct group *group; const struct argp_option *option; char *value; parser->state.next++; option = find_long_option(parser, optstart, &group); if (!option) { /* NOTE: This includes any "=something" in the output. */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: unrecognized option `%s'\n"), parser->state.name, arg); *arg_ebadkey = 0; return EBADKEY; } value = strchr(optstart, '='); if (value) value++; if (value && !option->arg) /* Unexpected argument. */ { if (token == ARG_LONG_OPTION) /* --option */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: option `--%s' doesn't allow an argument\n"), parser->state.name, option->name); else /* +option or -option */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: option `%c%s' doesn't allow an argument\n"), parser->state.name, arg[0], option->name); *arg_ebadkey = 0; return EBADKEY; } if (option->arg && !value && !(option->flags & OPTION_ARG_OPTIONAL)) /* We need an mandatory argument. */ { if (parser->state.next == parser->state.argc) /* Missing argument */ { if (token == ARG_LONG_OPTION) /* --option */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: option `--%s' requires an argument\n"), parser->state.name, option->name); else /* +option or -option */ fprintf (parser->state.err_stream, dgettext(parser->state.root_argp->argp_domain, "%s: option `%c%s' requires an argument\n"), parser->state.name, arg[0], option->name); *arg_ebadkey = 0; return EBADKEY; } value = parser->state.argv[parser->state.next++]; } *arg_ebadkey = 0; return group_parse(group, &parser->state, option->key, value); } case ARG_SHORT_OPTION: parser->state.next++; parser->nextchar = optstart; return 0; default: abort(); } } } } /* Parse the options strings in ARGC & ARGV according to the argp in ARGP. FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the index in ARGV of the first unparsed option is returned in it. If an unknown option is present, EINVAL is returned; if some parser routine returned a non-zero value, it is returned; otherwise 0 is returned. */ error_t __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, int *end_index, void *input) { error_t err; struct parser parser; /* If true, then err == EBADKEY is a result of a non-option argument failing to be parsed (which in some cases isn't actually an error). */ int arg_ebadkey = 0; if (! (flags & ARGP_NO_HELP)) /* Add our own options. */ { struct argp_child *child = alloca (4 * sizeof (struct argp_child)); struct argp *top_argp = alloca (sizeof (struct argp)); /* TOP_ARGP has no options, it just serves to group the user & default argps. */ memset (top_argp, 0, sizeof (*top_argp)); top_argp->children = child; memset (child, 0, 4 * sizeof (struct argp_child)); if (argp) (child++)->argp = argp; (child++)->argp = &argp_default_argp; if (argp_program_version || argp_program_version_hook) (child++)->argp = &argp_version_argp; child->argp = 0; argp = top_argp; } /* Construct a parser for these arguments. */ err = parser_init (&parser, argp, argc, argv, flags, input); if (! err) /* Parse! */ { while (! err) err = parser_parse_next (&parser, &arg_ebadkey); err = parser_finalize (&parser, err, arg_ebadkey, end_index); } return err; } #ifdef weak_alias weak_alias (__argp_parse, argp_parse) #endif /* Return the input field for ARGP in the parser corresponding to STATE; used by the help routines. */ void * __argp_input (const struct argp *argp, const struct argp_state *state) { if (state) { struct group *group; struct parser *parser = state->pstate; for (group = parser->groups; group < parser->egroup; group++) if (group->argp == argp) return group->input; } return 0; } #ifdef weak_alias weak_alias (__argp_input, _argp_input) #endif /* Defined here, in case a user is not inlining the definitions in * argp.h */ void __argp_usage (__const struct argp_state *__state) { __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); } int __option_is_short (__const struct argp_option *__opt) { if (__opt->flags & OPTION_DOC) return 0; else { int __key = __opt->key; /* FIXME: whether or not a particular key implies a short option * ought not to be locale dependent. */ return __key > 0 && isprint (__key); } } int __option_is_end (__const struct argp_option *__opt) { return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; } wvstreams-4.6.1/argp/Makefile.in0000644000175000001440000005525411202637334015604 0ustar wlachusers# Makefile.in generated by automake 1.8.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ # From glibc # Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # The GNU C Library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public # License along with the GNU C Library; see the file COPYING.LIB. If # not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. SOURCES = $(libargp_a_SOURCES) argp-test.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : noinst_PROGRAMS = argp-test$(EXEEXT) subdir = . DIST_COMMON = $(am__configure_deps) $(noinst_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(top_srcdir)/configure ChangeLog TODO \ depcomp install-sh mempcpy.c missing mkinstalldirs strchrnul.c \ strndup.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = AR = @AR@ ARFLAGS = cru LIBRARIES = $(noinst_LIBRARIES) libargp_a_AR = $(AR) $(ARFLAGS) am__DEPENDENCIES_1 = @LIBOBJS@ libargp_a_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libargp_a_OBJECTS = argp-ba.$(OBJEXT) argp-eexst.$(OBJEXT) \ argp-fmtstream.$(OBJEXT) argp-help.$(OBJEXT) \ argp-parse.$(OBJEXT) argp-pv.$(OBJEXT) argp-pvh.$(OBJEXT) libargp_a_OBJECTS = $(am_libargp_a_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) argp_test_SOURCES = argp-test.c argp_test_OBJECTS = argp-test.$(OBJEXT) argp_test_DEPENDENCIES = libargp.a DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = $(DEPDIR)/mempcpy.Po $(DEPDIR)/strchrnul.Po \ @AMDEP_TRUE@ $(DEPDIR)/strndup.Po ./$(DEPDIR)/argp-ba.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/argp-eexst.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/argp-fmtstream.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/argp-help.Po ./$(DEPDIR)/argp-parse.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/argp-pv.Po ./$(DEPDIR)/argp-pvh.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/argp-test.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libargp_a_SOURCES) argp-test.c DIST_SOURCES = $(libargp_a_SOURCES) argp-test.c RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign SUBDIRS = . testsuite noinst_LIBRARIES = libargp.a noinst_HEADERS = argp.h argp-fmtstream.h argp-namefrob.h # argp-comp.h EXTRA_DIST = mempcpy.c strchrnul.c strndup.c Versions # Leaves out argp-fs-xinl.c and argp-xinl.c libargp_a_SOURCES = argp-ba.c argp-eexst.c argp-fmtstream.c \ argp-help.c argp-parse.c argp-pv.c \ argp-pvh.c libargp_a_LIBADD = $(LIBOBJS) argp_test_LDADD = libargp.a all: config.h libargp.list $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libargp.a: $(libargp_a_OBJECTS) $(libargp_a_DEPENDENCIES) -rm -f libargp.a $(libargp_a_AR) libargp.a $(libargp_a_OBJECTS) $(libargp_a_LIBADD) $(RANLIB) libargp.a libargp.list: libargp.a $(AR) t $^ > libargp.list clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) argp-test$(EXEEXT): $(argp_test_OBJECTS) $(argp_test_DEPENDENCIES) @rm -f argp-test$(EXEEXT) $(LINK) $(argp_test_LDFLAGS) $(argp_test_OBJECTS) $(argp_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mempcpy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strchrnul.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strndup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-ba.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-eexst.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-fmtstream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-help.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pvh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-test.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || mkdir "$(distdir)/$$subdir" \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="../$(top_distdir)" \ distdir="../$(distdir)/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && $(mkdir_p) "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-noinstLIBRARIES \ clean-noinstPROGRAMS clean-recursive ctags ctags-recursive \ dist dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ \ dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-recursive \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-exec install-exec-am \ install-info install-info-am install-man install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: wvstreams-4.6.1/argp/testsuite/0000755000175000001440000000000011077124114015552 5ustar wlachuserswvstreams-4.6.1/argp/testsuite/ex1-test0000755000175000001440000000045711077124114017160 0ustar wlachusers#! /bin/sh # Success with no args ./ex1 || exit 1 # Fail with args if ./ex1 foo 2>/dev/null ; then exit 1 ; fi # Respond to --help ./ex1 --help >/dev/null || exit 1 # Not using ARGP_LONG_ONLY if ./ex1 -help 2>/dev/null ; then exit 1 ; fi (./ex1 --help | grep Usage: >/dev/null ) || exit 1 exit 0 wvstreams-4.6.1/argp/testsuite/Makefile.am0000644000175000001440000000044711077124114017613 0ustar wlachusersTS_SH = ex1-test permute-test TS_PROGS = TS_ALL = $(TS_PROGS) $(TS_SH) noinst_PROGRAMS = $(TS_PROGS) ex1 ex3 ex4 LDADD = ../libargp.a EXTRA_DIST = $(TS_SH) run-tests CLEANFILES = test.out .PHONY: check check: $(TS_ALL) $(srcdir)/run-tests srcdir="$(srcdir)" $(srcdir)/run-tests $(TS_ALL) wvstreams-4.6.1/argp/testsuite/ex1.c0000644000175000001440000000062111077124114016412 0ustar wlachusers/* Argp example #1 - a minimal program using argp */ /* This is (probably) the smallest possible program that uses argp. It won't do much except give an error messages and exit when there are any arguments, and print a (rather pointless) messages for -help. */ #include #include int main (int argc, char **argv) { argp_parse (0, argc, argv, 0, 0, 0); exit (0); } wvstreams-4.6.1/argp/testsuite/run-tests0000755000175000001440000000176211077124114017452 0ustar wlachusers#! /bin/sh failed=0 all=0 if [ -z "$srcdir" ] ; then srcdir=`pwd` fi export srcdir find_program () { if [ -x "$1" ] ; then echo "./$1" else echo "$srcdir/$1" fi } env_program () { if [ -x "$1" ] ; then if "$1"; then : ; else echo FAIL: $1 exit 1 fi fi } test_program () { testname=`basename "$1" -test` "$1" case "$?" in 0) echo PASS: $testname all=`expr $all + 1` ;; 77) echo SKIP: $testname ;; *) echo FAIL: $testname failed=`expr $failed + 1` all=`expr $all + 1` ;; esac } env_program `find_program setup-env` if [ $# -eq 0 ] ; then for f in *-test; do test_program "./$f"; done else for f in "$@" ; do test_program `find_program "$f"`; done fi if [ $failed -eq 0 ] ; then banner="All $all tests passed" else banner="$failed of $all tests failed" fi dashes=`echo "$banner" | sed s/./=/g` echo "$dashes" echo "$banner" echo "$dashes" env_program `find_program teardown-env` [ "$failed" -eq 0 ] wvstreams-4.6.1/argp/testsuite/ex4.c0000644000175000001440000001272011077124114016420 0ustar wlachusers/* Argp example #4 - a program with somewhat more complicated options */ /* This program uses the same features as example 3, but has more options, and somewhat more structure in the -help output. It also shows how you can `steal' the remainder of the input arguments past a certain point, for programs that accept a list of items. It also shows the special argp KEY value ARGP_KEY_NO_ARGS, which is only given if no non-option arguments were supplied to the program. For structuring the help output, two features are used, *headers* which are entries in the options vector with the first four fields being zero, and a two part documentation string (in the variable DOC), which allows documentation both before and after the options; the two parts of DOC are separated by a vertical-tab character ('\v', or '\013'). By convention, the documentation before the options is just a short string saying what the program does, and that afterwards is longer, describing the behavior in more detail. All documentation strings are automatically filled for output, although newlines may be included to force a line break at a particular point. All documentation strings are also passed to the `gettext' function, for possible translation into the current locale. */ #include #include #include const char *argp_program_version = "argp-ex4 1.0"; const char *argp_program_bug_address = ""; /* Program documentation. */ static char doc[] = "Argp example #4 -- a program with somewhat more complicated\ options\ \vThis part of the documentation comes *after* the options;\ note that the text is automatically filled, but it's possible\ to force a line-break, e.g.\n<-- here."; /* A description of the arguments we accept. */ static char args_doc[] = "ARG1 [STRING...]"; /* Keys for options without short-options. */ #define OPT_ABORT 1 /* -abort */ /* The options we understand. */ static struct argp_option options[] = { {"verbose", 'v', 0, 0, "Produce verbose output", 0}, {"quiet", 'q', 0, 0, "Don't produce any output", 0}, {"silent", 's', 0, OPTION_ALIAS, 0, 0}, {"output", 'o', "FILE", 0, "Output to FILE instead of standard output", 0}, {0,0,0,0, "The following options should be grouped together:", 0}, {"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL, "Repeat the output COUNT (default 10) times", 0}, {"abort", OPT_ABORT, 0, 0, "Abort before showing any output", 0}, {0, 0, 0, 0, 0, 0} }; /* Used by `main' to communicate with `parse_opt'. */ struct arguments { char *arg1; /* ARG1 */ char **strings; /* [STRING...] */ int silent, verbose, abort; /* `-s', `-v', `--abort' */ char *output_file; /* FILE arg to `--output' */ int repeat_count; /* COUNT arg to `--repeat' */ }; /* Parse a single option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { /* Get the `input' argument from `argp_parse', which we know is a pointer to our arguments structure. */ struct arguments *arguments = state->input; switch (key) { case 'q': case 's': arguments->silent = 1; break; case 'v': arguments->verbose = 1; break; case 'o': arguments->output_file = arg; break; case 'r': arguments->repeat_count = arg ? atoi (arg) : 10; break; case OPT_ABORT: arguments->abort = 1; break; case ARGP_KEY_NO_ARGS: argp_usage (state); case ARGP_KEY_ARG: /* Here we know that `state->arg_num == 0', since we force argument parsing to end before any more arguments can get here. */ arguments->arg1 = arg; /* Now we consume all the rest of the arguments. `state->next' is the index in `state->argv' of the next argument to be parsed, which is the first STRING we're interested in, so we can just use `&state->argv[state->next]' as the value for arguments->strings. _In addition_, by setting `state->next' to the end of the arguments, we can force argp to stop parsing here and return. */ arguments->strings = &state->argv[state->next]; state->next = state->argc; break; default: return ARGP_ERR_UNKNOWN; } return 0; } /* Our argp parser. */ static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0}; int main (int argc, char **argv) { int i, j; struct arguments arguments; /* Default values. */ arguments.silent = 0; arguments.verbose = 0; arguments.output_file = "-"; arguments.repeat_count = 1; arguments.abort = 0; /* Parse our arguments; every option seen by `parse_opt' will be reflected in `arguments'. */ argp_parse (&argp, argc, argv, 0, 0, &arguments); if (arguments.abort) { /* The glibc example used error (10, 0, "ABORTED"), but that's not portable. */ fprintf(stderr, "ex4: ABORTED\n"); exit(10); } for (i = 0; i < arguments.repeat_count; i++) { printf ("ARG1 = %s\n", arguments.arg1); printf ("STRINGS = "); for (j = 0; arguments.strings[j]; j++) printf (j == 0 ? "%s" : ", %s", arguments.strings[j]); printf ("\n"); printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n", arguments.output_file, arguments.verbose ? "yes" : "no", arguments.silent ? "yes" : "no"); } exit (0); } wvstreams-4.6.1/argp/testsuite/Makefile.in0000644000175000001440000003006211077124114017620 0ustar wlachusers# Makefile.in generated by automake 1.8.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in 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. @SET_MAKE@ SOURCES = ex1.c ex3.c ex4.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : noinst_PROGRAMS = $(am__EXEEXT_1) ex1$(EXEEXT) ex3$(EXEEXT) \ ex4$(EXEEXT) subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = am__EXEEXT_1 = PROGRAMS = $(noinst_PROGRAMS) ex1_SOURCES = ex1.c ex1_OBJECTS = ex1.$(OBJEXT) ex1_LDADD = $(LDADD) ex1_DEPENDENCIES = ../libargp.a ex3_SOURCES = ex3.c ex3_OBJECTS = ex3.$(OBJEXT) ex3_LDADD = $(LDADD) ex3_DEPENDENCIES = ../libargp.a ex4_SOURCES = ex4.c ex4_OBJECTS = ex4.$(OBJEXT) ex4_LDADD = $(LDADD) ex4_DEPENDENCIES = ../libargp.a DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ex1.Po ./$(DEPDIR)/ex3.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/ex4.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = ex1.c ex3.c ex4.c DIST_SOURCES = ex1.c ex3.c ex4.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ TS_SH = ex1-test permute-test TS_PROGS = TS_ALL = $(TS_PROGS) $(TS_SH) LDADD = ../libargp.a EXTRA_DIST = $(TS_SH) run-tests CLEANFILES = test.out all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu testsuite/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu testsuite/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) ex1$(EXEEXT): $(ex1_OBJECTS) $(ex1_DEPENDENCIES) @rm -f ex1$(EXEEXT) $(LINK) $(ex1_LDFLAGS) $(ex1_OBJECTS) $(ex1_LDADD) $(LIBS) ex3$(EXEEXT): $(ex3_OBJECTS) $(ex3_DEPENDENCIES) @rm -f ex3$(EXEEXT) $(LINK) $(ex3_LDFLAGS) $(ex3_OBJECTS) $(ex3_LDADD) $(LIBS) ex4$(EXEEXT): $(ex4_OBJECTS) $(ex4_DEPENDENCIES) @rm -f ex4$(EXEEXT) $(LINK) $(ex4_LDFLAGS) $(ex4_OBJECTS) $(ex4_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ex1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ex3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ex4.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstPROGRAMS ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am .PHONY: check check: $(TS_ALL) $(srcdir)/run-tests srcdir="$(srcdir)" $(srcdir)/run-tests $(TS_ALL) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: wvstreams-4.6.1/argp/testsuite/permute-test0000755000175000001440000000067111077124114020142 0ustar wlachusers#! /bin/sh # Test the somewhat hairy permuting of arguments. cat >test.out <&2 exit 1 } for args in "-v foo bar" \ "-v -v foo bar" "-v foo -v bar" "-v foo bar -v" \ "foo -v bar -v" "foo bar -v -v" "foo -v -v bar" ; do ./ex3 $args | diff - test.out >/dev/null || die "Test failed with args $args" done exit 0 wvstreams-4.6.1/argp/testsuite/ex3.c0000644000175000001440000001254411077124114016423 0ustar wlachusers/* Argp example #3 - a program with options and arguments using argp */ /* This program uses the same features as example 2, and uses options and arguments. We now use the first four fields in ARGP, so here's a description of them: OPTIONS - A pointer to a vector of struct argp_option (see below) PARSER - A function to parse a single option, called by argp ARGS_DOC - A string describing how the non-option arguments should look DOC - A descriptive string about this program; if it contains a vertical tab character (\v), the part after it will be printed *following* the options The function PARSER takes the following arguments: KEY - An integer specifying which option this is (taken from the KEY field in each struct argp_option), or a special key specifying something else; the only special keys we use here are ARGP_KEY_ARG, meaning a non-option argument, and ARGP_KEY_END, meaning that all arguments have been parsed ARG - For an option KEY, the string value of its argument, or NULL if it has none STATE- A pointer to a struct argp_state, containing various useful information about the parsing state; used here are the INPUT field, which reflects the INPUT argument to argp_parse, and the ARG_NUM field, which is the number of the current non-option argument being parsed It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the given KEY wasn't recognized, or an errno value indicating some other error. Note that in this example, main uses a structure to communicate with the parse_opt function, a pointer to which it passes in the INPUT argument to argp_parse. Of course, it's also possible to use global variables instead, but this is somewhat more flexible. The OPTIONS field contains a pointer to a vector of struct argp_option's; that structure has the following fields (if you assign your option structures using array initialization like this example, unspecified fields will be defaulted to 0, and need not be specified): NAME - The name of this option's long option (may be zero) KEY - The KEY to pass to the PARSER function when parsing this option, *and* the name of this option's short option, if it is a printable ascii character ARG - The name of this option's argument, if any FLAGS - Flags describing this option; some of them are: OPTION_ARG_OPTIONAL - The argument to this option is optional OPTION_ALIAS - This option is an alias for the previous option OPTION_HIDDEN - Don't show this option in -help output DOC - A documentation string for this option, shown in -help output An options vector should be terminated by an option with all fields zero. */ #include #include const char *argp_program_version = "argp-ex3 1.0"; const char *argp_program_bug_address = ""; /* Program documentation. */ static char doc[] = "Argp example #3 -- a program with options and arguments using argp"; /* A description of the arguments we accept. */ static char args_doc[] = "ARG1 ARG2"; /* The options we understand. */ static struct argp_option options[] = { {"verbose", 'v', 0, 0, "Produce verbose output", 0}, {"quiet", 'q', 0, 0, "Don't produce any output", 0}, {"silent", 's', 0, OPTION_ALIAS, 0, 0}, {"output", 'o', "FILE", 0, "Output to FILE instead of standard output", 0}, {0, 0, 0, 0, 0, 0} }; /* Used by `main' to communicate with `parse_opt'. */ struct arguments { char *args[2]; /* ARG1 & ARG2 */ int silent, verbose; char *output_file; }; /* Parse a single option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { /* Get the INPUT argument from `argp_parse', which we know is a pointer to our arguments structure. */ struct arguments *arguments = state->input; switch (key) { case 'q': case 's': arguments->silent = 1; break; case 'v': arguments->verbose = 1; break; case 'o': arguments->output_file = arg; break; case ARGP_KEY_ARG: if (state->arg_num >= 2) /* Too many arguments. */ argp_usage (state); arguments->args[state->arg_num] = arg; break; case ARGP_KEY_END: if (state->arg_num < 2) /* Not enough arguments. */ argp_usage (state); break; default: return ARGP_ERR_UNKNOWN; } return 0; } /* Our argp parser. */ static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 }; int main (int argc, char **argv) { struct arguments arguments; /* Default values. */ arguments.silent = 0; arguments.verbose = 0; arguments.output_file = "-"; /* Parse our arguments; every option seen by `parse_opt' will be reflected in `arguments'. */ argp_parse (&argp, argc, argv, 0, 0, &arguments); printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n" "VERBOSE = %s\nSILENT = %s\n", arguments.args[0], arguments.args[1], arguments.output_file, arguments.verbose ? "yes" : "no", arguments.silent ? "yes" : "no"); exit (0); } wvstreams-4.6.1/argp/install-sh0000755000175000001440000002143211077124114015527 0ustar wlachusers#!/bin/sh # install - install a program, script, or datafile scriptversion=2004-01-12.10 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename= transform_arg= instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= usage="Usage: $0 [OPTION]... SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 -d DIRECTORIES... In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. In the second, create the directory path DIR. Options: -b=TRANSFORMBASENAME -c copy source (using $cpprog) instead of moving (using $mvprog). -d create directories instead of installing files. -g GROUP $chgrp installed files to GROUP. -m MODE $chmod installed files to MODE. -o USER $chown installed files to USER. -s strip installed files (using $stripprog). -t=TRANSFORM --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) # When -d is used, all remaining arguments are directories to create. test -n "$dir_arg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then instcmd=: chmodcmd= else instcmd=$mkdirprog 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 test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -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 test $# -ne 0 ; do pathcomp=$pathcomp$1 shift test -d "$pathcomp" || $mkdirprog "$pathcomp" pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $instcmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else # If we're going to rename the final executable, determine the name now. if test -z "$transformarg"; then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename \ | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename. test -z "$dstfile" && dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # 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. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now remove or move aside any old file at destination location. We # try this two ways since rm can't unlink itself on some systems and # the destination file might be busy for other reasons. In this case, # the final cleanup might fail but the new file should still install # successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi || { (exit 1); exit; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # 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: wvstreams-4.6.1/argp/acinclude.m40000644000175000001440000006705211077124114015724 0ustar wlachusersdnl Try to detect the type of the third arg to getsockname() et al AC_DEFUN([LSH_TYPE_SOCKLEN_T], [AH_TEMPLATE([socklen_t], [Length type used by getsockopt]) AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_type_socklen_t, [AC_EGREP_HEADER(socklen_t, sys/socket.h, [ac_cv_type_socklen_t=yes], [ac_cv_type_socklen_t=no])]) if test $ac_cv_type_socklen_t = no; then AC_MSG_CHECKING(for AIX) AC_EGREP_CPP(yes, [ #ifdef _AIX yes #endif ],[ AC_MSG_RESULT(yes) AC_DEFINE(socklen_t, size_t) ],[ AC_MSG_RESULT(no) AC_DEFINE(socklen_t, int) ]) fi ]) dnl LSH_PATH_ADD(path-id, directory) AC_DEFUN([LSH_PATH_ADD], [AC_MSG_CHECKING($2) ac_exists=no if test -d "$2/." ; then ac_real_dir=`cd $2 && pwd` if test -n "$ac_real_dir" ; then ac_exists=yes for old in $1_REAL_DIRS ; do ac_found=no if test x$ac_real_dir = x$old ; then ac_found=yes; break; fi done if test $ac_found = yes ; then AC_MSG_RESULT(already added) else AC_MSG_RESULT(added) # LDFLAGS="$LDFLAGS -L $2" $1_REAL_DIRS="$ac_real_dir [$]$1_REAL_DIRS" $1_DIRS="$2 [$]$1_DIRS" fi fi fi if test $ac_exists = no ; then AC_MSG_RESULT(not found) fi ]) dnl LSH_RPATH_ADD(dir) AC_DEFUN([LSH_RPATH_ADD], [LSH_PATH_ADD(RPATH_CANDIDATE, $1)]) dnl LSH_RPATH_INIT(candidates) AC_DEFUN([LSH_RPATH_INIT], [AC_MSG_CHECKING([for -R flag]) RPATHFLAG='' case `uname -sr` in OSF1\ V4.*) RPATHFLAG="-rpath " ;; IRIX\ 6.*) RPATHFLAG="-rpath " ;; IRIX\ 5.*) RPATHFLAG="-rpath " ;; SunOS\ 5.*) if test "$TCC" = "yes"; then # tcc doesn't know about -R RPATHFLAG="-Wl,-R," else RPATHFLAG=-R fi ;; Linux\ 2.*) RPATHFLAG="-Wl,-rpath," ;; *) : ;; esac if test x$RPATHFLAG = x ; then AC_MSG_RESULT(none) else AC_MSG_RESULT([using $RPATHFLAG]) fi RPATH_CANDIDATE_REAL_DIRS='' RPATH_CANDIDATE_DIRS='' AC_MSG_RESULT([Searching for libraries]) for d in $1 ; do LSH_RPATH_ADD($d) done ]) dnl Try to execute a main program, and if it fails, try adding some dnl -R flag. dnl LSH_RPATH_FIX AC_DEFUN([LSH_RPATH_FIX], [if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then ac_success=no AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], ac_success=yes, ac_success=no, :) if test $ac_success = no ; then AC_MSG_CHECKING([Running simple test program failed. Trying -R flags]) dnl echo RPATH_CANDIDATE_DIRS = $RPATH_CANDIDATE_DIRS ac_remaining_dirs='' ac_rpath_save_LDFLAGS="$LDFLAGS" for d in $RPATH_CANDIDATE_DIRS ; do if test $ac_success = yes ; then ac_remaining_dirs="$ac_remaining_dirs $d" else LDFLAGS="$RPATHFLAG$d $LDFLAGS" dnl echo LDFLAGS = $LDFLAGS AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], [ac_success=yes ac_rpath_save_LDFLAGS="$LDFLAGS" AC_MSG_RESULT([adding $RPATHFLAG$d]) ], [ac_remaining_dirs="$ac_remaining_dirs $d"], :) LDFLAGS="$ac_rpath_save_LDFLAGS" fi done RPATH_CANDIDATE_DIRS=$ac_remaining_dirs fi if test $ac_success = no ; then AC_MSG_RESULT(failed) fi fi ]) dnl Like AC_CHECK_LIB, but uses $KRB_LIBS rather than $LIBS. dnl LSH_CHECK_KRB_LIB(LIBRARY, FUNCTION, [, ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) AC_DEFUN([LSH_CHECK_KRB_LIB], [AC_CHECK_LIB([$1], [$2], ifelse([$3], , [[ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` AC_DEFINE_UNQUOTED($ac_tr_lib) KRB_LIBS="-l$1 $KRB_LIBS" ]], [$3]), ifelse([$4], , , [$4 ])dnl , [$5 $KRB_LIBS]) ]) dnl LSH_LIB_ARGP(ACTION-IF-OK, ACTION-IF-BAD) AC_DEFUN([LSH_LIB_ARGP], [ ac_argp_save_LIBS="$LIBS" ac_argp_save_LDFLAGS="$LDFLAGS" ac_argp_ok=no # First check if we can link with argp. AC_SEARCH_LIBS(argp_parse, argp, [ LSH_RPATH_FIX AC_CACHE_CHECK([for working argp], lsh_cv_lib_argp_works, [ AC_TRY_RUN( [#include #include static const struct argp_option options[] = { { NULL, 0, NULL, 0, NULL, 0 } }; struct child_state { int n; }; static error_t child_parser(int key, char *arg, struct argp_state *state) { struct child_state *input = (struct child_state *) state->input; switch(key) { default: return ARGP_ERR_UNKNOWN; case ARGP_KEY_END: if (!input->n) input->n = 1; break; } return 0; } const struct argp child_argp = { options, child_parser, NULL, NULL, NULL, NULL, NULL }; struct main_state { struct child_state child; int m; }; static error_t main_parser(int key, char *arg, struct argp_state *state) { struct main_state *input = (struct main_state *) state->input; switch(key) { default: return ARGP_ERR_UNKNOWN; case ARGP_KEY_INIT: state->child_inputs[0] = &input->child; break; case ARGP_KEY_END: if (!input->m) input->m = input->child.n; break; } return 0; } static const struct argp_child main_children[] = { { &child_argp, 0, "", 0 }, { NULL, 0, NULL, 0} }; static const struct argp main_argp = { options, main_parser, NULL, NULL, main_children, NULL, NULL }; int main(int argc, char **argv) { struct main_state input = { { 0 }, 0 }; char *v[2] = { "foo", NULL }; argp_parse(&main_argp, 1, v, 0, NULL, &input); if ( (input.m == 1) && (input.child.n == 1) ) return 0; else return 1; } ], lsh_cv_lib_argp_works=yes, lsh_cv_lib_argp_works=no, lsh_cv_lib_argp_works=no)]) if test x$lsh_cv_lib_argp_works = xyes ; then ac_argp_ok=yes else # Reset link flags LIBS="$ac_argp_save_LIBS" LDFLAGS="$ac_argp_save_LDFLAGS" fi]) if test x$ac_argp_ok = xyes ; then ifelse([$1],, true, [$1]) else ifelse([$2],, true, [$2]) fi ]) dnl LSH_GCC_ATTRIBUTES dnl Check for gcc's __attribute__ construction AC_DEFUN([LSH_GCC_ATTRIBUTES], [AC_CACHE_CHECK(for __attribute__, lsh_cv_c_attribute, [ AC_TRY_COMPILE([ #include ], [ static void foo(void) __attribute__ ((noreturn)); static void __attribute__ ((noreturn)) foo(void) { exit(1); } ], lsh_cv_c_attribute=yes, lsh_cv_c_attribute=no)]) AH_TEMPLATE([HAVE_GCC_ATTRIBUTE], [Define if the compiler understands __attribute__]) if test "x$lsh_cv_c_attribute" = "xyes"; then AC_DEFINE(HAVE_GCC_ATTRIBUTE) fi AH_BOTTOM( [#if __GNUC__ && HAVE_GCC_ATTRIBUTE # define NORETURN __attribute__ ((__noreturn__)) # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) # define UNUSED __attribute__ ((__unused__)) #else # define NORETURN # define PRINTF_STYLE(f, a) # define UNUSED #endif ])]) AC_DEFUN([LSH_GCC_FUNCTION_NAME], [# Check for gcc's __FUNCTION__ variable AH_TEMPLATE([HAVE_GCC_FUNCTION], [Define if the compiler understands __FUNCTION__]) AH_BOTTOM( [#if HAVE_GCC_FUNCTION # define FUNCTION_NAME __FUNCTION__ #else # define FUNCTION_NAME "Unknown" #endif ]) AC_CACHE_CHECK(for __FUNCTION__, lsh_cv_c_FUNCTION, [ AC_TRY_COMPILE(, [ #if __GNUC__ == 3 # error __FUNCTION__ is broken in gcc-3 #endif void foo(void) { char c = __FUNCTION__[0]; } ], lsh_cv_c_FUNCTION=yes, lsh_cv_c_FUNCTION=no)]) if test "x$lsh_cv_c_FUNCTION" = "xyes"; then AC_DEFINE(HAVE_GCC_FUNCTION) fi ]) # Check for alloca, and include the standard blurb in config.h AC_DEFUN([LSH_FUNC_ALLOCA], [AC_FUNC_ALLOCA AH_BOTTOM( [/* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #else /* defined __GNUC__ */ # if HAVE_ALLOCA_H # include # endif #endif ])]) AC_DEFUN([LSH_FUNC_STRERROR], [AC_CHECK_FUNCS(strerror) AH_BOTTOM( [#if HAVE_STRERROR #define STRERROR strerror #else #define STRERROR(x) (sys_errlist[x]) #endif ])]) AC_DEFUN([LSH_FUNC_STRSIGNAL], [AC_CHECK_FUNCS(strsignal) AC_CHECK_DECLS([sys_siglist, _sys_siglist]) AH_BOTTOM( [#if HAVE_STRSIGNAL # define STRSIGNAL strsignal #else /* !HAVE_STRSIGNAL */ # if HAVE_DECL_SYS_SIGLIST # define STRSIGNAL(x) (sys_siglist[x]) # else # if HAVE_DECL__SYS_SIGLIST # define STRSIGNAL(x) (_sys_siglist[x]) # else # define STRSIGNAL(x) "Unknown signal" # if __GNUC__ # warning Using dummy STRSIGNAL # endif # endif # endif #endif /* !HAVE_STRSIGNAL */ ])]) dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])] dnl dnl the "ISO C9X: 7.18 Integer types " section requires the dnl existence of an include file that defines a set of dnl typedefs, especially uint8_t,int32_t,uintptr_t. dnl Many older installations will not provide this file, but some will dnl have the very same definitions in . In other enviroments dnl we can use the inet-types in which would define the dnl typedefs int8_t and u_int8_t respectivly. dnl dnl This macros will create a local "_stdint.h" or the headerfile given as dnl an argument. In many cases that file will just "#include " dnl or "#include ", while in other environments it will provide dnl the set of basic 'stdint's definitions/typedefs: dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t dnl int_least32_t.. int_fast32_t.. intmax_t dnl which may or may not rely on the definitions of other files, dnl or using the AC_CHECK_SIZEOF macro to determine the actual dnl sizeof each type. dnl dnl if your header files require the stdint-types you will want to create an dnl installable file mylib-int.h that all your other installable header dnl may include. So if you have a library package named "mylib", just use dnl AX_CREATE_STDINT_H(mylib-int.h) dnl in configure.ac and go to install that very header file in Makefile.am dnl along with the other headers (mylib.h) - and the mylib-specific headers dnl can simply use "#include " to obtain the stdint-types. dnl dnl Remember, if the system already had a valid , the generated dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things... dnl dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/) dnl @version $Id: acinclude.m4,v 1.18 2004/02/07 14:21:04 nisse Exp $ dnl @author Guido Draheim AC_DEFUN([AX_CREATE_STDINT_H], [# ------ AX CREATE STDINT H ------------------------------------- AC_MSG_CHECKING([for stdint types]) ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` # try to shortcircuit - if the default include path of the compiler # can find a "stdint.h" header then we assume that all compilers can. AC_CACHE_VAL([ac_cv_header_stdint_t],[ old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" old_CFLAGS="$CFLAGS" ; CFLAGS="" AC_TRY_COMPILE([#include ],[int_least32_t v = 0;], [ac_cv_stdint_result="(assuming C99 compatible system)" ac_cv_header_stdint_t="stdint.h"; ], [ac_cv_header_stdint_t=""]) CXXFLAGS="$old_CXXFLAGS" CPPFLAGS="$old_CPPFLAGS" CFLAGS="$old_CFLAGS" ]) v="... $ac_cv_header_stdint_h" if test "$ac_stdint_h" = "stdint.h" ; then AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) elif test "$ac_stdint_h" = "inttypes.h" ; then AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) elif test "_$ac_cv_header_stdint_t" = "_" ; then AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) else ac_cv_header_stdint="$ac_cv_header_stdint_t" AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) fi if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. dnl .....intro message done, now do a few system checks..... dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead inttype_headers=`echo $2 | sed -e 's/,/ /g'` ac_cv_stdint_result="(no helpful system typedefs seen)" AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) AC_MSG_RESULT([(..)]) for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do unset ac_cv_type_uintptr_t unset ac_cv_type_uint64_t _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" break; done AC_MSG_CHECKING([for stdint uintptr_t]) ]) if test "_$ac_cv_header_stdint_x" = "_" ; then AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) AC_MSG_RESULT([(..)]) for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do unset ac_cv_type_uint32_t unset ac_cv_type_uint64_t AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) ac_cv_stdint_result="(seen uint32_t$and64 in $i)" break; done AC_MSG_CHECKING([for stdint uint32_t]) ]) fi if test "_$ac_cv_header_stdint_x" = "_" ; then if test "_$ac_cv_header_stdint_o" = "_" ; then AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) AC_MSG_RESULT([(..)]) for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do unset ac_cv_type_u_int32_t unset ac_cv_type_u_int64_t AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" break; done AC_MSG_CHECKING([for stdint u_int32_t]) ]) fi fi dnl if there was no good C99 header file, do some typedef checks... if test "_$ac_cv_header_stdint_x" = "_" ; then AC_MSG_CHECKING([for stdint datatype model]) AC_MSG_RESULT([(..)]) AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(void*) ac_cv_stdint_char_model="" ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char" ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short" ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int" ac_cv_stdint_long_model="" ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int" ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long" ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp" name="$ac_cv_stdint_long_model" case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in 122/242) name="$name, IP16 (standard 16bit machine)" ;; 122/244) name="$name, LP32 (standard 32bit mac/win)" ;; 122/*) name="$name (unusual int16 model)" ;; 124/444) name="$name, ILP32 (standard 32bit unixish)" ;; 124/488) name="$name, LP64 (standard 64bit unixish)" ;; 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;; 124/*) name="$name (unusual int32 model)" ;; 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;; 128/*) name="$name (unusual int64 model)" ;; 222/*|444/*) name="$name (unusual dsptype)" ;; *) name="$name (very unusal model)" ;; esac AC_MSG_RESULT([combined for stdint datatype model... $name]) fi if test "_$ac_cv_header_stdint_x" != "_" ; then ac_cv_header_stdint="$ac_cv_header_stdint_x" elif test "_$ac_cv_header_stdint_o" != "_" ; then ac_cv_header_stdint="$ac_cv_header_stdint_o" elif test "_$ac_cv_header_stdint_u" != "_" ; then ac_cv_header_stdint="$ac_cv_header_stdint_u" else ac_cv_header_stdint="stddef.h" fi AC_MSG_CHECKING([for extra inttypes in chosen header]) AC_MSG_RESULT([($ac_cv_header_stdint)]) dnl see if int_least and int_fast types are present in _this_ header. unset ac_cv_type_int_least32_t unset ac_cv_type_int_fast32_t AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) fi # shortcircut to system "stdint.h" # ------------------ PREPARE VARIABLES ------------------------------ if test "$GCC" = "yes" ; then ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` else ac_cv_stdint_message="using $CC" fi AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl $ac_cv_stdint_result]) # ----------------- DONE inttypes.h checks START header ------------- AC_CONFIG_COMMANDS([$ac_stdint_h],[ AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) ac_stdint=$tmp/_stdint.h echo "#ifndef" $_ac_stdint_h >$ac_stdint echo "#define" $_ac_stdint_h "1" >>$ac_stdint echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint if test "_$ac_cv_header_stdint_t" != "_" ; then echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint fi cat >>$ac_stdint < #else #include /* .................... configured part ............................ */ STDINT_EOF echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint if test "_$ac_cv_header_stdint_x" != "_" ; then ac_header="$ac_cv_header_stdint_x" echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint else echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint fi echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint if test "_$ac_cv_header_stdint_o" != "_" ; then ac_header="$ac_cv_header_stdint_o" echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint else echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint fi echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint if test "_$ac_cv_header_stdint_u" != "_" ; then ac_header="$ac_cv_header_stdint_u" echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint else echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint fi echo "" >>$ac_stdint if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then echo "#include <$ac_header>" >>$ac_stdint echo "" >>$ac_stdint fi fi echo "/* which 64bit typedef has been found */" >>$ac_stdint if test "$ac_cv_type_uint64_t" = "yes" ; then echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint else echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint fi if test "$ac_cv_type_u_int64_t" = "yes" ; then echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint else echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint fi echo "" >>$ac_stdint echo "/* which type model has been detected */" >>$ac_stdint if test "_$ac_cv_stdint_char_model" != "_" ; then echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint else echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint fi echo "" >>$ac_stdint echo "/* whether int_least types were detected */" >>$ac_stdint if test "$ac_cv_type_int_least32_t" = "yes"; then echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint else echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint fi echo "/* whether int_fast types were detected */" >>$ac_stdint if test "$ac_cv_type_int_fast32_t" = "yes"; then echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint else echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint fi echo "/* whether intmax_t type was detected */" >>$ac_stdint if test "$ac_cv_type_intmax_t" = "yes"; then echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint else echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint fi echo "" >>$ac_stdint cat >>$ac_stdint <= 199901L #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #elif !defined __STRICT_ANSI__ #if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ #define _HAVE_UINT64_T typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ /* note: all ELF-systems seem to have loff-support which needs 64-bit */ #if !defined _NO_LONGLONG #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #endif #elif defined __alpha || (defined __mips && defined _ABIN32) #if !defined _NO_LONGLONG typedef long int64_t; typedef unsigned long uint64_t; #endif /* compiler/cpu type to define int64_t */ #endif #endif #endif #if defined _STDINT_HAVE_U_INT_TYPES /* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; /* glibc compatibility */ #ifndef __int8_t_defined #define __int8_t_defined #endif #endif #ifdef _STDINT_NEED_INT_MODEL_T /* we must guess all the basic types. Apart from byte-adressable system, */ /* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ /* (btw, those nibble-addressable systems are way off, or so we assume) */ dnl /* have a look at "64bit and data size neutrality" at */ dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ dnl /* (the shorthand "ILP" types always have a "P" part) */ #if defined _STDINT_BYTE_MODEL #if _STDINT_LONG_MODEL+0 == 242 /* 2:4:2 = IP16 = a normal 16-bit system */ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; #ifndef __int8_t_defined #define __int8_t_defined typedef char int8_t; typedef short int16_t; typedef long int32_t; #endif #elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 /* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ /* 4:4:4 = ILP32 = a normal 32-bit system */ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #ifndef __int8_t_defined #define __int8_t_defined typedef char int8_t; typedef short int16_t; typedef int int32_t; #endif #elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 /* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ /* 4:8:8 = LP64 = a normal 64-bit system */ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #ifndef __int8_t_defined #define __int8_t_defined typedef char int8_t; typedef short int16_t; typedef int int32_t; #endif /* this system has a "long" of 64bit */ #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef unsigned long uint64_t; typedef long int64_t; #endif #elif _STDINT_LONG_MODEL+0 == 448 /* LLP64 a 64-bit system derived from a 32-bit system */ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #ifndef __int8_t_defined #define __int8_t_defined typedef char int8_t; typedef short int16_t; typedef int int32_t; #endif /* assuming the system has a "long long" */ #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef unsigned long long uint64_t; typedef long long int64_t; #endif #else #define _STDINT_NO_INT32_T #endif #else #define _STDINT_NO_INT8_T #define _STDINT_NO_INT32_T #endif #endif /* * quote from SunOS-5.8 sys/inttypes.h: * Use at your own risk. As of February 1996, the committee is squarely * behind the fixed sized types; the "least" and "fast" types are still being * discussed. The probability that the "fast" types may be removed before * the standard is finalized is high enough that they are not currently * implemented. */ #if defined _STDINT_NEED_INT_LEAST_T typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; #ifdef _HAVE_UINT64_T typedef int64_t int_least64_t; #endif typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; #ifdef _HAVE_UINT64_T typedef uint64_t uint_least64_t; #endif /* least types */ #endif #if defined _STDINT_NEED_INT_FAST_T typedef int8_t int_fast8_t; typedef int int_fast16_t; typedef int32_t int_fast32_t; #ifdef _HAVE_UINT64_T typedef int64_t int_fast64_t; #endif typedef uint8_t uint_fast8_t; typedef unsigned uint_fast16_t; typedef uint32_t uint_fast32_t; #ifdef _HAVE_UINT64_T typedef uint64_t uint_fast64_t; #endif /* fast types */ #endif #ifdef _STDINT_NEED_INTMAX_T #ifdef _HAVE_UINT64_T typedef int64_t intmax_t; typedef uint64_t uintmax_t; #else typedef long intmax_t; typedef unsigned long uintmax_t; #endif #endif #ifdef _STDINT_NEED_INTPTR_T #ifndef __intptr_t_defined #define __intptr_t_defined /* we encourage using "long" to store pointer values, never use "int" ! */ #if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 typedef unsinged int uintptr_t; typedef int intptr_t; #elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 typedef unsigned long uintptr_t; typedef long intptr_t; #elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T typedef uint64_t uintptr_t; typedef int64_t intptr_t; #else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ typedef unsigned long uintptr_t; typedef long intptr_t; #endif #endif #endif /* shortcircuit*/ #endif /* once */ #endif #endif STDINT_EOF if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then AC_MSG_NOTICE([$ac_stdint_h is unchanged]) else ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` AS_MKDIR_P(["$ac_dir"]) rm -f $ac_stdint_h mv $ac_stdint $ac_stdint_h fi ],[# variables for create stdint.h replacement PACKAGE="$PACKAGE" VERSION="$VERSION" ac_stdint_h="$ac_stdint_h" _ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) ac_cv_stdint_message="$ac_cv_stdint_message" ac_cv_header_stdint_t="$ac_cv_header_stdint_t" ac_cv_header_stdint_x="$ac_cv_header_stdint_x" ac_cv_header_stdint_o="$ac_cv_header_stdint_o" ac_cv_header_stdint_u="$ac_cv_header_stdint_u" ac_cv_type_uint64_t="$ac_cv_type_uint64_t" ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" ac_cv_stdint_char_model="$ac_cv_stdint_char_model" ac_cv_stdint_long_model="$ac_cv_stdint_long_model" ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" ac_cv_type_intmax_t="$ac_cv_type_intmax_t" ]) ]) wvstreams-4.6.1/argp/argp-pv.c0000644000175000001440000000245711077124114015251 0ustar wlachusers/* Default definition for ARGP_PROGRAM_VERSION. Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* If set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which will print this this string followed by a newline and exit (unless the ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ const char *argp_program_version = 0; wvstreams-4.6.1/uniconf/0000755000175000001440000000000011260431126014227 5ustar wlachuserswvstreams-4.6.1/uniconf/unilistgen.cc0000644000175000001440000001047211036722347016734 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * UniListGen is a UniConf generator to allow multiple generators to be * stacked in a priority sequence for get/set/etc. * */ #include "unilistgen.h" #include "wvmoniker.h" #include "wvtclstring.h" #include "wvstringlist.h" #include "wvlinkerhack.h" WV_LINK(UniListGen); class UniListGen::IterIter : public UniConfGen::Iter { protected: DeclareWvScatterTable(UniConfKey); DeclareWvList2(IterList, UniConfGen::Iter); IterList l; IterList::Iter *i; UniConfKeyTable d; public: IterIter(UniListGen *gen, const UniConfKey &key); virtual ~IterIter() { delete i; } virtual void rewind(); virtual bool next(); virtual UniConfKey key() const; virtual WvString value() const; }; static IUniConfGen *creator(WvStringParm s, IObject *_obj) { UniConfGenList *l = new UniConfGenList(); WvStringList gens; wvtcl_decode(gens, s); WvStringList::Iter i(gens); for (i.rewind(); i.next();) { if (_obj) _obj->addRef(); IUniConfGen *gen = wvcreate(i(), _obj); if (gen) l->append(gen, true); } if (_obj) _obj->release(); return new UniListGen(l); } static WvMoniker reg("list", creator); UniListGen::UniListGen(UniConfGenList *_l) : l(_l) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next(); ) i->add_callback(this, wv::bind(&UniListGen::gencallback, this, _1, _2)); } UniListGen::~UniListGen() { UniConfGenList::Iter i(*l); for (i.rewind(); i.next(); ) i->del_callback(this); delete l; } void UniListGen::commit() { UniConfGenList::Iter i(*l); for (i.rewind(); i.next();) i->commit(); } bool UniListGen::refresh() { bool result = true; UniConfGenList::Iter i(*l); for (i.rewind(); i.next();) result = i->refresh() && result; return result; } WvString UniListGen::get(const UniConfKey &key) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next(); ) if (i->exists(key)) return i->get(key); return WvString::null; } // we try to set *all* our generators. Read-only ones will ignore us. void UniListGen::set(const UniConfKey &key, WvStringParm value) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next(); ) i->set(key, value); } void UniListGen::setv(const UniConfPairList &pairs) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next(); ) i->setv(pairs); } bool UniListGen::exists(const UniConfKey &key) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next();) { if (i->exists(key)) return true; } return false; } bool UniListGen::haschildren(const UniConfKey &key) { UniConfGenList::Iter i(*l); for (i.rewind(); i.next();) { if (i->haschildren(key)) return true; } return false; } bool UniListGen::isok() { UniConfGenList::Iter i(*l); for (i.rewind(); i.next();) { if (!i->isok()) return false; } return true; } void UniListGen::gencallback(const UniConfKey &key, WvStringParm value) { delta(key, get(key)); } UniConfGen::Iter *UniListGen::iterator(const UniConfKey &key) { return new IterIter(this, key); } /***** UniListGen::IterIter *****/ UniListGen::IterIter::IterIter(UniListGen *gen, const UniConfKey &key) { UniConfGenList::Iter geniter(*gen->l); for (geniter.rewind(); geniter.next(); ) { Iter *it = geniter->iterator(key); if (it) l.append(it, true); } i = new IterList::Iter(l); } void UniListGen::IterIter::rewind() { for ((*i).rewind(); (*i).next(); ) (*i)->rewind(); i->rewind(); i->next(); d.zap(); } bool UniListGen::IterIter::next() { if (l.isempty()) return false; if ((*i)->next()) { // When iterating, make sure each key value is only returned once // (from the top item in the list) if (!d[(*i)->key()]) { d.add(new UniConfKey((*i)->key()), true); return true; } else return next(); } if (!i->next()) return false; return next(); } UniConfKey UniListGen::IterIter::key() const { return (*i)->key(); } WvString UniListGen::IterIter::value() const { return (*i)->value(); } wvstreams-4.6.1/uniconf/unitempgen.cc0000644000175000001440000001030111057766345016726 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002-2005 Net Integration Technologies, Inc. * * A UniConf generator that stores keys in memory. */ #include "unitempgen.h" #include "wvmoniker.h" #include "wvlog.h" #include "wvstringcache.h" #include "unilistiter.h" #include "wvlinkerhack.h" WV_LINK(UniTempGen); static IUniConfGen *creator(WvStringParm, IObject*) { return new UniTempGen(); } static WvMoniker reg("temp", creator); /***** UniTempGen *****/ UniTempGen::UniTempGen() : root(NULL) { } UniTempGen::~UniTempGen() { delete root; } WvString UniTempGen::get(const UniConfKey &key) { if (root) { // Look for an empty section at the end. if (!key.isempty() && key.last().isempty()) return WvString::null; UniConfValueTree *node = root->find(key); if (node) return node->value(); } return WvString::null; } void UniTempGen::notify_deleted(const UniConfValueTree *node, void *) { delta(node->fullkey(), WvString::null); } void UniTempGen::set(const UniConfKey &_key, WvStringParm _value) { WvString value(scache.get(_value)); hold_delta(); UniConfKey key = _key; // FIXME: Use key.hastrailingslash(), it's shorter and easier and faster bool trailing_slash = false; if (!key.isempty()) { // Look for an empty section at the end. UniConfKey last = key; key = last.pop(last.numsegments() - 1); if (last.isempty()) trailing_slash = true; else key = _key; } if (value.isnull()) { // remove a subtree if (root) { UniConfValueTree *node = root->find(key); if (node) { hold_delta(); // Issue notifications for every key that gets deleted. node->visit(wv::bind(&UniTempGen::notify_deleted, this, _1, _2), NULL, false, true); delete node; if (node == root) root = NULL; dirty = true; unhold_delta(); } } } else if (!trailing_slash) { UniConfValueTree *node = root; UniConfValueTree *prev = NULL; UniConfKey prevkey; UniConfKey::Iter it(key); it.rewind(); for (;;) { bool more = it.next(); // not the last node in the key? if (!node) { // we'll have to create the sub-node, since we couldn't // find the most recent part of the key. node = new UniConfValueTree(prev, prevkey, more ? WvString::empty : value); dirty = true; if (!prev) // we just created the root root = node; if (more) delta(node->fullkey(), WvString::empty); // AUTO-VIVIFIED else { delta(node->fullkey(), value); // ADDED break; // done! } } else if (!more) { // don't have to create the most recent sub-node, but there // are no more sub-nodes; that means we're changing the value // of an existing node. if (value != node->value()) { node->setvalue(value); dirty = true; delta(node->fullkey(), value); // CHANGED } break; } prevkey = *it; prev = node; node = prev->findchild(prevkey); } assert(node); } unhold_delta(); } void UniTempGen::setv(const UniConfPairList &pairs) { setv_naive(pairs); } bool UniTempGen::haschildren(const UniConfKey &key) { if (root) { UniConfValueTree *node = root->find(key); return node != NULL && node->haschildren(); } return false; } UniConfGen::Iter *UniTempGen::iterator(const UniConfKey &key) { if (root) { UniConfValueTree *node = root->find(key); if (node) { ListIter *it = new ListIter(this); UniConfValueTree::Iter i(*node); for (i.rewind(); i.next(); ) it->add(i->key(), i->value()); return it; } } return NULL; } void UniTempGen::commit() { UniConfGen::commit(); } bool UniTempGen::refresh() { return UniConfGen::refresh(); } wvstreams-4.6.1/uniconf/daemon/0000755000175000001440000000000011260431131015466 5ustar wlachuserswvstreams-4.6.1/uniconf/daemon/tests/0000755000175000001440000000000011036722347016645 5ustar wlachuserswvstreams-4.6.1/uniconf/daemon/tests/daemontest05.txt0000644000175000001440000000001411036722347021711 0ustar wlachuserssubt / quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest.sh0000755000175000001440000000455211036722347021355 0ustar wlachusers#!/bin/sh # Shell script file to test some basic functionality of the UniConfDaemon. # Note: This uses the files daemontest##.txt and daemonresult##.txt function do_help { echo "" echo "This script tests the UniConfDaemon, via nc" echo "usage: daemontest.sh [-h] [-host ] [-port ]" echo "Options:" echo " -h : Display this help page" echo " -host : Test the UniConfDaemon on the specified server." echo " -port : Use the specified port number" echo " -noless : Don't less the difference files on a failed test." echo " -stress : Run the test files 100 times in succession. Needed to detect some heisenbugs." echo "" echo "Note: To add more tests to this script, simply create a new daemontest*.txt" echo "file in this directory, and create an appropriate real_res_daemontest*.txt file." echo "" exit 0 } testfiles=$(ls daemontest*.txt) failedfiles="" nl="-" stress="-" host="localhost" port="4111" function do_tests { for filename in $testfiles; do # echo $filename $cmd < $filename > res_$filename diff -b real_res_$filename res_$filename > diff_$filename if [ -s diff_$filename ]; then echo "TEST WITH FILE: $filename FAILED!" failedfiles="$failedfiles $filename" else rm -f diff_$filename res_$filename fi done } if [ "$1" = "-h" ]; then do_help fi # Set up the basic variables now # Now poll any command line arguments to get specified vars until [ $# -eq 0 ]; do case $1 in "-host" ) shift if [ $# -eq 0 ]; then do_help else host="$1" fi ;; "-port" ) shift if [ $# -eq 0 -o ! isnum $1 ]; then do_help else port=$1 fi ;; "-noless" ) nl="+" ;; "-stress" ) stress="+" ;; * ) do_help ;; esac shift done # Now create our nc command cmd="nc $host $port" runtimes=1 if [ "$stress" = "+" ] ; then runtimes=100 fi count=0 until [ $count -ge $runtimes ]; do do_tests count=$((count + 1)) if [ "$failedfiles" != "" ]; then break fi done if [ "$nl" = "+" ]; then exit 0 fi for filename in $failedfiles; do less -Psdiff_$filename diff_$filename done wvstreams-4.6.1/uniconf/daemon/tests/daemontest01.txt0000644000175000001440000000000511036722347021705 0ustar wlachusersquit wvstreams-4.6.1/uniconf/daemon/tests/daemontest08.txt0000644000175000001440000000012311036722347021715 0ustar wlachusersget /chickens/bob set /chickens/bob nerf rsub / set /chickens/bob goof rsub / quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest07.txt0000644000175000001440000000014311036722347021716 0ustar wlachusersget /chickens/bob set /chickens/bob nerf subt /chickens set /chickens/bob goof subt /chickens quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest02.txt0000644000175000001440000000013011036722347023561 0ustar wlachusersHELLO UniConf Server ready OK get /chickens/bob RETN /chickens/bob goof OK quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest09.txt0000644000175000001440000000010311036722347021714 0ustar wlachusersget /chickens set /chickens nerf subt /chickens set /chickens quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest09.txt0000644000175000001440000000026111036722347023575 0ustar wlachusersHELLO UniConf Server ready OK get /chickens RETN /chickens OK set /chickens OK subt /chickens SUBT /chickens {bob goof} {bill weasel} {nob bon} OK set /chickens OK quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest03.txt0000644000175000001440000000005611036722347021715 0ustar wlachusersget /chickens/bob set /chickens/bob nerf quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest08.txt0000644000175000001440000000162711036722347023603 0ustar wlachusersHELLO UniConf Server ready OK get /chickens/bob RETN /chickens/bob goof OK set /chickens/bob OK rsub / SUBT / {{wacky test section/ goose } bluebayou} {{wacky test section/weasels are } {like geese}} {chickens/bob nerf} {chickens/bill weasel} {chickens/nob bon} {wtf {wha the}} {big/fat/bob 2} {users/dcoombs blah} {users/apenwarr scs} {users/apenwarr/ftp 1} {users/apenwarr/pptp 0} {users/apenwarr/chicken/hammer 5} {nerf foo} {{chicken/hammer design} {simple test}} {barn burn} OK set /chickens/bob OK rsub / SUBT / {{wacky test section/ goose } bluebayou} {{wacky test section/weasels are } {like geese}} {chickens/bob goof} {chickens/bill weasel} {chickens/nob bon} {wtf {wha the}} {big/fat/bob 2} {users/dcoombs blah} {users/apenwarr scs} {users/apenwarr/ftp 1} {users/apenwarr/pptp 0} {users/apenwarr/chicken/hammer 5} {nerf foo} {{chicken/hammer design} {simple test}} {barn burn} OK quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest06.txt0000644000175000001440000000066511036722347023602 0ustar wlachusersHELLO UniConf Server ready OK rsub / SUBT / {{wacky test section/ goose } bluebayou} {{wacky test section/weasels are } {like geese}} {chickens/bob goof} {chickens/bill weasel} {chickens/nob bon} {wtf {wha the}} {big/fat/bob 2} {users/dcoombs blah} {users/apenwarr scs} {users/apenwarr/ftp 1} {users/apenwarr/pptp 0} {users/apenwarr/chicken/hammer 5} {nerf foo} {{chicken/hammer design} {simple test}} {barn burn} OK quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest03.txt0000644000175000001440000000015511036722347023571 0ustar wlachusersHELLO UniConf Server ready OK get /chickens/bob RETN /chickens/bob goof OK set /chickens/bob OK quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest06.txt0000644000175000001440000000001411036722347021712 0ustar wlachusersrsub / quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest04.txt0000644000175000001440000000023111036722347023565 0ustar wlachusersHELLO UniConf Server ready OK get /chickens/bob RETN /chickens/bob nerf OK set /chickens/bob OK get /chickens/bob RETN /chickens/bob goof OK quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest07.txt0000644000175000001440000000041311036722347023572 0ustar wlachusersHELLO UniConf Server ready OK get /chickens/bob RETN /chickens/bob goof OK set /chickens/bob OK subt /chickens SUBT /chickens {bob nerf} {bill weasel} {nob bon} OK set /chickens/bob OK subt /chickens SUBT /chickens {bob goof} {bill weasel} {nob bon} OK quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest05.txt0000644000175000001440000000027311036722347023574 0ustar wlachusersHELLO UniConf Server ready OK subt / SUBT / {{wacky test section} (nil)} {chickens (nil)} {wtf {wha the}} {big (nil)} {users (nil)} {nerf foo} {chicken (nil)} {barn burn} OK quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest04.txt0000644000175000001440000000010011036722347021704 0ustar wlachusersget /chickens/bob set /chickens/bob goof get /chickens/bob quit wvstreams-4.6.1/uniconf/daemon/tests/daemontest02.txt0000644000175000001440000000002711036722347021712 0ustar wlachusersget /chickens/bob quit wvstreams-4.6.1/uniconf/daemon/tests/real_res_daemontest01.txt0000644000175000001440000000005211036722347023563 0ustar wlachusersHELLO UniConf Server ready OK quit wvstreams-4.6.1/uniconf/daemon/sample.ini0000644000175000001440000000075611036722347017475 0ustar wlachusers[{}] key = value2 nerf = {fooblah bar} help = morphine wtf = blah blah = blah wft = zzz {{ }} = foo [wacky test section] { goose } = bluebayou {weasels are } = {like geese} [key] {only child} = {so alone} [users] dcoombs = blah apenwarr = scsy [users/apenwarr] ftp = 1 pptp = 0 [users/apenwarr/chicken] hammer = 5 [help] sos = {dit-dit-dit dah-dah-dah dit-dit-dit} [chickens] bob = goof nob = bon bill = weasel [{different wacky test section}] try = {try ... catch ... finally} wvstreams-4.6.1/uniconf/daemon/uniconfd.cc0000644000175000001440000001107611044160724017616 0ustar wlachusers#include "wvautoconf.h" #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_GETOPT_H # include #endif #ifndef _WIN32 #include #include #include #endif #ifdef WITH_SLP #include "wvslp.h" #endif #include "wvlogrcv.h" #include "uniconfdaemon.h" #include "uniclientconn.h" #include "unisecuregen.h" #include "unipermgen.h" #include "uniconfroot.h" #include "wvstrutils.h" #include "wvfileutils.h" #include "wvstreamsdaemon.h" #ifdef WITH_SLP #include "slp.h" #endif #include using std::map; using wv::shared_ptr; #ifdef _WIN32 #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #pragma comment(linker, "/include:?UniIniGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #endif #define DEFAULT_CONFIG_FILE "ini:uniconf.ini" static map > namedgens; static IUniConfGen *creator(WvStringParm s, IObject*) { map >::iterator it = namedgens.find(s); shared_ptr gen; if (it != namedgens.end()) gen = it->second; if (gen) gen->addRef(); return gen.get(); } WvMoniker UniNamedMoniker("named", creator); class UniConfd : public WvStreamsDaemon { bool needauth; WvString permmon; WvStringList lmonikers; time_t commit_interval; UniConfRoot cfg; bool first_time; IUniConfGen *permgen; bool namedgen_cb(WvStringParm option, void *) { WvString name(option); WvString moniker; char* ptr; ptr = strchr(name.edit(), '='); if (!ptr) return false; *ptr = 0; moniker = ptr + 1; namedgens[name] = shared_ptr( wvcreate(moniker), wv::bind(&IUniConfGen::release, _1)); return true; } void commit_stream_cb(WvStream *s) { cfg.commit(); cfg.refresh(); if (permgen) permgen->refresh(); s->alarm(commit_interval * 1000); } void startup() { if (first_time) { WvStringList::Iter i(_extra_args); for (i.rewind(); i.next(); ) { WvString path = *i, moniker; char *cptr = strchr(path.edit(), '='); if (!cptr) { moniker = path; path = "/"; } else { *cptr = 0; moniker = cptr+1; } log("Mounting '%s' on '%s': ", moniker, path); IUniConfGen *gen = cfg[path].mount(moniker, false); if (gen && gen->isok()) log("ok.\n"); else log("FAILED!\n"); } cfg.refresh(); } permgen = !!permmon ? wvcreate(permmon) : NULL; UniConfDaemon *daemon = new UniConfDaemon(cfg, needauth, permgen); add_die_stream(daemon, true, "uniconfd"); if (lmonikers.isempty()) { log(WvLog::Critical, "Can't start: no listeners given!\n"); die(7); return; } WvStringList::Iter i(lmonikers); for (i.rewind(); i.next(); ) daemon->listen(*i); WvStream *commit_stream = new WvStream; commit_stream->setcallback(wv::bind(&UniConfd::commit_stream_cb, this, commit_stream)); commit_stream->alarm(commit_interval * 1000); add_die_stream(commit_stream, true, "commit"); if (first_time) first_time = false; } public: UniConfd(): WvStreamsDaemon("uniconfd", VERBOSE_WVPACKAGE_VERSION, wv::bind(&UniConfd::startup, this)), needauth(false), commit_interval(5*60), first_time(true), permgen(NULL) { args.add_option(0, "pid-file", "Specify the .pid file to use (only applies with --daemonize)", "filename", pid_file); args.add_set_bool_option('a', "need-auth", "Require authentication on incoming connections", needauth); args.add_option('A', "check-access", "Check all accesses against perms moniker", "moniker", permmon); args.add_option('l', "listen", "Listen on the given socket (eg. tcp:4111, ssl:tcp:4112)", "lmoniker", lmonikers); args.add_option('n', "named-gen", "creates a \"named\" moniker 'name' from 'moniker'", "name=moniker", wv::bind(&UniConfd::namedgen_cb, this, _1, _2), NULL); args.add_optional_arg("MONIKERS", true); args.set_email("<" WVPACKAGE_BUGREPORT ">"); } }; int main(int argc, char **argv) { UniConfd uniconfd; return uniconfd.run(argc, argv); } wvstreams-4.6.1/uniconf/daemon/uniconfdaemonconn.cc0000644000175000001440000001517411036722347021525 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a UniConf daemon session. */ #include "uniconfdaemonconn.h" #include "uniconfdaemon.h" #include "wvtclstring.h" #include "wvstrutils.h" /***** UniConfDaemonConn *****/ UniConfDaemonConn::UniConfDaemonConn(WvStream *_s, const UniConf &_root) : UniClientConn(_s), root(_root) { uses_continue_select = true; addcallback(); writecmd(EVENT_HELLO, spacecat(wvtcl_escape("UniConf Server ready."), wvtcl_escape(UNICONF_PROTOCOL_VERSION))); } UniConfDaemonConn::~UniConfDaemonConn() { close(); terminate_continue_select(); delcallback(); } void UniConfDaemonConn::close() { UniClientConn::close(); } void UniConfDaemonConn::addcallback() { root.add_callback(this, wv::bind(&UniConfDaemonConn::deltacallback, this, _1, _2), true); } void UniConfDaemonConn::delcallback() { root.del_callback(this, true); } void UniConfDaemonConn::execute() { UniClientConn::execute(); WvString command_string; UniClientConn::Command command = readcmd(command_string); if (command != UniClientConn::NONE) { // parse and execute command WvString arg1(readarg()); WvString arg2(readarg()); switch (command) { case UniClientConn::NONE: break; case UniClientConn::INVALID: do_invalid(command_string); break; case UniClientConn::REQ_NOOP: do_noop(); break; case UniClientConn::REQ_GET: if (arg1.isnull()) do_malformed(command); else do_get(arg1); break; case UniClientConn::REQ_SET: if (arg1.isnull() || arg2.isnull()) do_malformed(command); else do_set(arg1, arg2); break; case UniClientConn::REQ_REMOVE: if (arg1.isnull()) do_malformed(command); else do_remove(arg1); break; case UniClientConn::REQ_SUBTREE: if (arg1.isnull()) do_malformed(command); else do_subtree(arg1, arg2.num() == 1); break; case UniClientConn::REQ_HASCHILDREN: if (arg1.isnull()) do_malformed(command); else do_haschildren(arg1); break; case UniClientConn::REQ_COMMIT: do_commit(); break; case UniClientConn::REQ_REFRESH: do_refresh(); break; case UniClientConn::REQ_QUIT: do_quit(); break; case UniClientConn::REQ_HELP: do_help(); break; default: do_invalid(command_string); break; } } } void UniConfDaemonConn::do_invalid(WvStringParm c) { writefail(WvString("unknown command: %s", c)); } void UniConfDaemonConn::do_malformed(UniClientConn::Command c) { writefail(WvString("malformed request: %s", UniClientConn::cmdinfos[c].name)); } void UniConfDaemonConn::do_noop() { writeok(); } void UniConfDaemonConn::do_reply(WvStringParm reply) { writefail("unexpected reply"); } void UniConfDaemonConn::do_get(const UniConfKey &key) { WvString value(root[key].getme()); if (value.isnull()) writefail(); else writeonevalue(key, value); } void UniConfDaemonConn::do_set(const UniConfKey &key, WvStringParm value) { root[key].setme(value); } void UniConfDaemonConn::do_remove(const UniConfKey &_key) { int notifications_sent = 0; bool single_key = true; // Remove '/' at the end of the key WvString strkey = _key; for (int n = strkey.len()-1; n > 0; n--) { if (strkey.edit()[n] == '/') strkey.edit()[n] = ' '; else break; } trim_string(strkey.edit()); UniConfKey key = strkey; // Remove keys one at a time UniConf cfg(root[key]); if (cfg.exists()) { UniConf::RecursiveIter it(cfg); for (it.rewind(); it.next(); ) { single_key = false; WvString sect_name = getdirname(it->fullkey()); root[it->fullkey()].remove(); if (sect_name == ".") sect_name = WvString::null; if (!root[sect_name].haschildren()) root[sect_name].remove(); // Don't hog the daemon while delivering notifications if (++notifications_sent > CONTINUE_SELECT_AT) { notifications_sent = 0; if (isok()) continue_select(0); } } if (single_key) root[key].remove(); } } void UniConfDaemonConn::do_subtree(const UniConfKey &key, bool recursive) { static int niceness = 0; UniConf cfg(root[key]); if (cfg.exists()) { if (recursive) { UniConf::RecursiveIter it(cfg); for (it.rewind(); it.next(); ) { writevalue(it->fullkey(cfg), it._value()); // the output might be totally gigantic. Don't hog the // entire daemon while fulfilling it; give up our timeslice // after each entry. if (!isok()) break; if (++niceness > CONTINUE_SELECT_AT) { niceness = 0; continue_select(0); } } } else { UniConf::Iter it(cfg); for (it.rewind(); it.next(); ) { writevalue(it->fullkey(cfg), it._value()); // the output might be totally gigantic. Don't hog the // entire daemon while fulfilling it; give up our timeslice // after each entry. if (!isok()) break; continue_select(0); } } writeok(); } else writefail(); } void UniConfDaemonConn::do_haschildren(const UniConfKey &key) { bool haschild = root[key].haschildren(); writecmd(REPLY_CHILD, spacecat(wvtcl_escape(key), haschild ? "TRUE" : "FALSE")); } void UniConfDaemonConn::do_commit() { root.commit(); writeok(); } void UniConfDaemonConn::do_refresh() { if (root.refresh()) writeok(); else writefail(); } void UniConfDaemonConn::do_quit() { writeok(); close(); } void UniConfDaemonConn::do_help() { for (int i = 0; i < UniClientConn::NUM_COMMANDS; ++i) writetext(UniClientConn::cmdinfos[i].description); writeok(); } void UniConfDaemonConn::deltacallback(const UniConf &cfg, const UniConfKey &key) { // for now, we just send notifications for *any* key that changes. // Eventually we probably want to do something about having each // connection specify exactly which keys it cares about. WvString value(cfg[key].getme()); WvString msg; UniConfKey fullkey(cfg.fullkey(cfg)); fullkey.append(key); if (value.isnull()) msg = wvtcl_escape(fullkey); else msg = spacecat(wvtcl_escape(fullkey), wvtcl_escape(cfg[key].getme())); writecmd(UniClientConn::EVENT_NOTICE, msg); } wvstreams-4.6.1/uniconf/daemon/uniconfpamconn.cc0000644000175000001440000000201711036722347021027 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a UniConf daemon session which is authenticated through PAM. */ #include "uniconfpamconn.h" #include "unisecuregen.h" #include "unipermgen.h" #include "uniunwrapgen.h" #include "uniconfdaemonconn.h" #include "uninullgen.h" #include "wvpam.h" #include "wvaddr.h" UniConfPamConn::UniConfPamConn(WvStream *_s, const UniConf &_root, UniPermGen *perms) : WvStreamClone(NULL) { WvPam pam("uniconfd"); WvString rhost(*(WvIPAddr *)_s->src()); if (pam.authenticate(rhost, "", WvString::null)) { UniSecureGen *sec = new UniSecureGen(new UniUnwrapGen(_root), perms); // get the user and groups from PAM WvString user = pam.getuser(); WvStringList groups; pam.getgroups(groups); sec->setcredentials(user, groups); newroot.mountgen(sec, false); setclone(new UniConfDaemonConn(_s, newroot)); } else { _s->print("FAIL {Not Authorized}\n"); _s->flush_then_close(1000); } } wvstreams-4.6.1/uniconf/daemon/uniconfd.ini.subst0000644000175000001440000000003311042636572021145 0ustar wlachusers[{}] version = {#VERSION#} wvstreams-4.6.1/uniconf/daemon/uniconfdaemon.cc0000644000175000001440000000413611036722347020643 0ustar wlachusers/* * Worldvisions Weaver Software * Copyright (C) 1997 - 2004 Net Integration Technologies Inc. * * Daemon program for the uniconf configuration system. */ #include "uniconfdaemon.h" #include "uniconfdaemonconn.h" #include "wvlistener.h" #include "uninullgen.h" #ifndef _WIN32 #include "uniconfpamconn.h" #endif UniConfDaemon::UniConfDaemon(const UniConf &_cfg, bool auth, IUniConfGen *_permgen) : cfg(_cfg), log("UniConf Daemon"), debug(log.split(WvLog::Debug1)) { authenticate = auth; #ifdef _WIN32 assert(!authenticate); #endif permgen = _permgen ? _permgen : new UniNullGen(); debug("Starting.\n"); } UniConfDaemon::~UniConfDaemon() { close(); WVRELEASE(permgen); } void UniConfDaemon::close() { if (!closed) { debug("Saving changes.\n"); cfg.commit(); debug("Done saving changes.\n"); } WvIStreamList::close(); } void UniConfDaemon::accept(WvStream *stream) { // FIXME: permgen should be used regardless of whether we authenticate, // and there should be a command to authenticate explicitly. That way we // can support access control for anonymous connections. #ifndef _WIN32 if (authenticate) append(new UniConfPamConn(stream, cfg, new UniPermGen(permgen)), true, "ucpamconn"); else #endif append(new UniConfDaemonConn(stream, cfg), true, "ucdaemonconn"); } void UniConfDaemon::listencallback(IWvStream *s) { const WvAddr *a = s->src(); if (a) debug("Incoming connection from %s.\n", *a); else debug("Incoming connection from UNKNOWN.\n"); if (s->geterr()) { debug("Error: %s\n", s->errstr()); WVRELEASE(s); } else accept(new WvStreamClone(s)); } void UniConfDaemon::listen(WvStringParm lmoniker) { IWvListener *l = IWvListener::create(lmoniker); debug("Listening on %s.\n", *l->src()); if (!l->isok()) { log(WvLog::Error, "Can't listen: %s\n", l->errstr()); seterr_both(l->geterr(), l->errstr()); WVRELEASE(l); } else { l->onaccept(wv::bind(&UniConfDaemon::listencallback, this, _1)); append(l, true, "listener"); } } wvstreams-4.6.1/uniconf/daemon/uniconfd.8.subst0000644000175000001440000000663111042636572020547 0ustar wlachusers'\" t .\" Worldvisions Weaver Software .\" Copyright (C) 1997 - 2004 Net Integration Technologies Inc. .TH UNICONFD 8 "August 2004" "UniConfDaemon #VERSION#" .SH NAME uniconfd \- a daemon program for the UniConf configuration system .SH SYNOPSIS .B uniconfd [ .IR OPTIONS ] .IR MOUNT\ ... .SH DESCRIPTION UniConf is the One True Configuration system that includes all the others because it has plugin backends .I and frontends. Or, less grandiosely, it's a lightweight, distributed, cacheable tree of strings. It supports: .IP \(bu 4 retrieving, storing, and enumerating key/value pairs (where both keys and values are strings). .IP \(bu multiple backends where the actual key/value pairs are stored. .IP \(bu multiple frontends for tying it to other configuration architectures. .PP It operates locally, and across a network, allowing you to tie multiple different applications together for distributed computing. Also, it provides notifications in the form of callbacks, so your application can be notified if a configuration key has changed. .B uniconfd is necessary when you have more than one application, or multiple instances of an application, sharing one configuration. UniConf-enabled applications contact .B uniconfd which provides notifications when any of their watched keys change. You tell .B uniconfd which UniConf .I MOUNT you want it to manage. See the .B MOUNTS section for more information. .SH OPTIONS .TP .B \-f Run in the foreground. Do not fork into a separate daemon process. .TP .BR \-d ,\ \-dd Print debugging messages to the console. The second .B d increases the verbosity of the messages. .TP .B \-V Print the version number and exit. .TP .B \-a Require authentication on incoming connections. .TP .B \-A Check all accesses against a .I perms moniker. .TP .BI \-p\ port Listen on a given TCP .IR port . The default is 4111. If .I port is 0, then listening on TCP is disabled. .TP .BI \-s\ port Listen on a given TCP .I port wrapped in SSL. The default is 4112. If .I port is 0, then listening on SSL-over-TCP is disabled. .TP .BI \-u\ filename Listen on a given Unix socket .IR filename . This is disabled by default. .SH MOUNTS Mounts are UniConf path monikers which are in the form: .RS .RI / SUBTREE = GENERATORS : PATH .RE .TP .I SUBTREE This is the tree to manage. All trees are descended from the root tree, indicated by a bare slash .RB ( / ). .TP .I GENERATORS These are the generators used to read and write key/value pairs. You can chain them with colons. For example, the generator chain: .I cache:retry:ini will cache the configuration for speed, retry persistently if the data source disappears, and store the data in an INI-formatted file. .TP .I PATH This is the location where the data is stored. It is dependent on which .IR GENERATOR S were specified. For instance, it could be: \(bu a filename .RI (ini: /var/lib/app/config.ini ), .br \(bu a network address, .RI (tcp: open.nit.ca:4111 ), .br \(bu or even an empty string (tmp:). .PP .B Examples: .RS .RI /= tmp : .br .RI / ca/nit = ssl : open.nit.ca .br .RI / ca/nit/uniconfd = ini : /var/lib/uniconfd/uniconfd.ini .br .RI / apps = cache:retry:unix : /var/lib/apps/socket .RE .SH FILES .I /etc/uniconfd.conf .br .I /var/lib/uniconf/uniconfd.ini .br .I /var/lib/uniconf/uniconf.ini .SH AUTHORS This software was written by the hackers at Net Integration Technologies. Contact us at .\" Local variables: .\" mode:nroff .\" End: wvstreams-4.6.1/uniconf/daemon/uniconf.conf0000644000175000001440000000021611036722347020012 0ustar wlachusers/ = retry:unix:/var/lib/uniconf/control ca/nit/uniconfd = ini:/var/lib/uniconf/uniconfd.ini ca/nit/nssuniconf = unix:/var/lib/uniconf/control wvstreams-4.6.1/uniconf/unihashtree.cc0000644000175000001440000001262511036722347017074 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniConf low-level tree storage abstraction. */ #include "unihashtree.h" #include "assert.h" UniHashTreeBase::UniHashTreeBase(UniHashTreeBase *parent, const UniConfKey &key) : xkey(key) { xparent = parent; xchildren = NULL; if (xparent) xparent->link(this); } UniHashTreeBase::~UniHashTreeBase() { if (xchildren) { Container *oldchildren = xchildren; xchildren = NULL; delete oldchildren; } // This happens only after the children are deleted by our // subclass. This ensures that we do not confuse them // about their parentage as their destructors are invoked // The xchildren vector is destroyed by the subclass! if (xparent) xparent->unlink(this); } void UniHashTreeBase::_setparent(UniHashTreeBase *parent) { if (xparent == parent) return; if (xparent) xparent->unlink(this); xparent = parent; if (xparent) xparent->link(this); } UniHashTreeBase *UniHashTreeBase::_root() const { const UniHashTreeBase *node = this; while (node->xparent) node = node->xparent; return const_cast(node); } UniConfKey UniHashTreeBase::_fullkey(const UniHashTreeBase *ancestor) const { UniConfKey result; if (ancestor) { const UniHashTreeBase *node = this; while (node != ancestor) { result.prepend(node->key()); node = node->xparent; assert(node != NULL || ! "ancestor was not a node in the tree"); } } else { const UniHashTreeBase *node = this; while (node->xparent) { result.prepend(node->key()); node = node->xparent; } } return result; } UniHashTreeBase *UniHashTreeBase::_find(const UniConfKey &key) const { const UniHashTreeBase *node = this; UniConfKey::Iter it(key); it.rewind(); while (it.next()) { node = node->_findchild(it()); if (!node) break; } return const_cast(node); } UniHashTreeBase *UniHashTreeBase::_findchild(const UniConfKey &key) const { if (key.isempty()) return const_cast(this); return xchildren ? (*xchildren)[key] : NULL; } bool UniHashTreeBase::haschildren() const { return xchildren && !xchildren->isempty(); } void UniHashTreeBase::link(UniHashTreeBase *node) { if (!xchildren) xchildren = new Container(); xchildren->add(node); } void UniHashTreeBase::unlink(UniHashTreeBase *node) { if (!xchildren) return; xchildren->remove(node); if (xchildren->count() == 0) { delete xchildren; xchildren = NULL; } } static int keysorter(const UniHashTreeBase *a, const UniHashTreeBase *b) { return a->key().compareto(b->key()); } void UniHashTreeBase::_recursive_unsorted_visit( const UniHashTreeBase *a, const UniHashTreeBaseVisitor &visitor, void *userdata, bool preorder, bool postorder) { if (preorder) visitor(a, userdata); Container::Iter i(*const_cast(a->xchildren)); for (i.rewind(); i.next();) _recursive_unsorted_visit(i.ptr(), visitor, userdata, preorder, postorder); if (postorder) visitor(a, userdata); } bool UniHashTreeBase::_recursivecompare( const UniHashTreeBase *a, const UniHashTreeBase *b, const UniHashTreeBaseComparator &comparator) { bool equal = true; // don't bother comparing subtree if this returns false // apenwarr 2004/04/26: some people seem to call recursivecompare and // have their comparator function get called for *all* keys, because // it has side effects. Gross, but whatever. If that's the case, then // short-circuiting here is a bad idea. if (!comparator(a, b)) equal = false; // begin iteration sequence Container::Sorter *ait = NULL, *bit = NULL; if (a != NULL) { ait = new Container::Sorter(*const_cast(a->xchildren), keysorter); ait->rewind(); a = ait->next() ? ait->ptr() : NULL; } if (b != NULL) { bit = new Container::Sorter(*const_cast(b->xchildren), keysorter); bit->rewind(); b = bit->next() ? bit->ptr() : NULL; } // compare each key while (a != NULL && b != NULL) { int order = a->key().compareto(b->key()); if (order < 0) { equal = false; _recursivecompare(a, NULL, comparator); a = ait->next() ? ait->ptr() : NULL; } else if (order > 0) { equal = false; _recursivecompare(NULL, b, comparator); b = bit->next() ? bit->ptr() : NULL; } else // keys are equal { if (!_recursivecompare(a, b, comparator)) equal = false; a = ait->next() ? ait->ptr() : NULL; b = bit->next() ? bit->ptr() : NULL; } } // finish up if one side is bigger than the other while (a != NULL) { equal = false; _recursivecompare(a, NULL, comparator); a = ait->next() ? ait->ptr() : NULL; } while (b != NULL) { equal = false; _recursivecompare(NULL, b, comparator); b = bit->next() ? bit->ptr() : NULL; } delete ait; delete bit; return equal; } wvstreams-4.6.1/uniconf/unifiltergen.cc0000644000175000001440000000601711036722347017246 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen framework to simplify writing filtering generators. */ #include "unifiltergen.h" /***** UniFilterGen *****/ UniFilterGen::UniFilterGen(IUniConfGen *inner) : xinner(NULL) { setinner(inner); } UniFilterGen::~UniFilterGen() { IUniConfGen *gen = xinner; setinner(NULL); WVRELEASE(gen); } void UniFilterGen::setinner(IUniConfGen *inner) { if (xinner) xinner->del_callback(this); xinner = inner; if (xinner) xinner->add_callback(this, wv::bind(&UniFilterGen::gencallback, this, _1, _2)); } bool UniFilterGen::keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key) { // by default, don't rename the key mapped_key = unmapped_key; return true; } bool UniFilterGen::reversekeymap(const UniConfKey &mapped_key, UniConfKey &unmapped_key) { // by default, don't rename the key unmapped_key = mapped_key; return true; } void UniFilterGen::commit() { if (xinner) xinner->commit(); } bool UniFilterGen::refresh() { if (xinner) return xinner->refresh(); else return false; } void UniFilterGen::prefetch(const UniConfKey &key, bool recursive) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) xinner->prefetch(mapped_key, recursive); } WvString UniFilterGen::get(const UniConfKey &key) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) return xinner->get(mapped_key); else return WvString::null; } void UniFilterGen::flush_buffers() { if (xinner) xinner->flush_buffers(); } void UniFilterGen::set(const UniConfKey &key, WvStringParm value) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) xinner->set(mapped_key, value); } void UniFilterGen::setv(const UniConfPairList &pairs) { if (xinner) xinner->setv(pairs); } bool UniFilterGen::exists(const UniConfKey &key) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) return xinner->exists(mapped_key); else return false; } bool UniFilterGen::haschildren(const UniConfKey &key) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) return xinner->haschildren(mapped_key); else return false; } bool UniFilterGen::isok() { if (xinner) return xinner->isok(); else return false; } UniConfGen::Iter *UniFilterGen::iterator(const UniConfKey &key) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) return xinner->iterator(mapped_key); else return NULL; } UniConfGen::Iter *UniFilterGen::recursiveiterator(const UniConfKey &key) { UniConfKey mapped_key; if (xinner && keymap(key, mapped_key)) return xinner->recursiveiterator(mapped_key); else return NULL; } void UniFilterGen::gencallback(const UniConfKey &key, WvStringParm value) { UniConfKey unmapped_key; if (xinner && reversekeymap(key, unmapped_key)) delta(unmapped_key, value); } wvstreams-4.6.1/uniconf/tests/0000755000175000001440000000000011260431131015365 5ustar wlachuserswvstreams-4.6.1/uniconf/tests/conftest.cc0000644000175000001440000003260111036722347017540 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for the new, hierarchical WvConfEmu. */ #include "wvlog.h" #include "wvlogrcv.h" #include "wvdiriter.h" #include "wvconfemu.h" #include "wvfile.h" #include "wvtclstring.h" #include "uniconf.h" #include "strutils.h" #include "uniconfroot.h" #include "uniconftree.h" #include "uniconfgen.h" #include static void copyall(UniConf &src, UniConf &dest) { UniConf::RecursiveIter it(src); for (it.rewind(); it.next(); ) { WvString value(it->getme()); if (value.isnull()) continue; //wverr->print("set: \"%s\" = \"%s\"\n", it->fullkey(), value); dest[it->fullkey()].setme(value); //wverr->print("get: \"%s\"\n", dest[it->fullkey()].get()); } } #if 0 class HelloGen : public UniConfGen { public: WvString defstr; int count; HelloGen(WvStringParm _def = "Hello World") : UniConfGen(WvString("hello:%s", _def)), defstr(_def) { count = 0; } virtual void update(UniConf *&h); }; void HelloGen::update(UniConf *&h) { wvcon->print("Hello: updating %s\n", h->fullkey()); h->setvalue(WvString("%s #%s", defstr, ++count)); h->dirty = false; h->obsolete = false; h->waiting = false; } #endif // FIXME: This class *REALLY* should be merged out. #if 0 class UniConfFileTreeGen : public UniConfGen { public: WvString basedir; WvLog log; UniConfValueTree root; UniConfFileTreeGen(WvStringParm _basedir); virtual ~UniConfFileTreeGen() { } /***** Overridden members *****/ virtual bool refresh(); virtual WvString get(const UniConfKey &key); virtual bool exists(const UniConfKey &key); virtual bool haschildren(const UniConfKey &key); virtual void set(const UniConfKey &key, WvStringParm) { } virtual Iter *iterator(const UniConfKey &key); private: UniConfValueTree *maketree(const UniConfKey &key); class NodeIter; }; class UniConfFileTreeGen::NodeIter : public UniConfFileTreeGen::Iter { protected: UniConfValueTree::Iter xit; public: NodeIter(UniConfValueTree &node) : xit(node) { } /***** Overridden methods *****/ virtual void rewind() { xit.rewind(); } virtual bool next() { return xit.next(); } virtual UniConfKey key() const { return xit->key(); } }; UniConfFileTreeGen::UniConfFileTreeGen(WvStringParm _basedir) : basedir(_basedir), log("FileTree", WvLog::Info), root(NULL, UniConfKey::EMPTY, "") { log(WvLog::Notice, "Creating a new FileTree based on '%s'.\n", basedir); } bool UniConfFileTreeGen::refresh() { WvString filename("%s%s", basedir, key); struct stat statbuf; bool exists = lstat(filename.cstr(), &statbuf) == 0; UniConfValueTree *node = root.find(key); if (!exists) { if (node != &root) delete node; return true; } node = maketree(key); node->zap(); WvDirIter dirit(filename, true); UniConfKey dirkey(filename); for (dirit.rewind(); dirit.next(); ) { log(WvLog::Debug2, "."); UniConfKey filekey(dirit->fullname); filekey = filekey.removefirst(dirkey.numsegments()); maketree(filekey); } return true; } WvString UniConfFileTreeGen::get(const UniConfKey &key) { // check the cache UniConfValueTree *node = root.find(key); if (node && !node->value().isnull()) return node->value(); // read the file and extract the first non-black line WvString filename("%s%s", basedir, key); WvFile file(filename, O_RDONLY); char *line; for (;;) { line = NULL; if (!file.isok()) break; line = file.blocking_getline(-1); if (!line) break; line = trim_string(line); if (line[0]) break; } if (file.geterr()) { log("Error reading %s: %s\n", filename, file.errstr()); line = ""; } if (!node) node = maketree(key); WvString value(line); value.unique(); node->setvalue(value); file.close(); return value; } bool UniConfFileTreeGen::exists(const UniConfKey &key) { UniConfValueTree *node = root.find(key); if (!node) { refresh(); node = root.find(key); } return node != NULL; } bool UniConfFileTreeGen::haschildren(const UniConfKey &key) { UniConfValueTree *node = root.find(key); if (!node || !node->haschildren()) { refresh(key, UniConfDepth::CHILDREN); node = root.find(key); } return node != NULL && node->haschildren(); } UniConfFileTreeGen::Iter *UniConfFileTreeGen::iterator(const UniConfKey &key) { if (haschildren(key)) { UniConfValueTree *node = root.find(key); if (node) return new NodeIter(*node); } return new NullIter(); } UniConfValueTree *UniConfFileTreeGen::maketree(const UniConfKey &key) { // construct a node for the file with a null value UniConfValueTree *node = &root; UniConfKey::Iter it(key); it.rewind(); while (it.next()) { UniConfValueTree *prev = node; node = node->findchild(it()); if (!node) node = new UniConfValueTree(prev, it(), WvString::null); } return node; } #endif int main() { WvLog log("conftest", WvLog::Info); WvLog quiet("*", WvLog::Debug1); // try Debug5 for lots of messages WvLogConsole rcv(2, WvLog::Debug4); log("A wvconf instance is %s/%s/%s bytes long.\n", sizeof(WvConf), sizeof(WvConfigSection), sizeof(WvConfigEntry)); log("A stringlist is %s bytes long.\n", sizeof(WvStringList)); log("A UniConfValueTree instance is %s bytes long.\n", sizeof(UniConfValueTree)); log("A UniConfKey instance is %s bytes long.\n", sizeof(UniConfKey)); { wvcon->print("\n\n"); log("-- Key test begins\n"); UniConfKey key("/a/b/c/d/e/f/ghij////k/l/m/"); UniConfKey key2(key), key2b(key, key); UniConfKey key3(key.removefirst(5)); UniConfKey key4(key.removefirst(900)); // FIXME: we're just barely scratching the surface here! log("key : %s\n" "key2: %s (%s, %s)\n" "key2b: %s (%s)\n" "key3: %s\n" "key4: %s\n", key, key2, key2.range(1, key2.numsegments()-1), key2.range(0, 0), key2b, key2b.numsegments(), key3, key4); log("keyiter test 2b: "); UniConfKey::Iter i(key2b); for (i.rewind(); i.next(); ) log("'%s' ", *i); log("\n"); } { wvcon->print("\n\n"); log("-- Basic config test begins\n"); UniConfRoot cfg("temp:"); cfg["/foo/blah/weasels"].setme("chickens"); cfg["foo"]["pah"]["meatballs"].setmeint(6); assert(cfg["/foo/blah"].haschildren()); assert(!cfg["/foo/blah/weasels"].haschildren()); UniConf x(cfg["snort/fish/munchkins"]); x["big/bad/weasels"].setmeint(7); x["foo"].setme("sneeze"); x["blue"].setme("sneeze"); x["true"].setme("sneeze"); { log("get() test:\n"); log(" '%s' '%s' '%s' '%s'/'%s' '%s'\n", cfg["foo/blah/weasels"].getme(), cfg["foo/blah"].getme(), cfg["foo"].getme(), cfg[""].getme(), cfg[UniConfKey::EMPTY].getme(), cfg.getme() ); } { log("Toplevel dump:\n"); UniConf::Iter i(cfg); for (i.rewind(); i.next(); ) quiet.print("'%s' = '%s'\n", i->key(), i->getme()); } log("Config dump:\n"); cfg.dump(quiet, true); } { wvcon->print("\n\n"); log("-- Simple deletion test begins\n"); UniConfRoot cfg("temp:"); UniConf a(cfg["admins"]), a1(a["1"]), a2(a["2"]); a1.setme("11"); a2.setme("22"); assert(a.haschildren()); assert(!a2.haschildren()); a1.remove(); assert(a.exists()); assert(!a1.exists()); assert(a2.exists()); assert(a.haschildren()); assert(!a1.haschildren()); assert(!a2.haschildren()); } #if 0 { wvcon->print("\n\n"); log("-- Inheritence test begins\n"); UniConf cfg, *h; cfg.set("/default/users/*/comment", "defuser comment"); cfg.set("/default/users/bob/comment", "defbob comment"); // should be (nil)/(nil) log("Old comment settings are: %s/%s\n", cfg.get("/users/randomperson/comment"), cfg.get("/users/bob/comment")); cfg["/users"].defaults = &cfg["/default/users"]; // should be defuser comment h = cfg["/users/randomperson/comment"].find_default(); log("Default for randomperson(%s): '%s'\n", h ? h->fullkey() : "", h ? h->get() : WvString("NONE")); // should be defbob comment h = cfg["/users/bob/comment"].find_default(); log("Default for bob: '%s'\n", h ? h->get() : WvString("NONE")); // should be defuser comment/defbob comment log("New comment settings are: %s/%s\n", cfg.get("/users/noperson/comment"), cfg.get("/users/bob/comment")); cfg.set("/users/bob/someone/comment", "fork"); log("Config dump 2:\n"); cfg.dump(quiet); } #endif #if 0 { wvcon->print("\n\n"); log("-- Hello Generator test begins\n"); UniConf cfg; cfg["/hello"].mount(new HelloGen("Hello world")); cfg["/bonjour"].mount(new HelloGen("Bonjour tout le monde!")); cfg.get("/bonjour/1"); cfg.get("/bonjour/2"); cfg.get("/bonjour/3"); cfg.get("/hello/3"); cfg.get("/hello/2"); cfg.get("/hello/1"); log("Config dump:\n"); cfg.dump(quiet); } #endif #if 0 { wvcon->print("\n\n"); log("-- FileTree test begins\n"); UniConfRoot root(new UniConfFileTreeGen("/etc/modutils")); UniConf cfg(root); log("Config dump:\n"); cfg.dump(quiet); } #endif { wvcon->print("\n\n"); log("-- IniFile test begins\n"); UniConfRoot root; UniConf cfg(root); UniConf cfg2(cfg["/weaver ini test"]); cfg.mount("readonly:ini:test.ini"); cfg2.mount("readonly:ini:/tmp/weaver.ini"); log("Config dump:\n"); cfg.dump(quiet); } { wvcon->print("\n\n"); log("-- Defaults test begins\n"); log("Setting up config file...\n"); UniConfRoot root("default:ini:uniconf.ini"); root["*"].setme("go wild, bay-be!"); root["*/drheld/whee"].setme("3"); root["users/*/chicken/bork"].setme("b0rk3n g00dn3ss"); root["users/*/chicken/*"].setme("happy"); root["users/apenwarr"].setme("ooga booga"); root["users/apenwarr/chicken/hammer"].setme("smashy!"); root["users/apenwarr/ftp"].setme("1"); root["wild/*/*/blink"].setme("*1"); root["wild/*/*/blank"].setme("*2"); root["wild/*/*/plunk"].setme("*3"); root.commit(); log("Starting tests...\n"); WvString result = root["stupidthing"].getme(); log("/stupidthing = %s (should = go wild, bay-be!)\n", result); result = root["home/drheld"]["whee"].getme(); log("/home/drheld/whee = %s (should = 3)\n", result); result = root["/users/apenwarr/chicken/bork"].getme(); log("/users/apenwarr/chicken/bork = %s (should = b0rk3n g00dn3ss)\n", result); result = root["/users/silly/chicken/die"].getme(); log("/users/silly/chicken/die = %s (should = happy)\n", result); result = root["/wild/foo/bar/blink"].getme("outtaspace"); log("/wild/foo/bar/blink = %s (should = bar)\n", result); result = root["/wild/foo/bar/blank"].getme("outtaspace"); log("/wild/foo/bar/blank = %s (should = foo)\n", result); result = root["/wild/foo/bar/plunk"].getme("outtaspace"); log("/wild/foo/bar/plunk = %s (should = outtaspace)\n", result); } { wvcon->print("\n\n"); log("-- Generator List test begins\n"); UniConfRoot root("list: readonly:ini:test.ini ini:test2.ini"); root["chickens"]["boob"].setme("not_frank"); log("[chickens][bob] = %s\n", root["chickens"]["bob"].getme()); log("[chickens][boob] = %s\n", root["chickens"]["boob"].getme()); root["chickens"]["bob"].setme("gooooblefish"); root["chickens"]["boob"].setme("I like to wear funny hats"); log("Setting [chickens][bob] = gooooblefish **(read only on top)\n"); log("Setting [chickens][boob] = I like to wear funny hats\n"); log("[chickens][bob] = %s\n", root["chickens"]["bob"].getme()); log("[chickens][boob] = %s\n", root["chickens"]["boob"].getme()); root.commit(); } { wvcon->print("\n\n"); log("-- IniFile test2 begins\n"); UniConfRoot root; UniConf cfg(root); UniConf h1(cfg["/1"]); UniConf h2(cfg["/"]); h1.mount("ini:test.ini", true); h2.mount("ini:test2.ini", true); log("Partial config dump (branch 1 only):\n"); h1.dump(quiet); log("Trying to save unchanged branches:\n"); cfg.commit(); UniConfRoot newroot; UniConf newcfg(newroot); UniConf newh1(newcfg["/1"]); UniConf newh2(newcfg["/"]); newh1.mount("ini:test.ini.new", false); newh2.mount("ini:test2.ini.new", false); copyall(cfg, newcfg); newh1.dump(quiet); log("Trying to save copy:\n"); newcfg.commit(); log("Changing some data:\n"); if (!newh1["big/fat/bob"].exists()) newh1["big/fat/bob"].setmeint(0); newh1["big/fat/bob"].setmeint(newh1["big/fat/bob"].getmeint() + 1); newh1["chicken/hammer\ndesign"].setme("simple test"); newh1["chicken/whammer/designer\\/code\nweasel"].setme( "this\n\tis a test "); log("Full config dump:\n"); newcfg.dump(quiet); log("Saving changed copy:\n"); newcfg.commit(); } return 0; } wvstreams-4.6.1/uniconf/tests/unisecuretest.cc0000644000175000001440000002624211036722347020621 0ustar wlachusers#include #include #include #include #include #include #include #include /** * FIXME: this doesn't test the following: * - exec permissions */ /** * Setup/teardown */ struct Objects { UniConfRoot root; UniConf u; UniPermGen *p; UniSecureGen *s; Objects(UniPermGen *_p, UniSecureGen *_s) : u(root), p(_p), s(_s) { u.mountgen(s); } }; Objects *setup(WvStringParm perms) { // populate secure.ini { // FIXME: should maybe not overwrite this if it exists unlink("secure.ini"); UniConfRoot root; UniConf u(root); u.mount("default:ini:secure.ini"); u["nondef/*"].setme("*1"); u["defaults/*/*"].setme("*1"); u["inherited/*"].setme("*1"); u.commit(); } // create and populate the perms gen UniPermGen *p = new UniPermGen(perms); UniSecureGen *s = new UniSecureGen("default:ini:secure.ini", p); // defaults tree has owner group set with a pattern p->setowner("defaults/*/*", "clampy"); p->setgroup("defaults/*/*", "cloggers"); // inherited tree inherits everything p->setowner("inherited", "clampy"); p->setgroup("inherited", "cloggers"); p->chmod("inherited", 0777); // now chmod each key in nondef/NNN and defaults/*/NNN to 0NNN, and set // the owner/group of nondef/* directly for (int user = 0; user < 8; user++) { for (int group = 0; group < 8; group++) { for (int world = 0; world < 8; world++) { WvString key("%s%s%s", user, group, world); WvString nondef("nondef/%s", key); WvString defaults("defaults/*/%s", key); p->setowner(nondef, "clampy"); p->setgroup(nondef, "cloggers"); p->chmod(nondef, user, group, world); p->chmod(defaults, user, group, world); } } } // all access to the defaults/2 tree should fail due to missing exec p->setexec("defaults/2", UniPermGen::USER, false); p->setexec("defaults/2", UniPermGen::GROUP, false); p->setexec("defaults/2", UniPermGen::WORLD, false); p->commit(); // create the uniconf obj and mount the generators Objects *o = new Objects(p, s); return o; } void teardown(Objects *o) { delete o; unlink("secure.ini"); } /** * Headers/footers */ void printheader(WvStringParm h) { WvString header("\n\nTEST %s", h); wvcon->print("%s\n",header); for (size_t i = 0; i < header.len(); i++) wvcon->print("="); wvcon->print("\n\n"); } void printfooter(bool pass) { if (pass) wvcon->print("\n***** PASSED *****\n\n"); else wvcon->print("\n///// FAILED /////\n\n"); } void printfinal(bool pass) { WvString footer("=== TEST SUITE %s ===", pass ? "PASSED" : "FAILED"); wvcon->print("%s\n",footer); } /** * Test get/set of a single key */ bool testaget(const UniConf &u, WvStringParm prefix, WvStringParm key, bool expectsucc) { WvString expect = expectsucc ? WvString(key) : WvString("nothing"); WvString got = u[prefix][key].getme("nothing"); if (expect == got) wvcon->print("OK - %s/%s: got \"%s\"\n", prefix, key, got); else wvcon->print("FAIL - %s/%s: expected \"%s\", got \"%s\"\n", prefix, key, expect, got); return (expect == got); } bool testaset(const UniConf &u, WvStringParm prefix, WvStringParm key, bool expectsucc) { WvString val = "brandnew"; WvString orig = u[prefix][key].getme(); WvString expect = expectsucc ? val : orig; u[prefix][key].setme(val); WvString got = u[prefix][key].getme(); if (expect == got) wvcon->print("OK - set %s/%s: got \"%s\"\n", prefix, key, got); else wvcon->print("FAIL - set %s/%s: expected \"%s\", got \"%s\"\n", prefix, key, expect, got); return (got == expect); } /** * Test get/set of a single key in 4 branches (nondef / foo, defaults / 1 / * foo, defaults / 2 / foo, inherited / foo) */ bool testget(const UniConf &u, WvStringParm key, bool expectsucc, bool noperms) { bool pass = true; // no default pass = testaget(u, "nondef", key, expectsucc) && pass; if (!noperms) { // with default pass = testaget(u, "defaults/1", key, expectsucc) && pass; // drilldown pass = testaget(u, "defaults/2", key, false) && pass; // inherited pass = testaget(u, "inherited", key, true) && pass; } return pass; } bool testset(const UniConf &u, WvStringParm key, bool expectsucc, bool noperms) { bool pass = true; // no default pass = testaset(u, "nondef", key, expectsucc) && pass; if (!noperms) { // with default pass = testaset(u, "defaults/1", key, expectsucc) && pass; // drilldown pass = testaset(u, "defaults/2", key, false) && pass; // inherited pass = testaset(u, "inherited", key, true) && pass; } return pass; } /** * Test a variety of keys for the given permissions */ bool testreadable(const UniConf &u, bool none, bool o, bool g, bool w, bool og, bool ow, bool gw, bool ogw, bool noperms = false) { bool pass = true; //readable: 4567 //unreadable: 0123 // all unreadable pass = testget(u, "000", none, noperms) && pass; pass = testget(u, "123", none, noperms) && pass; // user readable pass = testget(u, "400", o, noperms) && pass; pass = testget(u, "700", o, noperms) && pass; pass = testget(u, "512", o, noperms) && pass; // group readable pass = testget(u, "040", g, noperms) && pass; pass = testget(u, "070", g, noperms) && pass; pass = testget(u, "152", g, noperms) && pass; // world readable pass = testget(u, "004", w, noperms) && pass; pass = testget(u, "007", w, noperms) && pass; pass = testget(u, "236", w, noperms) && pass; // user, group readable pass = testget(u, "440", og, noperms) && pass; pass = testget(u, "770", og, noperms) && pass; pass = testget(u, "561", og, noperms) && pass; // user, world readable pass = testget(u, "404", ow, noperms) && pass; pass = testget(u, "707", ow, noperms) && pass; pass = testget(u, "625", ow, noperms) && pass; // group, world readable pass = testget(u, "044", gw, noperms) && pass; pass = testget(u, "077", gw, noperms) && pass; pass = testget(u, "265", gw, noperms) && pass; // all readable pass = testget(u, "444", ogw, noperms) && pass; pass = testget(u, "777", ogw, noperms) && pass; pass = testget(u, "465", ogw, noperms) && pass; return pass; } /** Make sure this is called last - it updates the keys */ bool testwriteable(const UniConf &u, bool none, bool o, bool g, bool w, bool og, bool ow, bool gw, bool ogw, bool noperms = false) { bool pass = true; //writeable: 2367 //unwriteable: 0145 //FIXME: we never test writeable but not readable because it's not //convenient // all unwriteable pass = testset(u, "000", none, noperms) && pass; pass = testset(u, "145", none, noperms) && pass; // user writeable pass = testset(u, "700", o, noperms) && pass; pass = testset(u, "614", o, noperms) && pass; // group writeable pass = testset(u, "070", g, noperms) && pass; pass = testset(u, "164", g, noperms) && pass; // world writeable pass = testset(u, "007", w, noperms) && pass; pass = testset(u, "516", w, noperms) && pass; // user, group writeable pass = testset(u, "770", og, noperms) && pass; pass = testset(u, "661", og, noperms) && pass; // user, world writeable pass = testset(u, "707", ow, noperms) && pass; pass = testset(u, "646", ow, noperms) && pass; // group, world writeable pass = testset(u, "077", gw, noperms) && pass; pass = testset(u, "566", gw, noperms) && pass; // all writeable pass = testset(u, "777", ogw, noperms) && pass; pass = testset(u, "666", ogw, noperms) && pass; return pass; } /** * Main test suite */ int main(int argc, char **argv) { WvLogConsole cons(2, WvLog::Debug4); WvString ini("ini:secure.ini"); bool allpassed = true; { printheader("DEFAULT PERMISSIONS"); Objects *o = setup("null"); /** All reads succeed, all writes fail */ bool pass = true; pass = testreadable(o->u, true, true, true, true, true, true, true, true, true) && pass; pass = testwriteable(o->u, false, false, false, false, false, false, false, false, true) && pass; teardown(o); printfooter(pass); allpassed = pass && allpassed; } { printheader("OWNER, GROUP MATCH"); Objects *o = setup("temp"); UniPermGen::Credentials c; c.user = "clampy"; c.groups.add(new WvString("cloggers"), true); o->s->setcredentials(c); /** ---, -g-, --w, -gw fail; o--, og-, o-w, ogw succeed */ bool pass = true; pass = testreadable(o->u, false, true, false, false, true, true, false, true) && pass; pass = testwriteable(o->u, false, true, false, false, true, true, false, true) && pass; teardown(o); printfooter(pass); allpassed = pass && allpassed; } { printheader("OWNER MATCHES BUT NOT GROUP"); Objects *o = setup("temp"); UniPermGen::Credentials c; c.user = "clampy"; c.groups.add(new WvString("froggers"), true); o->s->setcredentials(c); /** ---, -g-, --w, -gw fail; o--, og-, o-w, ogw succeed */ bool pass = true; pass = testreadable(o->u, false, true, false, false, true, true, false, true) && pass; pass = testwriteable(o->u, false, true, false, false, true, true, false, true) && pass; teardown(o); printfooter(pass); allpassed = pass && allpassed; } { printheader("GROUP MATCHES BUT NOT OWNER"); Objects *o = setup("temp"); UniPermGen::Credentials c; c.user = "stumpy"; c.groups.add(new WvString("cloggers"), true); o->s->setcredentials(c); /** ---, o--, --w, o-w fail; -g-, og-, -gw, ogw succeed */ bool pass = true; pass = testreadable(o->u, false, false, true, false, true, false, true, true) && pass; pass = testwriteable(o->u, false, false, true, false, true, false, true, true) && pass; teardown(o); printfooter(pass); allpassed = pass && allpassed; } { printheader("OWNER, GROUP DON'T MATCH"); Objects *o = setup("temp"); UniPermGen::Credentials c; c.user = "stumpy"; c.groups.add(new WvString("froggers"), true); o->s->setcredentials(c); /** ---, o--, -g-, og- fail; -w, o-w, -gw, ogw succeed */ bool pass = true; pass = testreadable(o->u, false, false, false, true, false, true, true, true) && pass; pass = testwriteable(o->u, false, false, false, true, false, true, true, true) && pass; teardown(o); printfooter(pass); allpassed = pass && allpassed; } printfinal(allpassed); } wvstreams-4.6.1/uniconf/tests/uniclienttimingtest.cc0000644000175000001440000000444611036722347022023 0ustar wlachusers// Test client for the uniconf daemon /** * FIXME: This test case is not as useful at it could be because: * 1) it only tests a very small subset of features * 2) it does not setup / teardown its environment explicitly */ #include "wvstream.h" #include "uniconfroot.h" #include "wvlogrcv.h" int alarms[] = { 10, 100, 1000, 10000, 10000, 10000, -1 }; class TestStream : public WvStream { public: TestStream(const UniConf &_uniconf) : WvStream(), uniconf(_uniconf), stage(0), done(false), passed(true) { alarm(0); } bool check(WvString test, WvString expected) { WvString value(uniconf[test].getme()); if (value == expected) { wvcon->print("OK - %s: got \"%s\"\n", test, value); return true; } else { wvcon->print("FAIL - %s: expected \"%s\", got \"%s\"\n", test, expected, value); return false; } } void run_test() { bool pass = check("chickens/bob", "goof"); if (pass) pass = check("users/apenwarr/ftp", "1"); if (!pass) { passed = false; done = true; } } virtual void execute() { WvStream::execute(); if (alarm_was_ticking) { run_test(); if (alarms[stage] == -1) done = true; else alarm(alarms[stage]); stage++; } } virtual bool isok() const { return !done; } public: const UniConf uniconf; unsigned int stage; bool done; bool passed; }; void usage(const char *name) { wvcon->print("%s usage:\n", name); wvcon->print("%s [-h]\n", name); wvcon->print("\t-h - display this message\n"); exit(0); } int main(int argc, char **argv) { WvString location("tcp:localhost:4111"); if (argc == 2 && !strcasecmp(argv[1], "-h")) { usage(argv[0]); } WvLogConsole clog(1, WvLog::Debug5); UniConfRoot root(location); TestStream t(root); while (t.isok()) if (t.select(-1)) t.callback(); if (t.passed) wvcon->print("\n***** PASSED *****\n\n"); else wvcon->print("\n///// FAILED /////\n\n"); } wvstreams-4.6.1/uniconf/tests/inttest.ini0000644000175000001440000000026311036722347017576 0ustar wlachusers[bools] true = true yes = yes on = on enabled = enabled false = false no = no off = off disabled = disabled [ints] foo = 0 bar = 1 baz = -1 boffle = 42_is_the_answer bluh = bluh wvstreams-4.6.1/uniconf/tests/unimem.cc0000644000175000001440000000332711036722347017210 0ustar wlachusers#include "uniconfroot.h" #include class Report { public: const char *before; void ps() { system(WvString("ps -o pid,sz,vsz,rss,trs,drs,dsiz,cmd %s", getpid())); } Report() { before = (const char *)sbrk(0); ps(); } void go() { const char *after = (const char *)sbrk(0); ps(); printf("%p, %p, %ld\n", before, after, (long)(after-before)); } }; int main() { printf("uniconfvaluetree: %d bytes\n", sizeof(UniConfValueTree)); printf("wvstring: %d bytes\n", sizeof(WvString)); Report r; int mode = 2; switch (mode) { case -1: { UniConfRoot uni; r.go(); uni.mount("ini:/tmp/dns.ini2", true); r.go(); system("touch /tmp/dns.ini2"); uni.refresh(); r.go(); system("touch /tmp/dns.ini2"); uni.refresh(); r.go(); for (int x = 0; x < 1e8; x++) ; system("touch /tmp/dns.ini2"); uni.refresh(); r.go(); } break; case 0: { UniConfRoot uni("temp:"); WvString s("this is a big long line with a really big " "long string involved in it somehow"); for (int i = 0; i < 18000; i++) uni.xset(WvString("blah/pah/%s", i), s.edit()); uni.commit(); r.go(); uni.remove(); uni.commit(); r.go(); } break; case 1: { WvStringList l; WvString s("this is a big long line with a really big " "long string involved in it somehow"); WvString a[18000]; for (int i = 0; i < 18000; i++) l.append(&(a[i] = s), false); r.go(); } break; case 2: { UniConfRoot uni("unix:/tmp/foos"); r.go(); { UniConf::RecursiveIter i(uni); r.go(); } r.go(); } } r.go(); return 0; } wvstreams-4.6.1/uniconf/tests/uninoticetest.cc0000644000175000001440000000252711036722347020614 0ustar wlachusers#include "uniconfroot.h" #include "wvtr1.h" #include "wvistreamlist.h" /** * This test is mostly for using with the uniconf daemon to see what * recursive/nonrecursive notifications do under different settings. Just * netcat the uniconf server and run sets / deletes by hand and see what * notifications pop up. * * Fun for the whole family! */ class foo { public: UniConfCallback meow; void cb(int a, const UniConf &moo, const UniConfKey &goo) { fprintf(stderr, "Moo... '%d' - goo = %s (%s)\n", a, goo.printable().cstr(), moo[goo].getme().cstr()); moo.setme("whee"); } }; int main() { UniConfRoot r("tcp:localhost:4111"); bool silly = false; bool nonsilly = false; bool silly2 = false; bool nonsilly2 = false; r["key/bob"].add_setbool(&silly, false); r["key"].add_setbool(&nonsilly, false); r["key/bob"].add_setbool(&silly2, true); r["key"].add_setbool(&nonsilly2, true); foo thing; r["heh"].add_callback(0, wv::bind(&foo::cb, &thing, 3, _1, _2)); WvIStreamList l; while (true) { l.select(-1); wvcon->print("(normals) key: %s, key/bob: %s\n", nonsilly, silly); wvcon->print("(recurse) key: %s, key/bob: %s\n", nonsilly2, silly2); silly2 = nonsilly2 = false; silly = nonsilly = false; } return 0; } wvstreams-4.6.1/uniconf/tests/uniconfwvgentest.cc0000644000175000001440000000444011036722347021323 0ustar wlachusers#include "wvconf.h" #include "uniwvconfgen.h" #include "uniconfroot.h" #include "wvlog.h" WvLog mylog("WvGenTest"); int main() { WvConf *_cfg = new WvConf("../../configfile/tests/testfile.ini"); WvConf &cfg = *_cfg; const char *test_str; if (!cfg.isok()) { mylog("Could not load config file.\n"); return -1; } mylog("Starting with WvConf...\n"); wvcon->print("\n"); test_str = cfg.get("intl", "sLanguage", "**NOT THERE**"); mylog("[intl]sLanguage = %s\n", test_str); mylog("[blah]bork = %s\n", cfg.get("blah", "bork")); mylog("[blah]default = %s\n", cfg.get("blah", "default", "Nothing to see here... move on along...")); wvcon->print("\n"); if (!cfg.isok()) { mylog("Config file is now borked?\n"); return -1; } WvConfigSection *sect = cfg["intl"]; if (sect) { mylog("Iterating...\n"); WvConfigSection::Iter i(*sect); for (i.rewind(); i.next();) { mylog("Item: %s\n", i->name); } } wvcon->print("\n"); mylog("Now testing uniconf wrapper.\n"); wvcon->print("\n"); UniConfRoot root(new UniWvConfGen(_cfg)); mylog("[intl]sLanguage = %s\n", root["intl"]["sLanguage"].getme()); mylog("[blah]bork = %s\n", root["blah"]["bork"].getme()); mylog("[blah]default = %s\n", root["blah"]["default"].getme( "Nothing to see here... move on along...")); wvcon->print("\n"); mylog("Iterating...\n"); UniConfRoot::Iter i(root["intl"]); for (i.rewind(); i.next();) { mylog("Item: %s\n", i->key()); } wvcon->print("\n"); mylog("Now testing children / sets with uniconf wrapper.\n"); wvcon->print("\n"); root["Silly"]["Rabbit"].setme("Trix are for kids!"); mylog("Setting: [Silly]Rabbit = Trix are for kids!\n"); mylog("Reading: [Silly]Rabbit = %s\n", cfg.get("Silly", "Rabbit")); if (root["Blah"].haschildren()) mylog("[Blah] has children!\n"); if (root["Silly"].haschildren()) mylog("[Silly] has children!\n"); mylog("Removing [Silly]\n"); root["Silly"].remove(); if (root["Silly"].haschildren()) mylog("[Silly] has children!\n"); else mylog("[Silly] doesn't have children!\n"); return 0; } wvstreams-4.6.1/uniconf/tests/emutest.cc0000644000175000001440000000527511036722347017410 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for the WvConf emulation in UniConf. */ #define WVCONFEMU #include "uniconfroot.h" #ifdef WVCONFEMU #include "wvconfemu.h" #else #include "wvconf.h" #endif #include "wvlog.h" int main() { bool c1 = false, c2 = false, c3 = false; WvLog log("emutest", WvLog::Info); #ifdef WVCONFEMU UniConfRoot uniconf("ini:test2.ini.new"); WvConf cfg(uniconf); #else WvConf cfg("test2.ini.new"); #endif cfg.zap(); cfg.load_file("test2.ini"); cfg.add_setbool(&c1, "Users", ""); cfg.add_setbool(&c2, "", "Bob"); cfg.add_setbool(&c3, "Users", "Bob"); log("Test1a: '%s'\n", cfg.get("Users", "Webmaster", "foo")); log("Test1b: '%s'\n", cfg.get("Users", "Webmaster", NULL)); log("Test2a: '%s'\n", cfg.get("Users", "Zebmaster", "foo")); log("Test2b: '%s'\n", cfg.get("Users", "Zebmaster", NULL)); log("Single section dump:\n"); WvConfigSection *sect = cfg["tunnel vision routes"]; if (sect) { WvConfigEntryList::Iter i(*sect); for (i.rewind(); i.next(); ) log(" Found: '%s' = '%s'\n", i->name, i->value); } log("Section dump done.\n"); log("All-section dump:\n"); WvConfigSectionList::Iter i(cfg); for (i.rewind(); i.next(); ) { WvConfigSection § = *i; log(" Section '%s'\n", sect.name); WvConfigSection::Iter i2(sect); i2.rewind(); i2.next(); if (i2.cur()) log(" First entry: '%s'='%s'\n", i2->name, i2->value); } log("All-section dump done.\n"); // not interesting log("setting [Neener]Bobber=50\n"); cfg.setint("Neener", "Bobber", 50); log("ChangeBools: %s/%s/%s\n", c1, c2, c3); assert(!c1 && !c2 && !c3); // set to same value - no change event log("setting [Users]webmaster=NOLOGIN\n"); cfg.set("Users", "webmaster", "NOLOGIN"); log("ChangeBools: %s/%s/%s\n", c1, c2, c3); //assert(!c1 && !c2 && !c3); // should set c1 log("setting [users]Wimp=hello\n"); cfg.set("users", "Wimp", "hello"); log("ChangeBools: %s/%s/%s\n", c1, c2, c3); assert(c1 && !c2 && !c3); // should set c2 log("setting [groups]bob=hello\n"); cfg.set("groups", "bob", "hello"); log("ChangeBools: %s/%s/%s\n", c1, c2, c3); assert(c1 && c2 && !c3); // should set c3 log("setting [users]bob=hello\n"); cfg.set("users", "bob", "hello"); log("ChangeBools: %s/%s/%s\n", c1, c2, c3); assert(c1 && c2 && c3); //log("Number of entries in [Global]: %s\n", cfg["Global"]->count()); cfg.del_setbool(&c1, "Users", ""); cfg.del_setbool(&c2, "", "Bob"); cfg.del_setbool(&c3, "Users", "Bob"); return 0; } wvstreams-4.6.1/uniconf/tests/inttest.cc0000644000175000001440000000555011036722347017410 0ustar wlachusers// Test client for uniconf integers /** * FIXME: This test case does not test integers, or set up/tear down its * environment explicatly */ #include #include #include "wvtclstring.h" #include "wvunixsocket.h" #include "wvaddr.h" #include "uniconfroot.h" #include "uniclientgen.h" #include "wvtcp.h" void printheader(WvString h, WvString mountpoint) { WvString header("%s WITH MOUNTPOINT %s", h, mountpoint); wvcon->print("%s\n",header); for (size_t i = 0; i < header.len(); i++) wvcon->print("="); wvcon->print("\n\n"); } void printresult(bool pass) { if (pass) wvcon->print("\n***** PASSED *****\n\n"); else wvcon->print("\n///// FAILED /////\n\n"); } bool check(WvStringParm test, int value, int expected) { if (value == expected) { wvcon->print("OK - %s: got \"%s\"\n", test, value); return true; } else { wvcon->print("FAIL - %s: expected \"%s\", got \"%s\"\n", test, expected, value); return false; } } bool testgetabool(const UniConf &mainconf, WvStringParm key, bool expected) { UniConf conf(mainconf["bools"][key]); return check(conf.fullkey(), conf.getmeint(), expected); } bool testgetbools(const UniConf &mainconf) { bool pass = true; pass = testgetabool(mainconf, "true", true) && pass; pass = testgetabool(mainconf, "yes", true) && pass; pass = testgetabool(mainconf, "on", true) && pass; pass = testgetabool(mainconf, "enabled", true) && pass; pass = testgetabool(mainconf, "false", false) && pass; pass = testgetabool(mainconf, "no", false) && pass; pass = testgetabool(mainconf, "off", false) && pass; pass = testgetabool(mainconf, "disabled", false) && pass; return pass; } bool testgetanint(const UniConf &mainconf, WvStringParm key, int expected) { UniConf conf(mainconf["ints"][key]); return check(conf.fullkey(), conf.getmeint(), expected); } bool testgetints(const UniConf &mainconf) { bool pass = true; pass = testgetanint(mainconf, "foo", 0) && pass; pass = testgetanint(mainconf, "bar", 1) && pass; pass = testgetanint(mainconf, "baz", -1) && pass; pass = testgetanint(mainconf, "boffle", 42) && pass; pass = testgetanint(mainconf, "bluh", 0) && pass; return pass; } void usage(const char *name) { wvcon->print("%s usage:\n", name); wvcon->print("%s [-h]\n", name); wvcon->print("\t-h - display this message\n"); exit(0); } int main(int argc, char **argv) { WvString location("ini:inttest.ini"); WvString mountpoint(""); UniConfRoot root; UniConf mounted(root[mountpoint]); mounted.mount(location); printheader("TEST GETTING BOOLS", mountpoint); printresult(testgetbools(mounted)); printheader("TEST GETTING INTS", mountpoint); printresult(testgetints(mounted)); return 0; } wvstreams-4.6.1/uniconf/tests/simple2.ini0000644000175000001440000000033711036722347017461 0ustar wlachusers[section1] xa = 1 xb = 2 xc = 3 xd = 4 xe = 5 [section2] a2 = 1x b2 = 2x c2 = 3x [section3] * = default star a3/bog = alternative bog [section4] aa = 1111 bb = 2222 cc = 3333 dd = 4444 ee = 5555 [*] aaa = aaa from star wvstreams-4.6.1/uniconf/tests/uni.cc0000644000175000001440000001125311044160724016500 0ustar wlachusers#include "wvautoconf.h" #include "uniconfroot.h" #include "wvlogrcv.h" #include "strutils.h" #include "wvstringmask.h" #include "wvtclstring.h" #ifdef _WIN32 #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #pragma comment(linker, "/include:?UniIniGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A") #endif void usage() { fprintf(stderr, "Usage: uni [extra stuff...]\n" " where is one of:\n" " get - get the value of a key, with optional default\n" " set - set a key to the given value from the command line\n" " xset - set a key to the given value from stdin\n" " keys - list the subkeys of a key\n" " hkeys - list the subkeys of a key, their subkeys, etc\n" " xkeys - list keys that match a wildcard\n" " dump - list the subkeys/values of a key (key=value)\n" " hdump - list the subkeys/values recursively\n" " xdump - list keys/values that match a wildcard\n" " del - delete all subkeys\n" " help - this text\n" "\n" "You must set the UNICONF environment variable to a valid " "UniConf moniker.\n" "\n" "Report bugs to <" WVPACKAGE_BUGREPORT ">.\n"); } int main(int argc, char **argv) { WvLogConsole logcon(2, WvLog::Info); if (argc < 3) { usage(); return 3; } // note: we know cmd and arg1 are non-NULL, but arg2 may be the argv // terminator, which is a NULL. That has a special meaning for some // commands, like 'set', and is different from the empty string. const char *_cmd = argv[1], *arg1 = argv[2], *arg2 = argc > 3 ? argv[3] : NULL; WvString cmd(_cmd); strlwr(cmd.edit()); if (cmd == "help") { usage(); return 0; } const char *confuri = getenv("UNICONF"); if (!confuri) { fprintf(stderr, "%s: UNICONF environment variable not set!\n", argv[0]); return 2; } UniConfRoot cfg(confuri); if (!cfg.whichmount() || !cfg.whichmount()->isok()) { fprintf(stderr, "%s: can't connect to uniconf at '%s'\n", argv[0], confuri); return 5; } static const WvStringMask nasties("\r\n[]="); if (cmd == "get") { WvString val = cfg[arg1].getme(arg2); if (!val.isnull()) { fputs(val, stdout); //fflush(stdout); // shouldn't be necessary! return 0; // okay } else return 1; // not found and no default given } else if (cmd == "set") { cfg[arg1].setme(arg2); cfg.commit(); return 0; // always works } else if (cmd == "xset") { // like set, but read from stdin WvDynBuf buf; size_t len; char *cptr; while (wvcon->isok()) { cptr = (char *)buf.alloc(10240); len = wvcon->read(cptr, 10240); buf.unalloc(10240 - len); } cfg[arg1].setme(buf.getstr()); cfg.commit(); return 0; // always works } else if (cmd == "keys") { UniConf::Iter i(cfg[arg1]); for (i.rewind(); i.next(); ) wvcon->print("%s\n", wvtcl_escape(i->key(), WVTCL_NASTY_NEWLINES)); } else if (cmd == "hkeys") { UniConf sub(cfg[arg1]); UniConf::RecursiveIter i(sub); for (i.rewind(); i.next(); ) wvcon->print("%s\n", wvtcl_escape(i->fullkey(sub), WVTCL_NASTY_NEWLINES)); } else if (cmd == "xkeys") { UniConf::XIter i(cfg, arg1); for (i.rewind(); i.next(); ) wvcon->print("%s\n", wvtcl_escape(i->fullkey(cfg), WVTCL_NASTY_NEWLINES)); } else if (cmd == "dump") { // note: the output of this command happens to be compatible with // (can be read by) the 'ini' UniConf backend. UniConf::Iter i(cfg[arg1]); for (i.rewind(); i.next(); ) wvcon->print("%s = %s\n", wvtcl_escape(i->key(), nasties), wvtcl_escape(i->getme(""), nasties)); } else if (cmd == "hdump") { // note: the output of this command happens to be compatible with // (can be read by) the 'ini' UniConf backend. UniConf sub(cfg[arg1]); UniConf::RecursiveIter i(sub); for (i.rewind(); i.next(); ) wvcon->print("%s = %s\n", wvtcl_escape(i->fullkey(sub), nasties), wvtcl_escape(i->getme(""), nasties)); } else if (cmd == "xdump") { // note: the output of this command happens to be compatible with // (can be read by) the 'ini' UniConf backend. UniConf::XIter i(cfg, arg1); for (i.rewind(); i.next(); ) wvcon->print("%s = %s\n", wvtcl_escape(i->fullkey(cfg), nasties), wvtcl_escape(i->getme(""), nasties)); } else if (cmd == "del") { UniConf sub(cfg[arg1]); sub.remove(); cfg.commit(); } else { fprintf(stderr, "%s: unknown command '%s'!\n", argv[0], _cmd); return 4; } } wvstreams-4.6.1/uniconf/tests/simple.ini0000644000175000001440000000037411036722347017400 0ustar wlachusers[section0] a0 = 1 b0 = 2 c0 = 3 d0 = 4 e0 = 5 [section1] a = 1 b = 2 c = 3 d = 4 e = 5 [section2] a2 = 11 b2 = 22 c2 = 33 d2 = 44 e2 = 55 [section3] a3 = 111 b3 = 222 c3 = 333 d3 = 444 e3 = 555 [*] * = "random subkey" [*/*] bog = the standard bog wvstreams-4.6.1/uniconf/tests/unitest.sh0000755000175000001440000001614111077124114017430 0ustar wlachusers#!/bin/bash # Test various UniConf stuff using the 'uni' program. # # Usage: unitest.sh [section/number] # Where 'section/number' is the test section name or test number to run. # If not given, we run all tests from all sections. # export UNICONF PATH=".:$PATH" RUNWHICH="$1" # do you want to test the uniconfd, or just straight ini files? [ -z "$DAEMON" ] && DAEMON=0 # don't play with these TESTNUM=1 FAILS=0 SECT="" IFS=" " RECONFIG() { killall -q uniconfd killall -q -9 uniconfd rm -f $PWD/unisocket XDAEMON="$DAEMON" if [ "$1" = "--daemon" ]; then XDAEMON=1 shift fi if [ "$XDAEMON" != "1" ]; then UNICONF="$@" else echo "Starting UniConfDaemon." # FIXME: we should be able to avoid the 'sleep' here, but # WvDaemon is currently buggy in that it forks into the background # *before* it finishes running the daemon setup code. Ew. # # Furthermore, we can't actually use WvDaemon's fork-to-background # because it *also* does chdir("/") as part of that, which happens # before opening the ini file, which is expected to be in the current # directory. Anyway, same bug: chdir and fork *after* setup. ../daemon/uniconfd -lunix:$PWD/unisocket "$@" & sleep 1 UNICONF="unix:$PWD/unisocket" fi } TESTMATCH() { if [ -z "$RUNWHICH" \ -o "$SECT" = "$RUNWHICH" \ -o "$TESTNUM" = "$RUNWHICH" ]; then return 0 # true else return 1 # false fi } SECTION() { SECT="$1" shift TESTMATCH || return echo echo "Testing \"$@ ('$SECT')\" in unitest.sh:" } _check() { teststr=$(echo -n "$@" | perl -e '@a=<>; $_=join("",@a); s/[\n\t]/!!/mg; printf("%-30.30s", $_);') echo -n "! unitest.sh:$SECT:$TESTNUM $teststr " if [ "$@" ]; then echo "ok" else echo "FAILED" # echo -n "Failure: ($@)" | perl -pe 's/\n/!/mg;' echo FAILS=$(($FAILS + 1)) fi } check() { echo "ONE='$ONE'" echo "TWO='$TWO'" TESTMATCH && _check "$@" TESTNUM=$(($TESTNUM + 1)) } x() { echo " x: '$*'" TESTMATCH && ONE=$("$@" || { [ $? -gt 127 ] && echo "UNI DIED!"; }) } xx() { echo "xx: '$*'" TESTMATCH && TWO=$("$@" || { [ $? -gt 127 ] && echo "UNI DIED!"; }) check "$(echo "$ONE" | sort)" = "$(echo "$TWO" | sort)" } s() { TESTMATCH && ONE="$*" } ss() { TESTMATCH && TWO="$*" check "$(echo "$ONE" | sort)" = "$(echo "$TWO" | sort)" } SECTION tester "Testing the tester" check 1 = 1 check "1 1" = $(echo "1 1") s "1 2" ss "1 2" xx echo "1 2" x echo 1 "" 1 ss 1\ \ 1 s 1 2 3 ss 2 1 3 SECTION null "null generator tests" RECONFIG null: s xx uni get /a xx uni get /a/b RECONFIG --daemon null: # needs persistence xx uni set /a/b foo xx uni get /a/b SECTION temp "temp generator tests" RECONFIG temp: s xx uni get /a xx uni get /a/b RECONFIG --daemon temp: # needs persistence xx uni set /a/b foo s foo xx uni get /a/b SECTION ini "ini file tests" RECONFIG ini:simple.ini x uni get /section1/a ss 1 x uni get /section1/a/b ss x uni keys / ss section0 section1 section2 section3 \* x uni hkeys section2 ss a2 b2 c2 d2 e2 x uni dump section2 ss "a2 = 11" "b2 = 22" "c2 = 33" "d2 = 44" "e2 = 55" # FIXME: this test fails with the daemon, passes without! # It's related to the trailing slash. # #RECONFIG ini:simple2.ini # x uni hdump /section3/ #ss "a3 = {}" "* = default star" "a3/bog = alternative bog" SECTION list "list (try-alternatives) generator tests" RECONFIG "list: ini:simple.ini" s 1 xx uni get /section1/a s section0 section1 section2 section3 \* xx uni keys / RECONFIG "list: ini:simple2.ini ini:simple.ini" s 1 xx uni get /section1/a xx uni get /section1/xa s section0 section1 section2 section3 section4 \* xx uni keys / s a b c d e xa xb xc xd xe xx uni keys /section1 s a2 b2 c2 d2 e2 xx uni keys /section2 s "a2 = 1x" "b2 = 2x" "c2 = 3x" "d2 = 44" "e2 = 55" xx uni dump /section2 # FIXME: MOST OF THE FOLLOWING TESTS FAIL!!! if false; then SECTION default "Default (*/*) generator tests" RECONFIG "default: null:" s xx uni get /anything RECONFIG default:ini:simple.ini s 1 xx uni get /section1/a s "the standard bog" xx uni get /section1/a/bog s xx uni get /frog/snicker/bog # FIXME: no frog/snicker; bog shouldn't exist s a a/bog b b/bog c c/bog d d/bog e e/bog xx uni hkeys /section1 # FIXME: iter should list 'bog', but currently doesn't s xx uni get '/*/*/bog' # FIXME: stars should be hidden by the default: filter xx uni hkeys '/*' # FIXME: stars should be hidden by the default: filter # the list: directive here should make no difference at all. SECTION deflist "Default/list combination tests" base="ini:simple.ini" for uri in "default:$base" "list:default:$base" "default:list:$base"; do RECONFIG "$uri" s 111 xx uni get /section3/a3 s "the standard bog" xx uni get /section3/a3/bog # FIXME: this one fails ONLY with second uri!! s a a/bog b b/bog c c/bog d d/bog e e/bog xx uni keys section1 # FIXME: this one fails because plain default: fails done RECONFIG "default:list: ini:simple2.ini ini:simple.ini" s 1x xx uni get /section2/a2 s 1 xx uni get /section1/a s "default star" xx uni get /section3/anything s "random subkey" xx uni get /section2/anything SECTION wvconf "WvConf wrapper tests" RECONFIG wvconf:simple.ini s 5 xx uni get /section1/e s section0 section1 section2 section3 \* xx uni keys / # FIXME: iterating at the top level doesn't work s a b c d e xx uni keys /section1 s bog xx uni keys '*/*' s "the standard bog" xx uni get '/*/*/bog' # FIXME: 'keys' lists the key, but 'get' is blank! s \* \*/bog xx uni hkeys \* FILE=__junk.ini rm -f "$FILE" touch "$FILE" RECONFIG "wvconf:$FILE" s xx uni set /section/entry "string" s "string" xx uni get /section/entry # FIXME: this fails if DAEMON=0 rm -f "$FILE" fi # disable failing tests # FIXME: the cache needs much more thorough testing than these simple tests; # especially consider what happens on 'set' and if someone else writes to # the daemon you're using. SECTION cache "Caching tests" # FIXME: all of these fail, implying that the cache massively sucks. RECONFIG "cache:ini:simple2.ini" s "alternative bog" xx uni get /section3/a3/bog xx uni get /section3/a3/bog s section1 section2 section3 section4 \* xx uni keys / s \* a3 a3/bog xx uni hkeys /section3 RECONFIG "cache:list: ini:simple2.ini ini:simple.ini" s 1 xx uni get /section1/a xx uni get /section1/xa s section0 section1 section2 section3 section4 \* xx uni keys / s a b c d e xa xb xc xd xe xx uni keys /section1 s a2 b2 c2 d2 e2 xx uni keys /section2 s "a2 = 1x" "b2 = 2x" "c2 = 3x" "d2 = 44" "e2 = 55" xx uni dump /section2 RECONFIG --daemon "ini:simple2.ini" # daemon itself is non-cached UNICONF="cache:$UNICONF" # but cache the connection to the daemon s "alternative bog" xx uni get /section3/a3/bog xx uni get /section3/a3/bog s section1 section2 section3 section4 \* xx uni keys / s \* a3 a3/bog xx uni hkeys /section3 DAEMON= RECONFIG "null:" echo if [ "$FAILS" = 0 ]; then echo "All uniconf tests passed." exit 0 else echo "$FAILS uniconf tests failed!" exit 1 fi wvstreams-4.6.1/uniconf/tests/uniclientitertest.cc0000644000175000001440000000344211036722347021472 0ustar wlachusers// Test client for the uniconf daemon #include #include #include "wvtclstring.h" #include "wvunixsocket.h" #include "wvaddr.h" #include "uniconfroot.h" #include "uniclientgen.h" #include "wvtcp.h" #include "wvlogrcv.h" void printheader(WvString h, WvString mountpoint) { WvString header("\n\n%s WITH MOUNTPOINT %s", h, mountpoint); wvcon->print("%s\n",header); for (size_t i = 0; i < header.len(); i++) wvcon->print("="); wvcon->print("\n\n"); } void testnormaliter(const UniConf &mainconf) { UniConf::Iter i(mainconf); for (i.rewind(); i.next();) { wvcon->print("Key:%s has value:%s.\n", i->fullkey(), i->getme()); } } void testrecursiveiter(const UniConf &mainconf) { UniConf::RecursiveIter i(mainconf); for (i.rewind(); i.next();) { wvcon->print("Key:%s has value:%s.\n", i->fullkey(), i->getme()); } } int main(int argc, char **argv) { WvString mountpoint("/"); WvString location("tcp:localhost:4111"); WvLogConsole cons(2, WvLog::Debug4); for (int i = 0; i < 2; i++) { // Test a normal iterator { UniConfRoot root; UniConf mainconf(root); UniConf mounted(mainconf[mountpoint]); mounted.mount(location); printheader("TEST NORMAL ITERATORS", mountpoint); testnormaliter(mainconf); } // Test a recursive iterator { UniConfRoot root; UniConf mainconf(root); UniConf mounted(mainconf[mountpoint]); mounted.mount(location); printheader("TEST RECURSIVE ITERATORS", mountpoint); testrecursiveiter(mainconf); } mountpoint = "/orino"; } return 0; } wvstreams-4.6.1/uniconf/tests/unistress.cc0000644000175000001440000000144311036722347017752 0ustar wlachusers#include "uniconfroot.h" #include "wvstream.h" #include "wvtimeutils.h" int main(int argc, char **argv) { const char *mon = (argc > 1) ? argv[1] : "ini:/tmp/big.cfg"; wvcon->print("Using uniconf moniker '%s'\n", mon); UniConfRoot cfg(mon); UniConf c2(cfg["/uids"]); WvTime start; int count; while (1) { for (start = wvtime(), count = 0; msecdiff(wvtime(), start) < 5000; count++) { if (!cfg.whichmount() || !cfg.whichmount()->isok()) { wvcon->print("not isok! aborting.\n"); return 1; } UniConf::Iter i(c2);//cfg["/uids"]); for (i.rewind(); i.next(); ) { UniConf c(*i); WvString v(i._value()); } } wvcon->print("%s iters/sec (%s in 5ms)\n", count/5, count); } return 0; } wvstreams-4.6.1/uniconf/tests/uni.8.subst0000644000175000001440000000707111042636572017433 0ustar wlachusers'\" t .\" Worldvisions Weaver Software .\" Copyright (C) 1997 - 2004 Net Integration Technologies Inc. .TH UNI 8 "September 2004" "Uni #VERSION#" .SH NAME uni \- a program to interface with the UniConf configuration system .SH SYNOPSIS .B uni get .I KEY .RI [ DEFAULT ] .PP .B uni set .I KEY .RI [ VALUE ] .br .B uni xset .I KEY .RI [ VALUE ] .PP .B uni keys .I KEY .br .B uni hkeys .I KEY .br .B uni xkeys .I KEY .PP .B uni dump .I KEY .br .B uni hdump .I KEY .br .B uni xdump .I KEY .SH DESCRIPTION UniConf is the One True Configuration system that includes all the others because it has plugin backends .I and frontends. Or, less grandiosely, it's a lightweight, distributed, cacheable tree of strings. .PP .B uni is used to interface directly with the UniConf system. It's primary use is for diagnostic purposes, but it can be used to add UniConf support to shell scripts. .SH "ENVIRONMENT VARIABLE" .TP .I UNICONF Before using .BR uni , you must tell it which UniConf moinker you wish to query by setting this environment variable. .PP Monikers are used to contact UniConf back-ends, be they a .B uniconfd server, or a local file. For example, they could be: .RS 4 \(bu a filename .RI (ini: /var/lib/app/config.ini ), .br \(bu or a network address, .RI (tcp: open.nit.ca:4111 ). .RE .SH COMMANDS .TP get Retreive the .I VALUE associated with the provided .I KEY within the UniConf database. If a .I DEFAULT is provided, this will be returned if the .I KEY has no associated .IR VALUE . .TP set Assign the provided .I VALUE the the provided .IR KEY . UniConf provides no guarentee that the entry committed throughout the database. The next \(lqget\(rq command for this .I KEY may not return the most recently \(lqset\(rq value due to caching, or the existance of a read-only generator. .TP xset Assign, to the provided .IR KEY , the contents of the standard-input stream. Use this command to pipe information into the UniConf database. .TP keys List all the sub-keys contained within the provided .IR KEY . .TP hkeys List all the sub-keys, recursively, contained within the provided .IR KEY . Since any .I KEY may contain sub-keys, UniConf provides no guarentee that there are no circular references. .TP xkeys List all the sub-keys contained within the provided .IR KEY , which can contain wildcards. See the .B WILDCARDS section. .TP dump List all the sub-keys and their values, contained within the provided .IR KEY . .TP hdump List all the sub-keys and their values, recursively, contained within the provided .IR KEY . .TP xdump List all the sub-keys and their values, contained within the provided .IR KEY , which can contain wildcards. .SH WILDCARDS A .I KEY looks just like a normal slash-delimited path. The root of the UniConf tree has a .I KEY named .RB \(lq / \(rq. Sub-keys can be accessed by names such as .RB \(lq /software/myapp/version \(rq. .PP With wildcards, you can access more than one key at a time. .TP * To access a sub-key within any one level of keys, use the asterix like so: .RB \(lq /software/*/version \(rq. This retrieves all keys of .RB \(lq version \(rq that are one level beneath .RB \(lq /software \(rq. .TP .RB ... To access a sub-key anywhere beneath a key, use the ellipsis like so: .RB \(lq /.../version \(rq. This retrieves all keys of .RB \(lq version \(rq that are zero or more levels beneath the root .RI ( i.e. any appearance of .RB \(lq version \(rq within the database. .SH "SEE ALSO" .BR uniconfd (8) .SH AUTHORS This software was written by the hackers at Net Integration Technologies. Contact us at .\" Local variables: .\" mode:nroff .\" End: wvstreams-4.6.1/uniconf/tests/basictest.cc0000644000175000001440000000060511036722347017673 0ustar wlachusers#include "uniconfroot.h" int main() { UniConfRoot root("temp:"); root["foo"].setme("bar"); printf("foo = \"%s\"\n", root["foo"].getme().cstr()); root["foo"].setme("baz"); printf("foo = \"%s\"\n", root["foo"].getme().cstr()); UniConfRoot r("temp:"); UniConf uu; UniConfKey k; printf("root: %d uu: %d k: %d\n", sizeof(r), sizeof(uu), sizeof(k)); } wvstreams-4.6.1/uniconf/tests/c_test.c0000644000175000001440000000045411036722347017032 0ustar wlachusers#include "uniconf.h" int main() { uniconf_t uni; uni = uniconf_init("temp:"); uniconf_set(uni, "foo", "bar"); printf("foo = \"%s\"\n", uniconf_get(uni, "foo")); uniconf_set(uni, "foo", "baz"); printf("foo = \"%s\"\n", uniconf_get(uni, "foo")); uniconf_free(uni); } wvstreams-4.6.1/uniconf/tests/itertest.cc0000644000175000001440000000456611036722347017567 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test for the UniConf::Iter objects. */ #include "uniconfroot.h" #include "uniinigen.h" #include #include #include #if 0 static int hconfcmp(const UniConf *a, const UniConf *b) { return a->key() == b->key(); } static int rhconfcmp(const UniConf *a, const UniConf *b) { return a->full_key() == b->full_key(); } #endif template void dump(WvLog &log, Iter &i) { for (i.rewind(); i.next(); ) log(" '%s' = '%s'\n", i->fullkey(), i->getme()); } int main() { WvLogConsole rcv(2, WvLog::Debug4); WvLog log("itertest", WvLog::Info); UniConfRoot uniconfroot("ini:test2.ini"); UniConf h(uniconfroot); { log("Iter dump of /HTTPD:\n"); UniConf::Iter i(h["/httpd"]); dump(log, i); log("SortedIter dump of /HTTPD:\n"); UniConf::SortedIter si(h["/httpd"]); dump(log, si); } { UniConf r(h["/Tunnel Vision Routes"]); log("RecursiveIter dump of %s:\n", r.fullkey()); UniConf::RecursiveIter i(r); dump(log, i); } { log("XIter dump of /: (should be one key)\n"); UniConf::XIter i(h, "/"); dump(log, i); log("XIter dump of /*: (should be depth 1 only)\n"); UniConf::XIter i2(h, "/*"); dump(log, i2); log("XIter dump of /*/*: (should be depth 2 only)\n"); UniConf::XIter i3(h, "/*/*"); dump(log, i3); log("XIter dump of /httpd/*: (should be depth 2 only)\n"); UniConf::XIter i4(h, "/httpd/*"); dump(log, i4); log("XIter dump of /*/webmaster: (should show a few entries)\n"); UniConf::XIter i5(h, "/*/webmaster"); dump(log, i5); log("XIter dump of /*/*/monkey/*/2/*:\n"); UniConf::XIter i6(h, "/*/*/monkey/*/2/*"); dump(log, i6); log("XIter dump of /.../2/*:\n"); UniConf::XIter i7(h, "/.../2/*"); dump(log, i7); log("XIter dump of /.../*/4/...:\n"); UniConf::XIter i8(h, "/.../*/4/..."); dump(log, i8); log("XIter dump of /.../virus scanner/...:\n"); UniConf::XIter i9(h, "/.../virus scanner/..."); dump(log, i9); log("SortedXIter dump of /*/*/monkey/*/2/*:\n"); UniConf::XIter si(h, "/*/*/monkey/*/2/*"); dump(log, si); } return 0; } wvstreams-4.6.1/uniconf/tests/test2.ini0000644000175000001440000001200311036722347017140 0ustar wlachusers[Backup Preferences] webmaster = 1 [big/fat/monkey/1/2] 3 = abcde [big/fat/monkey/1/3] 4 = abcdf [big/fat/monkey/4/2] 6 = qwerjh [big/thin/monkey/1/2] 3 = xabcde [big/thin/monkey/1/3] 4 = xabcdf [big/thin/monkey/4/2] 6 = xqwerjh [chickens] bob = gooooblefish boob = {I like to wear funny hats} [Dialer] {Abort on Busy} = 0 {Abort on No Dialtone} = 0 {Expect Modems} = 0 [eth0] {DHCP In Progress} = 1 Exists = 1 [FTPAllow] webmaster = 1 [Full Names] webmaster = {Web Server Admin} [Global] DNS1 = weaver Domain = weavernet.null {First Boot} = 0 {Have Disk} = 0 Hostname = insight Interface = eth0 IPAddr = 192.168.12.100 {Mail Log} = 0 Netmask = 255.255.255.0 {Public IPAddr} = 192.168.12.100 RBL = 1 Version = 3.69f {Version String} = {3.70pre0 (dev)} WINS1 = weaver [gre0] {DHCP In Progress} = 0 Exists = 1 [Group Email] webmaster = 0 [Groups] webmaster = webmaster [HTTPD] {Admin Email} = webmaster {Admin Team} = webmaster {Make Certificate} = 1 {User Pages} = 1 [lo] {DHCP In Progress} = 0 Exists = 1 [Neener] Bobber = 50 [NFS] Mapping = 0 [PPTPAllow] webmaster = 1 [Samba] Workgroup = WORKGROUP [Servers] Appletalk = 1 ftpd = 1 httpd = 1 httpsd = 1 IMAP = 1 LDAP = 1 MySQL = 1 NFS = 0 NIS = 0 POP-3 = 1 pptpd = 0 {Public DNS} = 0 rsync = 2 Samba = 1 SMTP = 1 SNMP = 0 {Web Mail} = 1 {Web Proxy} = 0 [SoftUpdate] 2.9921 = {Incomplete Version 2.9921} 3.69f = {Version 3.70pre0 (dev)} [Tunnel Vision] Enable = 0 {RSA Private Key} = 3082025c02010002818100a072cd1a55a8f9843d739861c681d8288b6fb0581872ce0e415309617796869582ce7ab02cc3fc252fcd5d14f3799f968176af8434dc3ddb0e0ad88cbf8f26e8619634f9c4f1f6331dc171475b17f60680fe3a296a530974cf8799219eff5f7d7020ea6fe8cd1b8fd6ce6d316e5932cb1d0083134d311fe6d40cb698c4359f0d0201030281806af73366e3c5fbad7e4d10412f013ac5b24a7590104c895ed6375b964fb9af0e573451cac882a818ca88e8b8a251150f00f9ca58233d7e92095c905dd50a19ef32b42a58e11c5d0fdc70011fe289a854d2c51db85242dc721c508e6832d30ef2599d25b6d82e6f2bdff3b122bc315cd9df214a121fdd0fb7848af2ab1f1277eb024100d104072a61dba3ac34d9c1a352afde508edaad6e21b2b6cec29d7e9463237e8631bc0b3e40af4c203a9d15ca0dd621f44153af8054ca60a71fdc018abe09c595024100c483ee4a116bc6ef1e3fadf434999b36b5fbe026cd3c07fae27144f0ef9f4a8bb7f9269f63d828adcc43cdb3463905900cfae477c89b27ac6d60490d579025990241008b5804c6ebe7c272cde681178c753ee05f3c739ec121cf3481be5462ecc25459767d5cd42b1f88157c68b9315e8ec14d80e275003886eb1a153d565c7eb12e6302410083029edc0b9d2f4a142a73f8231112247952956f337d5aa741a0d8a09fbf8707cffb6f14ed3ac5c932d7de77842603b55dfc984fdb121a72f3958608e50ac3bb024100ce47b8e1064bae7f22dc5f673200b5ff19b58311fd667fb7b8f33d72648844e1a35d6fac9b31b2255e0761d285892eb45b7372d5c314d9a315cecd5a255aa2f8 {RSA Public Key} = 30818702818100a072cd1a55a8f9843d739861c681d8288b6fb0581872ce0e415309617796869582ce7ab02cc3fc252fcd5d14f3799f968176af8434dc3ddb0e0ad88cbf8f26e8619634f9c4f1f6331dc171475b17f60680fe3a296a530974cf8799219eff5f7d7020ea6fe8cd1b8fd6ce6d316e5932cb1d0083134d311fe6d40cb698c4359f0d020103 [Tunnel Vision Routes] 1.2.3.4 = 5.6.7.8 [Tunnel Vision Routes/10.42.49.96] 28 = 64.231.68.19 [Tunnel Vision Routes/169.254.92.0] 24 = 24.201.183.20 [Tunnel Vision Routes/192.168.0.0] 24 = 64.187.20.55 [Tunnel Vision Routes/192.168.10.0] 24 = 64.231.68.19 [Tunnel Vision Routes/192.168.13.0] 24 = 64.119.101.44 [Tunnel Vision Routes/192.168.22.0] 24 = 4.47.219.11 [Tunnel Vision Routes/192.168.42.0] 23 = 1.2.3.4 24 = 24.202.171.33 [Tunnel Vision Routes/192.168.50.0] 24 = 24.202.171.33 [Tunnel Vision Routes/192.168.51.0] 24 = 158.43.17.94 [Tunnel Vision Routes/192.168.52.0] 24 = 158.43.17.94 [UIDs] webmaster = 1008 [Users] webmaster = NOLOGIN [Virus Scanner] Licensed = 0 {Mail Scan} = 1 Update = 1 {Update Time} = 1 [WanPipe] Exists = 0 [Web Proxy] {Positive Filtering} = 0 [WebConfig] X509Certificate = 30820292308201fba00302010202023039300d06092a864886f70d01010405003069311e301c060355040313157765617665722e7765617665726e65742e6e756c6c31163014060a0992268993f22c640119130677656176657231193017060a0992268993f22c64011913097765617665726e657431143012060a0992268993f22c64011913046e756c6c301e170d3032303330373231323332315a170d3132303330343231323332315a3069311e301c060355040313157765617665722e7765617665726e65742e6e756c6c31163014060a0992268993f22c640119130677656176657231193017060a0992268993f22c64011913097765617665726e657431143012060a0992268993f22c64011913046e756c6c30819d300d06092a864886f70d010101050003818b0030818702818100a072cd1a55a8f9843d739861c681d8288b6fb0581872ce0e415309617796869582ce7ab02cc3fc252fcd5d14f3799f968176af8434dc3ddb0e0ad88cbf8f26e8619634f9c4f1f6331dc171475b17f60680fe3a296a530974cf8799219eff5f7d7020ea6fe8cd1b8fd6ce6d316e5932cb1d0083134d311fe6d40cb698c4359f0d020103a34b3049301106096086480186f8420101040403020640302406096086480186f842010c041716157765617665722e7765617665726e65742e6e756c6c300e0603551d0f0101ff0404030205a0300d06092a864886f70d0101040500038181007624a8125f12f60b39bf3abe5fda35c57a83a27c3df13b77f667aee5122b9773d90184fc4b6bc0b023d11bfb4940af2d227ca6107f47ed410aa0b770b29e52b587f3f8d973a1d1135fd001cfd47c16f93981979f394db2e55c8d2fff3f52bd6bbb99f08fac33807e47a6b142e495914aaee6a88ed66d91e6c0ce8851f400ba5d wvstreams-4.6.1/uniconf/tests/test.ini0000644000175000001440000000061411036722347017063 0ustar wlachusers [wacky\ test\ section] { goose } = weasels {weasels are } = like geese [{different wacky test section}] try = catch [chickens] bob = frank bill = weasel nob = bon [users] apenwarr = scs dcoombs = blah [users/apenwarr] pptp = 0 chicken/hammer = 5 [] /users/apenwarr/ftp = 1 [malformed] #A comment #blah blah blah malformed1 = malformed2 = malformed3 {malformed4 =} {malformed5 wvstreams-4.6.1/uniconf/tests/uniclienttest.cc0000644000175000001440000001116611036722347020610 0ustar wlachusers// Test client for the uniconf daemon /** * FIXME: This test case is not as useful at it could be because: * 1) it only tests a very small subset of features * 2) it does not setup / teardown its environment explicitly */ #include #include #include "wvtclstring.h" #include "wvunixsocket.h" #include "wvaddr.h" #include "uniconfroot.h" #include "uniclientgen.h" #include "wvtcp.h" void printheader(WvString h, WvString mountpoint) { WvString header("%s WITH MOUNTPOINT %s", h, mountpoint); wvcon->print("%s\n",header); for (size_t i = 0; i < header.len(); i++) wvcon->print("="); wvcon->print("\n\n"); } void printresult(bool pass) { if (pass) wvcon->print("\n***** PASSED *****\n\n"); else wvcon->print("\n///// FAILED /////\n\n"); } bool check(WvString test, WvString value, WvString expected) { if (value == expected) { wvcon->print("OK - %s: got \"%s\"\n", test, value); return true; } else { wvcon->print("FAIL - %s: expected \"%s\", got \"%s\"\n", test, expected, value); return false; } } bool testgetkeys(const UniConf &mainconf) { bool pass = true; UniConf narf(mainconf["chickens/bob"]); pass = check(narf.fullkey(), narf.getme(), "goof") && pass; narf = mainconf["wacky test section/ goose "]; pass = check(narf.fullkey(), narf.getme(), "bluebayou") && pass; narf = mainconf["this key should not exist/ bcscso "]; pass = check(narf.fullkey(), narf.getme(), WvString::null) && pass; return pass; } bool testgetfromsections(const UniConf &mainconf) { bool pass = true; UniConf neep(mainconf["chickens"]); UniConf sub(neep["bob"]); pass = check(sub.fullkey(), sub.getme(), "goof") && pass; neep = mainconf["users"]; sub = neep["apenwarr"]; UniConf subsub(sub["ftp"]); pass = check(subsub.fullkey(), subsub.getme(), "1") && pass; subsub = sub["pptp"]; pass = check(subsub.fullkey(), subsub.getme(), "0") && pass; return pass; } bool testgetsetkey(const UniConf &mainconf) { bool pass = true; UniConf narf(mainconf["chickens/bob"]); pass = check(narf.fullkey(), narf.getme(), "goof") && pass; narf.setme("troop"); pass = check(narf.fullkey(), narf.getme(), "troop") && pass; narf.remove(); pass = check(narf.fullkey(), narf.getme(), WvString::null) && pass; #if 1 // FIXME: UniConf daemon handling of empty string broken narf.setme(""); pass = check(narf.fullkey(), narf.getme(), "") && pass; #endif narf.setme("goof"); pass = check(narf.fullkey(), narf.getme(), "goof") && pass; return pass; } void usage(const char *name) { wvcon->print("%s usage:\n", name); wvcon->print("%s [-h] [-t test_type]\n", name); wvcon->print("\t-h - display this message\n"); wvcon->print("\t-t test_type: test_type is one of all, get, set or section\n"); exit(0); } int main(int argc, char **argv) { // system("clear"); WvString location("tcp:localhost:4111"); WvString mountpoint(""); WvString totest = "all"; if (argc == 2 && !strcasecmp(argv[1], "-h")) { usage(argv[0]); } else if (3 == argc) { if (!strcasecmp("-t",argv[1])) totest = argv[2]; } for (int i = 0; i < 2; i++) { // Test getting a few keys if ("all" == totest || "get" == totest) { UniConfRoot root; UniConf mainconf(root); UniConf mounted(mainconf[mountpoint]); mounted.mount(location); printheader("TEST GETTING KEYS", mountpoint); printresult(testgetkeys(mounted)); } // Test getting a section and then a key if ("all" == totest || "section" == totest) { UniConfRoot root; UniConf mainconf(root); UniConf mounted(mainconf[mountpoint]); mounted.mount(location); printheader("TEST GETTING FROM A SECTION", mountpoint); printresult(testgetfromsections(mounted)); } // Test getting & setting a key if ("all" == totest || "set" == totest) { UniConfRoot root; UniConf mainconf(root); UniConf mounted(mainconf[mountpoint]); mounted.mount(location); printheader("TEST SETTING KEYS", mountpoint); printresult(testgetsetkey(mounted)); } mountpoint = "orino"; } /* WvTCPConn conn(addr); conn.select(0, true,true,false); conn.print("|******************************|\n"); */ return 0; } wvstreams-4.6.1/uniconf/uniwvconfgen.cc0000644000175000001440000000515011036722347017260 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A generator to make a UniConf object out of a WvConf. */ #include "wvconf.h" #include "uniwvconfgen.h" #include "wvmoniker.h" /** * A wrapper class for the wvconf iters to provide a UniConfGen iter. */ class UniWvConfGen::WvConfIter : public UniConfGen::Iter { protected: WvConfigSection::Iter i; public: WvConfIter(WvConfigSection *sect); /***** Overridden members *****/ virtual void rewind(); virtual bool next(); virtual UniConfKey key() const; virtual WvString value() const; }; static IUniConfGen *creator(WvStringParm s, IObject*) { return new UniWvConfGen(new WvConf(s)); } static WvMoniker reg("wvconf", creator); void UniWvConfGen::notify(void *userdata, WvStringParm section, WvStringParm entry, WvStringParm oldval, WvStringParm newval) { UniConfKey key(section, entry); tempvalue = newval; tempkey = &key; delta(key, newval); tempkey = NULL; } UniWvConfGen::UniWvConfGen(WvConf *_cfg): tempkey(NULL), tempvalue(), cfg(_cfg) { cfg->add_callback(wv::bind(&UniWvConfGen::notify, this, _1, _2, _3, _4, _5), NULL, "", "", this); } UniWvConfGen::~UniWvConfGen() { if (cfg) delete cfg; } WvString UniWvConfGen::get(const UniConfKey &key) { if (tempkey && key == *tempkey) return tempvalue; else return cfg->get(key.first(), key.last(key.numsegments() - 1)); } void UniWvConfGen::set(const UniConfKey &key, WvStringParm value) { WvString section = key.first(); WvString keyname = key.last(key.numsegments() - 1); WvConfigSection *sect = (*cfg)[section]; if (value == WvString::null && sect) cfg->delete_section(key); else cfg->set(section, keyname, value); } void UniWvConfGen::setv(const UniConfPairList &pairs) { setv_naive(pairs); } bool UniWvConfGen::haschildren(const UniConfKey &key) { WvConfigSection *sect = (*cfg)[key]; if (sect) return true; return false; } UniWvConfGen::Iter *UniWvConfGen::iterator(const UniConfKey &key) { WvConfigSection *sect = (*cfg)[key]; if (sect) return new WvConfIter(sect); else return NULL; } /***** UniWvConfGen::WvConfIter *****/ UniWvConfGen::WvConfIter::WvConfIter(WvConfigSection *sect) : i(*sect) { } void UniWvConfGen::WvConfIter::rewind() { i.rewind(); } bool UniWvConfGen::WvConfIter::next() { return i.next(); } UniConfKey UniWvConfGen::WvConfIter::key() const { return i->name; } WvString UniWvConfGen::WvConfIter::value() const { return i->value; } wvstreams-4.6.1/uniconf/unilistiter.cc0000644000175000001440000000202511036722347017121 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A simple implementation of a UniConfGen iterator. See unilistiter.h. */ #include "unilistiter.h" UniListIter::UniListIter(IUniConfGen *_gen) : ki(keys), vi(values) { gen = _gen; } void UniListIter::add(const UniConfKey &k, WvStringParm v) { UniConfKey *nk = new UniConfKey(k); keys.append(nk, true); keylook.add(nk, false); if (!v.isnull()) values.append(new WvString(scache.get(v)), true); } void UniListIter::autofill(IUniConfGen::Iter *_source) { IUniConfGen::Iter &source(*_source); for (source.rewind(); source.next(); ) add(source.key(), source.value()); } void UniListIter::rewind() { ki.rewind(); vi.rewind(); } bool UniListIter::next() { if (vi.cur()) vi.next(); return ki.next(); } UniConfKey UniListIter::key() const { return *ki; } WvString UniListIter::value() const { if (vi.cur()) return *vi; else return gen->get(*ki); } wvstreams-4.6.1/uniconf/unislowgen.cc0000644000175000001440000000331411036722347016742 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen that makes everything slow. See unislowgen.h. */ #include "unislowgen.h" #include "wvmoniker.h" #ifndef _MSC_VER // FIXME:WLACH Is unistd even needed here?! #include #endif static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniSlowGen(wvcreate(s, _obj)); } static WvMoniker reg("slow", creator); UniSlowGen::UniSlowGen(IUniConfGen *inner) : UniFilterGen(inner) { slowcount = 0; } UniSlowGen::~UniSlowGen() { fprintf(stderr, "%p: UniSlowGen: ran a total of %d slow operations.\n", this, how_slow()); } void UniSlowGen::commit() { be_slow("commit()"); UniFilterGen::commit(); } bool UniSlowGen::refresh() { be_slow("refresh()"); return UniFilterGen::refresh(); } WvString UniSlowGen::get(const UniConfKey &key) { be_slow("get(%s)", key); return UniFilterGen::get(key); } bool UniSlowGen::exists(const UniConfKey &key) { be_slow("exists(%s)", key); return UniFilterGen::exists(key); } bool UniSlowGen::haschildren(const UniConfKey &key) { be_slow("haschildren(%s)", key); return UniFilterGen::haschildren(key); } UniConfGen::Iter *UniSlowGen::iterator(const UniConfKey &key) { be_slow("iterator(%s)", key); return UniFilterGen::iterator(key); } UniConfGen::Iter *UniSlowGen::recursiveiterator(const UniConfKey &key) { be_slow("recursiveiterator(%s)", key); return UniFilterGen::recursiveiterator(key); } void UniSlowGen::be_slow(WvStringParm what) { fprintf(stderr, "%p: UniSlowGen: slow operation: %s\n", this, what.cstr()); // sleep(1); slowcount++; } wvstreams-4.6.1/uniconf/wvconfemutrace.pl0000755000175000001440000000212111036722347017624 0ustar wlachusers#! /usr/bin/perl -w use strict; my %entries; my $binary = shift(@ARGV); while(my $line = <>) { next unless $line =~ m/^TRACE:/; chomp($line); my(undef, $type, $section, $key, $cookie, @backtrace) = split(/:/, $line); if($type eq 'add') { $entries{$section} = {} if !defined($entries{$section}); $entries{$section}{$key} = {} if !defined($entries{$section}{$key}); $entries{$section}{$key}{$cookie} = \@backtrace; } elsif($type eq 'del') { $entries{$section}{$key}{$cookie} = undef; } else { die("unknown type"); } } foreach my $section (sort(keys(%entries))) { foreach my $key (sort(keys(%{$entries{$section}}))) { foreach my $cookie (sort(keys(%{$entries{$section}{$key}}))) { if(defined($entries{$section}{$key}{$cookie})) { print "[$section]$key -> $cookie:\n"; shift(@{$entries{$section}{$key}{$cookie}}); foreach my $frame (@{$entries{$section}{$key}{$cookie}}) { $frame =~ s/\+0x[0-9a-f]+\)/)/; $frame =~ s/\) \[(.*)\]$/)/; #my $line = `addr2line -e $binary $1`; #chomp($line); print "\t$1: $frame\n", ; } } } } } wvstreams-4.6.1/uniconf/unidefgen.cc0000644000175000001440000000622611036722347016521 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * UniDefGen is a UniConfGen for retrieving data with defaults */ #include "unidefgen.h" #include "wvmoniker.h" //#include "wvstream.h" #include #include #include "wvlinkerhack.h" WV_LINK(UniDefGen); // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the // given moniker. static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniDefGen(wvcreate(s, _obj)); } // this name is too confusing. We should deprecate it. static WvMoniker reg("default", creator); // a better name for the same thing. static WvMoniker reg2("wildcard", creator); UniConfKey UniDefGen::finddefault(const UniConfKey &key, char *p, char *q) { UniConfKey result; if (!p) { q++; if (inner() && inner()->exists(q)) return q; else return UniConfKey(); } // pop the first segment of p to r char *r = strchr(p, '/'); if (r) *r++ = '\0'; // append p to q char *s = strchr(q, '\0'); *s++ = '/'; *s = 0; q = strcat(q, p); // try this literal path result = finddefault(key, r, q); if (result.numsegments()) return result; // replace what used to be p with a * *s++ = '*'; *s = '\0'; result = finddefault(key, r, q); if (r) *--r = '/'; return result; } WvString UniDefGen::replacewildcard(const UniConfKey &key, const UniConfKey &defkey, WvStringParm in) { // check if the result wants a wildcard ('*n') if (in.len() < 2 || in[0] != '*') return in; const char *s = in.cstr(); int idx = atoi(s+1); if (idx == 0) return in; // search backwards for segment num of the n'th wildcard UniConfKey k(defkey); int loc = key.numsegments(); for (int i = 0; i < idx; i++) { if (i != 0) { k = k.removelast(); loc--; } while (!k.last().iswild()) { k = k.removelast(); loc--; if (k.isempty()) { // oops, ran out of segments! return WvString(); } } } // pull the literal from that segment num of the key return key.segment(loc-1); } bool UniDefGen::keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key) { WvString tmp_key(unmapped_key), tmp(""); char *p = tmp_key.edit(); tmp.setsize(strlen(tmp_key) * 2); char *q = tmp.edit(); *q = '\0'; mapped_key = finddefault(unmapped_key, p, q); if (!mapped_key.numsegments()) mapped_key = unmapped_key; // fprintf(stderr, "mapping '%s' -> '%s'\n", key.cstr(), result.cstr()); return true; } WvString UniDefGen::get(const UniConfKey &key) { UniConfKey mapped_key; if (keymap(key, mapped_key)) return replacewildcard(key, mapped_key, inner() ? inner()->get(mapped_key) : WvString()); else return WvString::null; } void UniDefGen::set(const UniConfKey &key, WvStringParm value) { // no keymap() on set() if (inner()) inner()->set(key, value); } wvstreams-4.6.1/uniconf/uniconfgen.cc0000644000175000001440000001157711036722347016715 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * An abstract data container that backs a UniConf tree. */ #include "uniconfgen.h" #include "strutils.h" // FIXME: interfaces (IUniConfGen) shouldn't have implementations! IUniConfGen::~IUniConfGen() { } UUID_MAP_BEGIN(UniConfGen) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IUniConfGen) UUID_MAP_END UniConfGen::UniConfGen() { hold_nesting = 0; } UniConfGen::~UniConfGen() { assert(cblist.isempty()); } void UniConfGen::hold_delta() { hold_nesting++; } void UniConfGen::unhold_delta() { assert(hold_nesting > 0); if (hold_nesting == 1) flush_delta(); hold_nesting--; } void UniConfGen::clear_delta() { deltas.zap(); } void UniConfGen::flush_delta() { UniConfPairList::Iter it(deltas); for (;;) { it.rewind(); if (! it.next()) break; UniConfKey key((*it).key()); WvString value((*it).value()); it.xunlink(); dispatch_delta(key, value); } } void UniConfGen::dispatch_delta(const UniConfKey &key, WvStringParm value) { cblist(key, value); } void UniConfGen::delta(const UniConfKey &key, WvStringParm value) { if (hold_nesting == 0) { // not nested, dispatch immediately dispatch_delta(key, value); } else { hold_delta(); deltas.add(new UniConfPair(key, value), true); unhold_delta(); } } void UniConfGen::setv_naive(const UniConfPairList &pairs) { UniConfPairList::Iter pair(pairs); for (pair.rewind(); pair.next(); ) set(pair->key(), pair->value()); } bool UniConfGen::haschildren(const UniConfKey &key) { bool children = false; hold_delta(); Iter *it = iterator(key); if (it) { it->rewind(); if (it->next()) children = true; delete it; } unhold_delta(); return children; } bool UniConfGen::exists(const UniConfKey &key) { return !get(key).isnull(); } int UniConfGen::str2int(WvStringParm value, int defvalue) const { // also recognize bool strings as integers const char *strs[] = { "true", "yes", "on", "enabled", "false", "no", "off", "disabled" }; const size_t numtruestrs = 4; if (!value.isnull()) { // try to recognize an integer char *end; int num = strtol(value.cstr(), &end, 0); if (end != value.cstr()) return num; // was a valid integer // try to recognize a special string for (size_t i = 0; i < sizeof(strs) / sizeof(const char*); ++i) if (strcasecmp(value, strs[i]) == 0) return i < numtruestrs; } return defvalue; } bool UniConfGen::isok() { return true; } void UniConfGen::add_callback(void *cookie, const UniConfGenCallback &callback) { cblist.add(callback, cookie); } void UniConfGen::del_callback(void *cookie) { cblist.del(cookie); } class _UniConfGenRecursiveIter : public IUniConfGen::Iter { WvList itlist; IUniConfGen *gen; UniConfKey top, current; bool sub_next; public: _UniConfGenRecursiveIter(IUniConfGen *_gen, const UniConfKey &_top) : top(_top) { gen = _gen; sub_next = false; } virtual ~_UniConfGenRecursiveIter() { } virtual void rewind() { current = ""; sub_next = false; itlist.zap(); Iter *subi = gen->iterator(top); if (subi) { subi->rewind(); itlist.prepend(subi, true); } } virtual bool next() { //assert(!itlist.isempty()); // trying to seek past the end is illegal! if (sub_next) { sub_next = false; UniConfKey subkey(itlist.first()->key()); UniConfKey newkey(current, subkey); //fprintf(stderr, "subiter: '%s'\n", newkey.cstr()); Iter *newsub = gen->iterator(UniConfKey(top, newkey)); if (newsub) { current.append(subkey); //fprintf(stderr, "current is now: '%s'\n", current.cstr()); newsub->rewind(); itlist.prepend(newsub, true); } } WvList::Iter i(itlist); for (i.rewind(); i.next(); ) { if (i->next()) // NOTE: not the same as i.next() { // set up so next time, we go into its subtree sub_next = true; return true; } // otherwise, this iterator is empty; move up the tree current = current.removelast(); //fprintf(stderr, "current is now: '%s'\n", current.cstr()); i.xunlink(); } // all done! return false; } virtual UniConfKey key() const { //fprintf(stderr, "current is now: '%s'\n", current.cstr()); if (!itlist.isempty()) return UniConfKey(current, itlist.first()->key()); else return current; } virtual WvString value() const { return gen->get(UniConfKey(top, key())); } }; UniConfGen::Iter *UniConfGen::recursiveiterator(const UniConfKey &key) { return new _UniConfGenRecursiveIter(this, key); } wvstreams-4.6.1/uniconf/uniconfroot.cc0000644000175000001440000001145611202637334017117 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines the root management class for UniConf. To create any kind of * UniConf tree, you'll need one of these. */ #include "uniconfroot.h" #include "wvlinkerhack.h" WV_LINK_TO(UniGenHack); UniConfRoot::UniConfRoot(): UniConf(this), watchroot(NULL) { mounts.add_callback(this, wv::bind(&UniConfRoot::gen_callback, this, _1, _2)); } UniConfRoot::UniConfRoot(WvStringParm moniker, bool refresh): UniConf(this), watchroot(NULL) { mounts.mount("/", moniker, refresh); mounts.add_callback(this, wv::bind(&UniConfRoot::gen_callback, this, _1, _2)); } UniConfRoot::UniConfRoot(UniConfGen *gen, bool refresh): UniConf(this), watchroot(NULL) { mounts.mountgen("/", gen, refresh); mounts.add_callback(this, wv::bind(&UniConfRoot::gen_callback, this, _1, _2)); } // make sure the given subtree of callback information is empty static bool watchout(UniWatchInfoTree *t) { bool fail = false; UniWatchInfoTree::Iter i(*t); for (i.rewind(); i.next(); ) { UniWatchInfoTree *w = i.ptr(); if (w->haschildren()) if (watchout(w)) fail = true; if (!w->watches.isempty()) { fail = true; if (1) fprintf(stderr, "Remaining watch: '%s' (%zd)\n", w->fullkey().printable().cstr(), w->watches.count()); } } return fail; } UniConfRoot::~UniConfRoot() { // first, unmount everything. Some of the mounts might have waiting // callbacks. (I hope not, but... things like UniUnwrapGen might get // confusing.) mounts.zap(); // if the list of callbacks is non-empty, someone is either very buggy // (they disappeared without deleting their callback, so they could cause // crashes), or they're not getting what they expected (we disappeared // before they did, so they won't be getting their callback). assert(!watchout(&watchroot)); mounts.del_callback(this); } void UniConfRoot::add_callback(void *cookie, const UniConfKey &key, const UniConfCallback &callback, bool recurse) { UniWatchInfo *w = new UniWatchInfo(cookie, recurse, callback); UniWatchInfoTree *node = &watchroot; UniConfKey::Iter i(key); for (i.rewind(); i.next(); ) { UniWatchInfoTree *prev = node; node = node->findchild(i()); if (!node) node = new UniWatchInfoTree(prev, i()); } node->watches.append(w, true); } void UniConfRoot::del_callback(void *cookie, const UniConfKey &key, bool recurse) { UniWatchInfoTree *node = watchroot.find(key); if (node) { UniWatchInfoList::Iter i(node->watches); for (i.rewind(); i.next(); ) { // remove the watch if it matches if (i->cookie == cookie && i->recurse == recurse) { i.xunlink(); break; } } // prune the branch if needed prune(node); } } void UniConfRoot::add_setbool(const UniConfKey &key, bool *flag, bool recurse) { add_callback(flag, key, wv::bind(&UniConfRoot::setbool_callback, flag, _1, _2), recurse); } void UniConfRoot::del_setbool(const UniConfKey &key, bool *flag, bool recurse) { del_callback(flag, key, recurse); } void UniConfRoot::check(UniWatchInfoTree *node, const UniConfKey &key, int segleft) { UniWatchInfoList::Iter i(node->watches); for (i.rewind(); i.next(); ) { if (!i->recursive() && segleft > 0) continue; i->notify(UniConf(this, key.removelast(segleft)), key.last(segleft)); } } void UniConfRoot::deletioncheck(UniWatchInfoTree *node, const UniConfKey &key) { UniWatchInfoTree::Iter i(*node); for (i.rewind(); i.next(); ) { UniWatchInfoTree *w = i.ptr(); UniConfKey subkey(key, w->key()); // pretend that we wiped out just this key check(w, subkey, 0); deletioncheck(w, subkey); } } void UniConfRoot::prune(UniWatchInfoTree *node) { while (node != & watchroot && ! node->isessential()) { UniWatchInfoTree *next = node->parent(); delete node; node = next; } } void UniConfRoot::gen_callback(const UniConfKey &key, WvStringParm value) { hold_delta(); UniWatchInfoTree *node = & watchroot; int segs = key.numsegments(); // check root node check(node, key, segs); // look for watches on key and its ancestors for (int s = 0; s < segs; ) { node = node->findchild(key.segment(s)); s++; if (!node) goto done; // no descendents so we can stop check(node, key, segs - s); } // look for watches on descendents of key if node was deleted if (value.isnull()) deletioncheck(node, key); done: unhold_delta(); } wvstreams-4.6.1/uniconf/wvconfemu.cc0000644000175000001440000002664611036722347016576 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Basic WvConf emulation layer for UniConf. */ #include "wvconfemu.h" #include "uniinigen.h" #include "wvstringtable.h" #include "wvfile.h" #include "strutils.h" //#define DEBUG_DEL_CALLBACK 1 #ifdef DEBUG_DEL_CALLBACK #include #endif /* * Parse the WvConf string "request"; pointers to the found section, * entry, and value fields are stored in *section, *entry, and *value * respectively, and request[] is modified. * * For example, the string: * [silly]billy=willy * is parsed into: * section="silly"; entry="billy"; value="willy"; * * Returns 0 on success, -1 if the command is missing the '[', -2 if * the string is missing a ']', or -3 if the section or entry is * blank. If a "value" is not found (ie. there is no equal sign * outside the [] brackets) this does not qualify as an error, but * *value is set to NULL. */ static int parse_wvconf_request(char *request, char *§ion, char *&entry, char *&value) { entry = value = NULL; section = strchr(request, '['); if (!section) return -1; section++; entry = strchr(section, ']'); if (!entry) return -2; *entry++ = 0; value = strchr(entry, '='); if (value) { *value++ = 0; value = trim_string(value); } section = trim_string(section); entry = trim_string(entry); if (!*section) return -3; return 0; } static void do_setbool(void *userdata, WvStringParm section, WvStringParm key, WvStringParm oldval, WvStringParm newval) { bool* b = static_cast(userdata); *b = true; } static void do_addname(void *userdata, WvStringParm section, WvStringParm key, WvStringParm oldval, WvStringParm newval) { if (!!key) (*(WvStringList *)userdata).append(new WvString(key), true); } WvConfigEntryEmu *WvConfigSectionEmu::operator[] (WvStringParm s) { WvConfigEntryEmu* entry = entries[s]; if (uniconf[s].exists()) { if (!entry) { entry = new WvConfigEntryEmu(s, uniconf[s].getme()); entries.add(entry, true); } else entry->value = uniconf[s].getme(); } else entry = NULL; return entry; } const char *WvConfigSectionEmu::get(WvStringParm entry, const char *def_val) { if (!entry) return def_val; WvString s(uniconf[entry].getme(def_val)); // look it up in the cache WvString *sp = values[s]; if (!sp) values.add(sp = new WvString(s), true); return sp->cstr(); } void WvConfigSectionEmu::set(WvStringParm entry, WvStringParm value) { if (!!entry) { if (!!value) uniconf[entry].setme(value); else uniconf[entry].setme(WvString::null); } } void WvConfigSectionEmu::quick_set(WvStringParm entry, WvStringParm value) { uniconf[entry].setme(value); } bool WvConfigSectionEmu::isempty() const { return !uniconf.haschildren(); } WvConfigSectionEmu::Iter::~Iter() { } void WvConfigSectionEmu::Iter::rewind() { iter.rewind(); link.data = entry = NULL; } WvLink *WvConfigSectionEmu::Iter::next() { while (iter.next()) { // WvConf-enabled code expects all set keys to be non-empty; // enforce this behaviour if (!!iter->getme()) { /* * FIXME: if the WvConfEmu is not at the root of the * UniConf tree, this will give an incorrect result. */ entry = sect[iter->fullkey(sect.uniconf)]; link.data = static_cast(entry); assert(entry); return &link; } } return NULL; } WvLink *WvConfigSectionEmu::Iter::cur() { return &link; } WvConfigEntryEmu *WvConfigSectionEmu::Iter::ptr() const { return entry; } void *WvConfigSectionEmu::Iter::vptr() const { return link.data; } void WvConfEmu::notify(const UniConf &_uni, const UniConfKey &_key) { WvString section(_key.first()); WvString key(_key.removefirst()); if (hold) return; WvString value = uniconf[section][key].getme(""); WvList::Iter i(callbacks); for (i.rewind(); i.next(); ) { if ((!i->section || !strcasecmp(i->section, section)) && (!i->key || !strcasecmp(i->key, key))) { i->callback(i->userdata, section, key, WvString(), value); } } } WvConfEmu::WvConfEmu(const UniConf &_uniconf) : sections(42), hold(false), values(420), uniconf(_uniconf) { wvauthd = NULL; uniconf.add_callback(this, wv::bind(&WvConfEmu::notify, this, _1, _2), true); dirty = false; } WvConfEmu::~WvConfEmu() { // things will "work" if you don't empty the callback list before // deleting the WvConfEmu, but they probably won't work the way you // think they will. (ie. someone might be using a temporary WvConfEmu // and think his callbacks will stick around; they won't!) #ifndef DEBUG_DEL_CALLBACK assert(callbacks.isempty()); #else if (!callbacks.isempty()) { WvList::Iter i(callbacks); fprintf(stderr, " *** leftover callbacks in WvConfEmu ***\n"); for (i.rewind(); i.next(); ) { fprintf(stderr, " - [%s]%s (%p)\n", i->section.cstr(), i->key.cstr(), i->cookie); } } #endif uniconf.del_callback(this); } void WvConfEmu::zap() { uniconf.remove(); } bool WvConfEmu::isclean() const { return isok() && !dirty; } bool WvConfEmu::isok() const { return !uniconf.isnull(); } void WvConfEmu::load_file(WvStringParm filename) { UniConfRoot new_uniconf(WvString("ini:%s", filename)); hold = true; new_uniconf.copy(uniconf, true); hold = false; } void WvConfEmu::save(WvStringParm filename, int _create_mode) { UniConfRoot tmp_uniconf(new UniIniGen(filename, _create_mode), false); uniconf.copy(tmp_uniconf, true); tmp_uniconf.commit(); } void WvConfEmu::save() { uniconf.commit(); } void WvConfEmu::flush() { uniconf.commit(); dirty = false; } WvConfigSectionEmu *WvConfEmu::operator[] (WvStringParm sect) { if (UniConfKey(sect).numsegments() != 1) return NULL; WvConfigSectionEmu* section = sections[sect]; if (!section && uniconf[sect].exists()) { section = new WvConfigSectionEmu(uniconf[sect], sect, &values); sections.add(section, true); } return section; } void WvConfEmu::add_callback(WvConfCallback callback, void *userdata, WvStringParm section, WvStringParm key, void *cookie) { if (!callback) return; WvList::Iter i(callbacks); for (i.rewind(); i.next(); ) { if (i->cookie == cookie && i->section == section && i->key == key) return; } #ifdef DEBUG_DEL_CALLBACK void* trace[10]; int count = backtrace(trace, sizeof(trace)/sizeof(trace[0])); char** tracedump = backtrace_symbols(trace, count); fprintf(stderr, "TRACE:add:%s:%s:%p", section.cstr(), key.cstr(), cookie); for (int i = 0; i < count; ++i) fprintf(stderr, ":%s", tracedump[i]); fprintf(stderr, "\n"); free(tracedump); #endif callbacks.append(new CallbackInfo(callback, userdata, section, key, cookie), true); } void WvConfEmu::del_callback(WvStringParm section, WvStringParm key, void *cookie) { WvList::Iter i(callbacks); assert(cookie); for (i.rewind(); i.next(); ) { if (i->cookie == cookie && i->section == section && i->key == key) { #ifdef DEBUG_DEL_CALLBACK fprintf(stderr, "TRACE:del:%s:%s:%p\n", section.cstr(), key.cstr(), cookie); #endif i.xunlink(); } } } void WvConfEmu::add_setbool(bool *b, WvStringParm _section, WvStringParm _key) { add_callback(do_setbool, b, _section, _key, b); } void WvConfEmu::del_setbool(bool *b, WvStringParm _section, WvStringParm _key) { del_callback(_section, _key, b); } void WvConfEmu::add_addname(WvStringList *list, WvStringParm sect, WvStringParm ent) { add_callback(do_addname, list, sect, ent, list); } void WvConfEmu::del_addname(WvStringList *list, WvStringParm sect, WvStringParm ent) { del_callback(sect, ent, list); } WvString WvConfEmu::getraw(WvString wvconfstr, int &parse_error) { char *section, *entry, *value; parse_error = parse_wvconf_request(wvconfstr.edit(), section, entry, value); if (parse_error) return WvString(); return get(section, entry, value); } int WvConfEmu::getint(WvStringParm section, WvStringParm entry, int def_val) { if (!section || !entry) return def_val; return uniconf[section][entry].getmeint(def_val); } const char *WvConfEmu::get(WvStringParm section, WvStringParm entry, const char *def_val) { if (!section || !entry) return def_val; WvString s(uniconf[section][entry].getme(def_val)); // look it up in the cache WvString *sp = values[s]; if (!sp) values.add(sp = new WvString(s), true); return sp->cstr(); } int WvConfEmu::fuzzy_getint(WvStringList §, WvStringParm entry, int def_val) { WvString def_str(def_val); return check_for_bool_string(fuzzy_get(sect, entry, def_str)); } const char *WvConfEmu::fuzzy_get(WvStringList §, WvStringParm entry, const char *def_val) { WvStringList::Iter i(sect); WvStringTable cache(5); WvConfigSectionEmu *s; for (i.rewind(); i.next(); ) { for(s = (*this)[*i]; s && !cache[s->name]; s = (*s)["Inherits"] ? (*this)[(*s)["Inherits"]->value] : NULL) { const char *ret = s->get(entry); if (ret) return ret; cache.add(&s->name, false); } } return def_val; } void WvConfEmu::setraw(WvString wvconfstr, const char *&_value, int &parse_error) { char *section, *entry, *value; parse_error = parse_wvconf_request(wvconfstr.edit(), section, entry, value); if (!parse_error) { set(section, entry, value); _value = get(section, entry, value); } else _value = NULL; } void WvConfEmu::setint(WvStringParm section, WvStringParm entry, int value) { if (!!entry) uniconf[section][entry].setmeint(value); } void WvConfEmu::set(WvStringParm section, WvStringParm entry, const char *value) { if (!!entry) { if (value && value[0] != 0) uniconf[section][entry].setme(value); else uniconf[section][entry].setme(WvString::null); dirty = true; } } void WvConfEmu::maybesetint(WvStringParm section, WvStringParm entry, int value) { if (!!entry && !get(section, entry, NULL)) setint(section, entry, value); } void WvConfEmu::maybeset(WvStringParm section, WvStringParm entry, const char *value) { if (!!entry && get(section, entry, 0) == 0) set(section, entry, value); } void WvConfEmu::delete_section(WvStringParm section) { uniconf[section].remove(); dirty = true; } int WvConfEmu::check_for_bool_string(const char *s) { if (strcasecmp(s, "off") == 0 || strcasecmp(s, "false") == 0 || strncasecmp(s, "no", 2) == 0) // also handles "none" return 0; if (strcasecmp(s, "on") == 0 || strcasecmp(s, "true") == 0 || strcasecmp(s, "yes") == 0) return 1; // not a special bool case, so just return the number return atoi(s); } void WvConfEmu::Iter::rewind() { iter.rewind(); link.data = NULL; } WvLink *WvConfEmu::Iter::next() { link.data = NULL; while (link.data == NULL && iter.next()) { link.data = static_cast(conf[iter->key()]); } if (link.data) { return &link; } return NULL; } WvConfigSectionEmu *WvConfEmu::Iter::ptr() const { return conf[iter->key()]; } wvstreams-4.6.1/uniconf/t/0000755000175000001440000000000011260431126014472 5ustar wlachuserswvstreams-4.6.1/uniconf/t/unisubtreegen.t.cc0000644000175000001440000000570111077124114020127 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "uniwatch.h" #include "unitempgen.h" #include "unisubtreegen.h" #include "uniconfdaemon.h" #include "uniconfgen-sanitytest.h" #include "wvfileutils.h" #include "uniclientgen.h" #include "wvtimeutils.h" #include "wvunixsocket.h" #include WVTEST_MAIN("UniSubtreeGen Sanity Test") { UniSubtreeGen *gen = new UniSubtreeGen(new UniTempGen(), "/"); UniConfGenSanityTester::sanity_test(gen, "subtree:temp: /"); WVRELEASE(gen); } int callback_count; void callback(const UniConf &uniconf, const UniConfKey &key) { wverr->print("callback: %s = %s (count now %s)\n", uniconf[key].fullkey(), uniconf[key].getme(), ++callback_count); } int sub_callback_count; void sub_callback(const UniConf &uniconf, const UniConfKey &key) { wverr->print("sub_callback: %s = %s (count now %s)\n", uniconf[key].fullkey(), uniconf[key].getme(), ++sub_callback_count); } #ifndef _WIN32 WVTEST_MAIN("callbacks") { signal(SIGPIPE, SIG_IGN); WvString sockname = wvtmpfilename("unisubtreegen.t-sock"); unlink(sockname); UniConfTestDaemon daemon(sockname, "temp:"); UniConfRoot uniconf; printf("Waiting for daemon to start.\n"); fflush(stdout); int num_tries = 0; const int max_tries = 20; while (!uniconf.isok() && num_tries++ < max_tries) { WVFAIL(uniconf.isok()); // Try again... uniconf.unmount(uniconf.whichmount(), true); uniconf.mount(WvString("unix:%s", sockname)); wvdelay(100); } num_tries = 0; UniConfRoot sub_uniconf; UniClientGen *sub_client_gen; while (num_tries++ < max_tries) { WvUnixConn *unix_conn; sub_client_gen = new UniClientGen( unix_conn = new WvUnixConn(sockname)); if (!unix_conn || !unix_conn->isok() || !sub_client_gen || !sub_client_gen->isok()) { WVRELEASE(sub_client_gen); wvout->print("Failed to connect, retrying...\n"); wvdelay(100); } else break; } UniSubtreeGen *subtree = new UniSubtreeGen(sub_client_gen, "sub"); sub_uniconf.mountgen(subtree); UniWatchList watches; watches.add(uniconf, callback, true); watches.add(sub_uniconf, sub_callback, true); uniconf.getme(); sub_uniconf.getme(); uniconf["sub"].setme(""); uniconf["another-sub"].setme(""); uniconf.getme(); sub_uniconf.getme(); callback_count = 0; sub_callback_count = 0; uniconf["sub/foo"].setme("bar"); uniconf.getme(); WVPASSEQ(callback_count, 1); sub_uniconf.getme(); WVPASSEQ(sub_callback_count, 1); callback_count = 0; sub_callback_count = 0; uniconf["another-sub/foo"].setme("bar"); uniconf.getme(); WVPASSEQ(callback_count, 1); sub_uniconf.getme(); WVPASSEQ(sub_callback_count, 0); // Should not have received callbacks unlink(sockname); } #endif wvstreams-4.6.1/uniconf/t/uniconfroot.t.cc0000644000175000001440000002040311036722347017620 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "wvstream.h" WVTEST_MAIN("no generator") { UniConfRoot root1; WVPASS(root1.getme() == WvString::null); // verify that setting keys in unmounted space does not actually // set their values (or more likely, cause a segfault) UniConfRoot root2; root2["subt/mayo/baz"].mount("temp:"); root2["/"].setme("foo"); root2["subt"].setme("bar"); root2["subt/mayo"].setme("moo"); WVPASS(strcmp(root2["/"].getme().cstr(), "") == 0); WVPASS(strcmp(root2["subt"].getme().cstr(), "") == 0); WVPASS(strcmp(root2["subt/mayo"].getme().cstr(), "") == 0); WVFAIL(root2["dialer 2"].exists()); } WVTEST_MAIN("null generator") { UniConfRoot root("null:"); } // if this test compiles at all, we win! WVTEST_MAIN("type conversions") { UniConfRoot root("temp:"); UniConf cfg(root); cfg.setme("x"); cfg.setme(5); WVPASSEQ("5", cfg.getme("x")); WVPASSEQ("5", cfg.getme(5)); cfg["x"].setme("x"); cfg[5].setme("x"); int x = 5; WVPASSEQ("x", cfg[x].getme("x")); cfg[cfg.getme(5)].setme("x"); cfg.setme(cfg.getme(x)); cfg.setme(cfg.getmeint(x)); cfg.setmeint(cfg.getmeint(x)); cfg.setmeint(cfg.getme(x).num()); cfg[WvString(x)].setme("x"); cfg[WvFastString(x)].setme("x"); cfg[WvString(5)].setme("x"); cfg.setme(7); cfg[6].setme(*cfg); cfg.setme(cfg->num()); WVPASSEQ("7", *cfg); cfg.xset("sub", "y"); WVPASSEQ("y", *cfg["sub"]); WVPASSEQ("y", cfg.xget("sub", "foo")); WVPASSEQ(55, cfg.xgetint("sub", 55)); // unrecognizable string WVPASSEQ(7, cfg.xgetint(6)); cfg.xsetint("sub", 99); WVPASSEQ(99, cfg["sub"].getmeint(55)); WVPASSEQ("zz", cfg["blah"]->ifnull("zz")); } WVTEST_MAIN("case") { UniConfRoot root("temp:"); UniConf cfg(root); cfg.xset("eth0/IPAddr", "10"); WVPASSEQ("10", cfg.xget("eth0/IPAddr")); WVPASSEQ("10", cfg.xget("eth0/ipaddr")); } WVTEST_MAIN("haschildren() and exists()") { UniConfRoot root; { UniConf cfg(root); WVFAIL(cfg["/"].haschildren()); WVFAIL(cfg["/"].exists()); cfg.mount("temp:"); WVFAIL(cfg["/"].haschildren()); WVPASS(cfg["/"].exists()); } { UniConf cfg(root); WVFAIL(cfg["/bar"].haschildren()); WVFAIL(cfg["/bar"].exists()); cfg["/bar/config"].mount("temp:"); WVFAIL(cfg["/bar/config"].haschildren()); WVPASS(cfg["/bar/config"].exists()); //once something is mounted, parent keys should exist WVPASS(cfg["/"].haschildren()); WVPASS(cfg["/"].exists()); WVPASS(cfg["/bar"].haschildren()); WVPASS(cfg["/bar"].exists()); cfg.mount("temp:"); cfg.xset("/config/bar/foo", "goo"); WVPASS(cfg["/"].haschildren()); WVPASS(cfg["/"].exists()); WVFAIL(cfg["/foo"].exists()); cfg.xset("/foo", "bar"); WVPASS(cfg["/foo"].exists()); } } WVTEST_MAIN("section collapsing") { UniConfRoot r; WVPASSEQ(r[""][""]["/"]["simon"][""][""].fullkey().printable(), "simon/"); WVPASSEQ(r[""][""]["/"]["simon"][""]["/"].fullkey().printable(), "simon/"); } WVTEST_MAIN("fullkey()") { UniConfRoot root; root.mount("temp:"); UniConf cfg(root["cfg"]); cfg.xsetint("hello", 1); cfg.xsetint("hello/world", 2); WVPASSEQ(cfg["hello"].fullkey().printable(), "cfg/hello"); WVPASSEQ(cfg["hello/world"].fullkey(cfg).printable(), "hello/world"); WVPASSEQ(cfg["hello/world"].fullkey("cfg").printable(), "hello/world"); WVPASSEQ(cfg["hello/world"].fullkey("cfg/").printable(), "hello/world"); } static int itcount(const UniConf &cfg) { int count = 0; UniConf::Iter i(cfg); for (i.rewind(); i.next(); ) count++; return count; } static int ritcount(const UniConf &cfg) { int count = 0; UniConf::RecursiveIter i(cfg); for (i.rewind(); i.next(); ) count++; return count; } WVTEST_MAIN("iterators") { UniConfRoot root("temp:"); root["1"].setme("foo"); root["2"].setme("blah"); root["2/2b"].setme("sub"); root["x/y/z/a/b/1/2/3"].setme("something"); WVPASSEQ(itcount(root), 3); WVPASSEQ(itcount(root["2"]), 1); WVPASSEQ(itcount(root["1"]), 0); WVPASSEQ(itcount(root["2/2b"]), 0); WVPASSEQ(itcount(root["3"]), 0); WVPASSEQ(ritcount(root), 11); WVPASSEQ(ritcount(root["2"]), 1); WVPASSEQ(ritcount(root["1"]), 0); WVPASSEQ(ritcount(root["2/2b"]), 0); WVPASSEQ(ritcount(root["3"]), 0); WVPASSEQ(ritcount(root["x/y/z/a/b"]), 3); UniConf sub(root["x/y/z/a"]); UniConf::RecursiveIter i(sub); i.rewind(); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "b"); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "b/1"); } // bug 6869 static int compare(const UniConf &_a, const UniConf &_b) { return _a.key().compareto(_b.key()); } WVTEST_MAIN("sorted iterators") { UniConfRoot root("temp:"); root["3"].setme("foo1"); root["2"].setme("foo2"); root["1"].setme("foo3"); root["4"].setme("foo4"); UniConf sub(root); UniConf::Iter j(sub); for (j.rewind(); j.next(); ) wverr->print("fullkey=%s\n", j->fullkey()); UniConf::SortedIter i(sub, &compare); i.rewind(); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "1"); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "2"); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "3"); i.next(); WVPASSEQ(i->fullkey(sub).printable(), "4"); } WVTEST_MAIN("nested iterators") { UniConfRoot root("temp:"); UniConf cfg(root); UniConf::Iter i1(cfg); cfg["foo"].setmeint(1); cfg["/foo/bar"].setmeint(1); cfg["/foo/car/bar"].setmeint(1); WVPASS(cfg["foo"].getmeint()); for (i1.rewind(); i1.next();) { UniConf::RecursiveIter i2(cfg); for (i2.rewind(); i2.next();) { i2->getme(); } } WVPASS(cfg["foo"].getmeint()); WVPASS(cfg["/foo/bar"].getmeint()); } WVTEST_MAIN("mounting with paths prefixed by /") { UniConfRoot root("temp:"); UniConf cfg1(root["/config"]); UniConf cfg2(root["config"]); int i = 0; for (i = 0; i < 5; i++) root.xsetint(WvString("/config/bloing%s", i), 1); for (i = 0; i < 5; i++) { WVPASS(cfg1.xgetint(WvString("/bloing%s", i))); WVPASS(cfg2.xgetint(WvString("/bloing%s", i))); } UniConf::Iter iter1(cfg1); UniConf::Iter iter2(cfg1); i = 0; for (iter1.rewind(); iter1.next(); i++) WVPASS(iter1->getmeint()); i = 0; for (iter2.rewind(); iter2.next(); i++) WVPASS(iter2->getmeint()); } WVTEST_MAIN("Deleting while iterating") { UniConfRoot root("temp:"); char *foo = new char[250]; //to make sure the hash moves in memory for (int i = 0; i < 10; i++) { root.xsetint(i, i); root[i].xsetint(i, i); } UniConf::Iter i(root); char *foo2 = new char[250]; for (i.rewind(); i.next(); ) { // fprintf(stderr, "%s\n", i->getme().cstr()); root[i->key()].setme(WvString::null); if (i->getme() != WvString::null) i.rewind(); } deletev foo; deletev foo2; } void verify_recursive_iter(UniConfRoot &root) { // verify that recursive iteration works as expected UniConf::RecursiveIter i(root); i.rewind(); WVPASS(i.next()); WVPASSEQ(i().key().printable().cstr(), "subt"); WVPASSEQ(i().getme(), ""); WVPASS(i.next()); WVPASSEQ(i().key().printable().cstr(), "mayo"); WVPASSEQ(i().getme(), "baz"); WVFAIL(i.next()); // verify that non-recursive iteration doesn't go over keys // it's not supposed to UniConf::Iter j(root); j.rewind(); WVPASS(j.next()); WVPASSEQ(j().key().printable().cstr(), "subt"); WVPASSEQ(j().getme(), ""); WVFAIL(j.next()); } WVTEST_MAIN("Recursive iteration with no generator at root") { // distance of "2" between first mount and unmounted root UniConfRoot root1; root1["subt/mayo"].mount("temp:"); root1["subt/mayo"].setme("baz"); verify_recursive_iter(root1); // distance of "1" between first mount and unmounted root UniConfRoot root2; root2["subt"].mount("temp:"); root2["subt/mayo"].setme("baz"); verify_recursive_iter(root2); } wvstreams-4.6.1/uniconf/t/unicachegen.t.cc0000644000175000001440000000461411036722347017532 0ustar wlachusers#include "unitempgen.h" #include "unicachegen.h" #include "uniconfroot.h" #include "uniconfgen-sanitytest.h" #include "unislowgen.h" #include "uniwatch.h" #include "wvtest.h" class WatchReceiver { public: WatchReceiver(WvStringParm _expected_key, WvStringParm _expected_value) : cbs(0), expected_key(_expected_key), expected_value(_expected_value) {} void callback(const UniConf keyconf, const UniConfKey key) { printf("key: %s expected key: %s\n", key.printable().cstr(), expected_key.cstr()); WVPASS(key == expected_key); WVPASS(keyconf[key].getme() == expected_value); cbs++; } int cbs; private: WvString expected_key; WvString expected_value; }; WVTEST_MAIN("UniCacheGen Sanity Test") { UniCacheGen *gen = new UniCacheGen(new UniTempGen()); UniConfGenSanityTester::sanity_test(gen, "cache:temp:"); WVRELEASE(gen); } WVTEST_MAIN("cache basics") { UniTempGen *t = new UniTempGen; UniSlowGen *slow = new UniSlowGen(t); UniConfRoot cacheroot; UniCacheGen *c = new UniCacheGen(slow); cacheroot.mountgen(c, true); WVPASSEQ(slow->how_slow(), 2); slow->reset_slow(); // 1 level of hierarchy t->set("foo", "bar"); WVPASS(cacheroot["foo"].getme() == "bar"); WVFAIL(cacheroot["foo"].haschildren()); cacheroot["bar"].setme("foo"); WVPASS(t->get("bar") == "foo"); WVFAIL(t->haschildren("bar")); // 3 levels of hierarchy t->set("foo/baz/beep", "bar"); WVPASS(cacheroot["foo/baz/beep"].getme() == "bar"); WVFAIL(cacheroot["foo/baz/beep"].haschildren()); cacheroot["foo/baz/boop"].setme("foo"); WVPASS(t->get("foo/baz/boop") == "foo"); WVFAIL(t->haschildren("foo/baz/boop")); // (recursive) notifications of the cache WatchReceiver cache_received("beep", "foo"); UniWatch cache_watch(cacheroot["/foo/baz"], wv::bind(&WatchReceiver::callback, &cache_received, _1, _2)); t->set("foo/baz/beep", "foo"); WVPASS(cache_received.cbs == 1); // make sure that we are _not_ notified if the // key is not a subkey of the one we are watching t->set("foo", "foo"); WVPASS(cache_received.cbs == 1); // if the cache works correctly, nothing we did since the constructor // should have incurred any slow operations at all. WVPASSEQ(slow->how_slow(), 0); } wvstreams-4.6.1/uniconf/t/uniconfgen-sanitytest.h0000644000175000001440000000525511044443657021226 0ustar wlachusers// This class is used to test the basic sanity of a UniConf generator. This // tests things that might not be strictly guaranteed by UniConf, but are true // for all known generators. If your generator fails these, you either need // to rethink a bit, or put some very large warnings on your generator. #ifndef UNICONFGEN_SANITYTEST_H #define UNICONFGEN_SANITYTEST_H #include "wvstring.h" #include "wvlog.h" #include "uniconf.h" #include "uniconfkey.h" class IUniConfGen; class UniConfGenSanityTester { public: static void clear_generator(IUniConfGen *g); static void sanity_test(IUniConfGen *g, WvStringParm moniker); static void test_trailing_slashes(IUniConfGen *g, WvStringParm moniker); static void test_haschildren_gen(IUniConfGen *g); static void test_haschildren_moniker(WvStringParm moniker); static void test_iter_sanity(WvStringParm moniker); static void test_recursive_iter_sanity(WvStringParm moniker); // Same as the one in unicachegen.t.cc class CbCounter { public: CbCounter() : cbs(0), log("Callback counter", WvLog::Info) { } void callback(const UniConf keyconf, const UniConfKey key) { log("Got callback for key '%s', value '%s'\n", keyconf[key].fullkey().printable(), keyconf[key].getme()); cbs++; } int cbs; WvLog log; }; }; // Create a UniConfDaemon upon instantiation. By default, the server listens // to the given socket name, and mounts the given moniker, and doesn't do much // else. The server is killed and its socket is unlinked by the destructor. class UniConfTestDaemon { pid_t server_pid; WvString sockname; WvString server_moniker; public: typedef wv::function UniConfDaemonServerCb; // A default server callback that doesn't do anything interesting, just // mounts the given moniker on the given socket. static void boring_server_cb(WvStringParm sockname, WvStringParm server_moniker); // Just like the boring server, but increments a key every time through // its select loop, to generate some notifications. static void autoinc_server_cb(WvStringParm sockname, WvStringParm server_moniker); // server_cb is the main body of the server. It must not return. UniConfTestDaemon(WvStringParm _sockname, WvStringParm _server_moniker, UniConfDaemonServerCb server_cb = boring_server_cb); ~UniConfTestDaemon(); pid_t get_pid() { return server_pid; } WvString get_sockname() { return sockname; } WvString get_moniker() { return server_moniker; } }; #endif wvstreams-4.6.1/uniconf/t/uniconfgen.t.cc0000644000175000001440000000053511036722347017412 0ustar wlachusers#include "wvtest.h" #include "uniconfgen.h" #include "wvmoniker.h" static void cb(const UniConfKey &, WvStringParm) { } WVTEST_MAIN("null generator, setcallback, delete") { IUniConfGen *gen = wvcreate("null:"); WVPASS(gen); if (gen) { gen->add_callback(gen, cb); gen->del_callback(gen); } WVRELEASE(gen); } wvstreams-4.6.1/uniconf/t/unipermgen.t.cc0000644000175000001440000002173611036722347017436 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "uniwatch.h" #include "unitempgen.h" #include "unipermgen.h" #include "unisecuregen.h" #include "uniunwrapgen.h" #include "unidefgen.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniPermGen Sanity Test") { UniPermGen *gen = new UniPermGen("temp:"); // No moniker for the PermGen, sigh. UniConfGenSanityTester::sanity_test(gen, WvString::null); WVRELEASE(gen); } // Same as the one in unicachegen.t.cc class CbCounter { public: CbCounter() : cbs(0) {} void callback(const UniConf keyconf, const UniConfKey key) { cbs++; } int cbs; }; WVTEST_MAIN("permgen basic") { UniConfRoot root; IUniConfGen *tempgen = new UniTempGen(); UniPermGen permgen("temp:"); WvStringList defgroups; permgen.setexec(UniConfKey("/"), UniPermGen::WORLD, true); permgen.setread(UniConfKey("/"), UniPermGen::WORLD, true); permgen.setwrite(UniConfKey("/"), UniPermGen::WORLD, true); UniSecureGen *sec = new UniSecureGen(tempgen, &permgen); fprintf(stderr, "Mounting securegen\n"); WVPASS(root.mountgen(sec)); fprintf(stderr, "Done\n"); sec->setcredentials("notroot", defgroups); root["/open/foo"].setmeint(1); root["/open/bar"].setmeint(1); root["/exec_only/read"].setmeint(1); root["/exec_only/noread"].setmeint(1); root["/exec_only/read_noexec"].setmeint(1); // should be read root["/exec_only/read_noexec/read"].setmeint(1); // should be unreadable root["/exec_only/read_noexec/read/exec"].setmeint(1); // should be unreadable root["/exec_only/read_noexec/exec/read"].setmeint(1); // should be unreadable root["/exec_only/noread_noexec/read"].setmeint(1); // should be unreadable root["/closed/foo"].setmeint(1); root["/closed/bar"].setmeint(1); root["/closed/exec/foo"].setmeint(1); permgen.setowner("/", "root"); permgen.chmod(UniConfKey("/open"), 7, 7, 5); permgen.chmod(UniConfKey("/"), 7, 7, 1); permgen.chmod(UniConfKey("/exec_only"), 7, 7, 1); // FIXME: chmodding one key seems to automatically chmod its // children. Is this correct? permgen.chmod(UniConfKey("/exec_only/read"), 7, 7, 4); permgen.chmod(UniConfKey("/exec_only/noread"), 7, 7, 0); permgen.chmod(UniConfKey("/exec_only/noread_noexec"), 7, 7, 0); permgen.chmod(UniConfKey("/exec_only/read_noexec"), 7, 7, 4); permgen.chmod(UniConfKey("/exec_only/read_noexec/read"), 7, 7, 4); permgen.chmod(UniConfKey("/exec_only/read_noexec/exec"), 7, 7, 1); permgen.chmod(UniConfKey("/exec_only/read_noexec/exec/read"), 7, 7, 4); permgen.chmod(UniConfKey("/closed"), 7, 7, 0); permgen.chmod(UniConfKey("/closed/exec"), 7, 7, 1); permgen.chmod(UniConfKey("/closed/exec/foo"), 7, 7, 5); // testing "get" WVPASS(root["/open"].getme() == ""); WVPASS(root["/open/foo"].getme() == "1"); WVPASS(root["/open/bar"].getme() == "1"); WVPASS(root["/exec_only"].getme() == WvString::null); WVPASS(root["/exec_only/read"].getme() == "1"); WVPASS(root["/exec_only/noread"].getme() == WvString::null); WVPASS(root["/exec_only/read_noexec"].getme() == "1"); WVPASS(root["/exec_only/read_noexec/read"].getme() == WvString::null); WVPASS(root["/exec_only/read_noexec/exec"].getme() == WvString::null); WVPASS(root["/exec_only/read_noexec/exec/read"].getme() == WvString::null); WVPASS(root["/closed"].getme() == WvString::null); WVPASS(root["/closed/foo"].getme() == WvString::null); WVPASS(root["/closed/bar"].getme() == WvString::null); // testing "set" (obviously incomplete) root["/exec_only"].setmeint(1); WVPASS(root["/exec_only"].getme() == WvString::null); root["/closed"].setmeint(1); WVPASS(root["/closed"].getme() == WvString::null); // testing iteration UniConf::Iter i(root); i.rewind(); for (int k=0; k<3; k++) { WVPASS(i.next()); if (i.ptr()->key() == "closed") { WVPASS(i.ptr()->getme() == WvString::null); WVPASS(i._value() == WvString::null); } else if (i.ptr()->key() == "exec_only") { WVPASS(i.ptr()->getme() == WvString::null); WVPASS(i._value() == WvString::null); } else if (i.ptr()->key() == "open") { WVPASS(i.ptr()->getme() == ""); WVPASS(i._value() == ""); } } WVFAIL(i.next()); // testing recursive iteration UniConf::RecursiveIter j(root); j.rewind(); for (int k=0; k<3; k++) { WVPASS(j.next()); if (j.ptr()->key() == "closed") { WVPASS(j.ptr()->getme() == WvString::null); WVPASS(j._value() == WvString::null); } else if (j.ptr()->key() == "exec_only") { WVPASS(j.ptr()->getme() == WvString::null); WVPASS(j._value() == WvString::null); for (int l=0; l<4; l++) { WVPASS(j.next()); if (j.ptr()->key() == "read") { WVPASS(j.ptr()->getme() == "1"); WVPASS(j._value() == "1"); } else if (j.ptr()->key() == "noread_noexec") { WVPASS(j.ptr()->getme() == WvString::null); WVPASS(j._value() == WvString::null); } else if (j.ptr()->key() == "read_noexec") { WVPASS(j.ptr()->getme() == "1"); WVPASS(j._value() == "1"); } else if (j.ptr()->key() == "noread") { WVPASS(j.ptr()->getme() == WvString::null); WVPASS(j._value() == WvString::null); } } } else if (j.ptr()->key() == "open") { WVPASS(j.ptr()->getme() == ""); WVPASS(j._value() == ""); for (int l=0; l<2; l++) { WVPASS(j.next()); if (j.ptr()->key() == "bar") { WVPASS(j.ptr()->getme() == "1"); WVPASS(j._value() == "1"); } else if (j.ptr()->key() == "foo") { WVPASS(j.ptr()->getme() == "1"); WVPASS(j._value() == "1"); } } } } WVFAIL(j.next()); // Checking notifications.. (we will assume that we are getting the // right keys for now) CbCounter notifywatcher; UniWatch watcher(root["/"], wv::bind(&CbCounter::callback, ¬ifywatcher, _1, _2)); tempgen->set("open/foo", "2"); WVPASS(notifywatcher.cbs == 1); tempgen->set("exec_only/read", "2"); WVPASS(notifywatcher.cbs == 2); tempgen->set("exec_only/noread", "2"); WVPASS(notifywatcher.cbs == 2); tempgen->set("exec_only/read_noexec", "2"); WVPASS(notifywatcher.cbs == 3); tempgen->set("exec_only/read_noexec/read", "2"); WVPASS(notifywatcher.cbs == 3); tempgen->set("exec_only/read_noexec/exec/read", "2"); WVPASS(notifywatcher.cbs == 3); tempgen->set("closed/foo", "2"); WVPASS(notifywatcher.cbs == 3); // Test appropriate granting of permissions (recall the owner is root) sec->setcredentials("root", defgroups); WVPASS(root["/closed/foo"].getme() == "2"); WVPASS(root["/exec_only/noread_noexec/read"].getme() == "1"); UniConf::Iter k(root["/exec_only/noread_noexec"]); k.rewind(); WVPASS(k.next()); WVPASS(k.ptr()->key() == "read"); WVPASS(k._value() == "1"); WVFAIL(k.next()); } WVTEST_MAIN("permgen + defaultgen") { UniConfRoot root; IUniConfGen *tempgen = new UniTempGen(); IUniConfGen *innerperm = new UniTempGen(); IUniConfGen *innerdef = new UniDefGen(innerperm); UniPermGen permgen(innerdef); WvStringList nogroups; WvStringList rootgroup; rootgroup.append("root"); innerdef->set("cfg/*/world-exec", "false"); UniSecureGen *sec = new UniSecureGen(tempgen, &permgen); WVPASS(root.mountgen(sec)); permgen.setowner("/", "root"); permgen.setgroup("/", "root"); sec->setcredentials("root", nogroups); permgen.chmod(UniConfKey("/"), 7, 7, 7); // test that readable/writable stuff works as expected (default does // not override root) root["/cfg/users/foo"].setme("123"); WVPASS(root["/cfg/users/foo"].getme() == "123"); // make sure that the same is true for groups sec->setcredentials("notroot", rootgroup); root["/cfg/users/foo"].setme("456"); WVPASS(root["/cfg/users/foo"].getme() == "456"); // test execute permission denial by default, and test override root["cfg/exec/read"].setmeint(1); sec->setcredentials("notroot", nogroups); WVPASS(root["cfg/exec/read"].getme() == WvString::null); innerdef->set("cfg/exec/world-exec", "true"); WVPASS(root["cfg/exec/read"].getme() == "1"); // probably don't need to test read, write explicitly as those cases // are mostly covered by the above tests } wvstreams-4.6.1/uniconf/t/uniautogen.t.cc0000644000175000001440000000170011036722347017430 0ustar wlachusers#include "uniautogen.h" #include "uniconfroot.h" #include "wvtest.h" WVTEST_MAIN("basics") { uniautogen_moniker = "default:ini:tmp.ini"; { UniConfRoot r("ini:tmp.ini"); r.xset("/a/b/c", "ini:tmp.ini"); r.xset("/a/*", "ini:tmp2.ini"); r.xset("/a", "ini:tmp3.ini"); r.commit(); } { UniConfRoot r("ini:tmp2.ini"); r.xset("/2/2/2", "tmp2.ini"); r.xset("/1/1/1", "also tmp2.ini"); r.commit(); } { UniConfRoot r("ini:tmp3.ini"); r.xset("/3/3/3", "tmp3.ini"); r.xset("/1/1/1", "also tmp3.ini"); r.commit(); } WVPASSEQ(UniConfRoot("auto:a/b/c").xget("a/b/c"), "ini:tmp.ini"); WVPASSEQ(UniConfRoot("auto:a/b/c/a/b").xget("c"), "ini:tmp.ini"); WVPASSEQ(UniConfRoot("auto:a/x").xget("2/2/2"), "tmp2.ini"); WVPASSEQ(UniConfRoot("auto:a/*").xget("2/2/2"), "tmp2.ini"); WVPASSEQ(UniConfRoot("auto:a/x/2/2").xget("2"), "tmp2.ini"); WVPASSEQ(UniConfRoot("auto:a").xget("3/3/3"), "tmp3.ini"); } wvstreams-4.6.1/uniconf/t/unicallbackgen.t.cc0000644000175000001440000000476511036722347020232 0ustar wlachusers#include "wvtest.h" #include "unicallbackgen.h" #include "uniconfgen-sanitytest.h" class AutoIncrementer { int value; public: AutoIncrementer() : value(0) {} WvString get(const UniConfKey &) { return value++; } void set(const UniConfKey &, WvStringParm _value) { value = _value.num(); } }; WVTEST_MAIN("UniCallbackGen Sanity Test") { UniCallbackGen *gen = new UniCallbackGen; // The callback generator doesn't have a moniker UniConfGenSanityTester::sanity_test(gen, WvString::null); WVRELEASE(gen); } WVTEST_MAIN("non-dynamic") { AutoIncrementer ai; UniCallbackGen g; WVPASS(!g.get("key")); g.setgetcallback("key", wv::bind(&AutoIncrementer::get, &ai, _1)); WVPASS((g.set("key", "foo"), g.get("key")) == WvString(0)); WVPASS((g.set("key", "foo"), g.get("key")) == WvString(1)); WVPASS((g.set("key", "foo"), g.get("key")) == WvString(2)); WVPASS((g.set("key", "foo"), g.get("key")) == WvString(3)); WVPASS((g.set("key", "foo"), g.get("key")) == WvString(4)); g.setgetcallback("key", UniCallbackGenGetCallback()); WVPASS((g.set("key", "foo"), g.get("key") == WvString("foo"))); } WVTEST_MAIN("dynamic") { AutoIncrementer ai; UniCallbackGen g; WVPASS(!g.get("key")); g.update_after_set = false; g.update_before_get = true; g.setgetcallback("key", wv::bind(&AutoIncrementer::get, &ai, _1)); WVPASS(g.get("key") == WvString(0)); WVPASS(g.get("key") == WvString(1)); WVPASS(g.get("key") == WvString(2)); WVPASS(g.get("key") == WvString(3)); WVPASS(g.get("key") == WvString(4)); g.setgetcallback("key", UniCallbackGenGetCallback()); WVPASS(!g.get("key")); } WVTEST_MAIN("set") { AutoIncrementer ai; UniCallbackGen g; WVPASS(!g.get("key")); g.update_after_set = false; g.update_before_get = true; g.setgetcallback("key", wv::bind(&AutoIncrementer::get, &ai, _1)); g.setsetcallback("key", wv::bind(&AutoIncrementer::set, &ai, _1, _2)); WVPASS(g.get("key") == WvString(0)); WVPASS(g.get("key") == WvString(1)); WVPASS(g.get("key") == WvString(2)); WVPASS(g.get("key") == WvString(3)); WVPASS(g.get("key") == WvString(4)); g.set("key", 0); WVPASS(g.get("key") == WvString(0)); WVPASS(g.get("key") == WvString(1)); WVPASS(g.get("key") == WvString(2)); WVPASS(g.get("key") == WvString(3)); WVPASS(g.get("key") == WvString(4)); g.setgetcallback("key", UniCallbackGenGetCallback()); WVPASS(!g.get("key")); } wvstreams-4.6.1/uniconf/t/uniclientgen.t.cc0000644000175000001440000001762211077124114017741 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "unitempgen.h" #include "uniretrygen.h" #include "uniconfdaemon.h" #include "uniconfgen-sanitytest.h" #include "uniclientgen.h" #include "uniinigen.h" #include "wvunixsocket.h" #include "wvfileutils.h" #include "wvfile.h" #include "uniwatch.h" #include "wvstrutils.h" #include "wvtimeutils.h" #include #include class WvDebugUnixConn : public WvUnixConn { WvLog log; WvString socket; public: WvDebugUnixConn(WvString _name, WvStringParm _socket) : WvUnixConn(_socket), log(_name, WvLog::Debug), socket(_socket) { log("Created UNIX connection on %s\n", socket); } ~WvDebugUnixConn() { log("Destroyed UNIX connection on %s\n", socket); } size_t uread(void *buf, size_t count) { size_t result = WvUnixConn::uread(buf, count); if (result > 0) log("<- %s\n", cstr_escape(buf, result)); return result; } size_t uwrite(const void *buf, size_t count) { size_t result = WvUnixConn::uwrite(buf, count); if (result > 0) log("-> %s\n", cstr_escape(buf, result)); return result; } }; static int delta_count; static void delta_callback(const UniConf &, const UniConfKey &) { ++delta_count; } typedef wv::function client_factory_t; // Returns a new UniClientGen, using a non-logging underlying stream. // unix_conn is set to a pointer to the underlying unix stream. static UniClientGen *quiet_client_factory(WvStringParm name, WvStringParm sockname, WvUnixConn *&unix_conn) { return new UniClientGen(unix_conn = new WvUnixConn(sockname)); } // Set the default client_factory to debug_client_factory if you want to see // what goes through the connection. static UniClientGen *create_client_conn(WvString name, WvString sockname, client_factory_t client_factory = quiet_client_factory) { UniClientGen *client_gen = NULL; while (true) { WvUnixConn *unix_conn; client_gen = client_factory(name, sockname, unix_conn); if (!unix_conn || !unix_conn->isok() || !client_gen || !client_gen->isok()) { WVRELEASE(client_gen); wvout->print("Failed to connect, retrying...\n"); wvdelay(100); } else break; } return client_gen; } WVTEST_MAIN("UniClientGen Sanity Test") { signal(SIGPIPE, SIG_IGN); WvString sockname = wvtmpfilename("uniclientgen.t-sock"); UniConfTestDaemon daemon(sockname, "temp:"); UniClientGen *gen = create_client_conn("sanity", sockname); UniConfGenSanityTester::sanity_test(gen, WvString("unix:%s", sockname)); WVRELEASE(gen); } WVTEST_MAIN("deltas") { signal(SIGPIPE, SIG_IGN); UniConfRoot uniconf; WvString sockname = wvtmpfilename("uniclientgen.t-sock"); unlink(sockname); UniConfTestDaemon daemon(sockname, "temp:", UniConfTestDaemon::autoinc_server_cb); UniClientGen *client_gen = create_client_conn("deltas", sockname); uniconf.mountgen(client_gen); int old_delta_count = delta_count = 0; uniconf.add_callback(client_gen, "", delta_callback, false); int i; for (i=0; i<100; ++i) { client_gen->refresh(); wvdelay(1); } WVPASS(delta_count > old_delta_count); } static time_t file_time(WvStringParm filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_mtime; else { wverr->print("stat(%s) failed: %s\n", filename, strerror(errno)); return -1; } } WVTEST_MAIN("commit") { signal(SIGPIPE, SIG_IGN); UniConfRoot uniconf; WvString ini_file("/tmp/wvtest-uniclientgen-commit-%s.ini", getpid()); unlink(ini_file); WvString sockname = wvtmpfilename("uniclientgen.t-sock"); UniConfTestDaemon daemon(sockname, WvString("ini:%s", ini_file)); UniClientGen *client_gen = create_client_conn("commit", sockname); uniconf.mountgen(client_gen); uniconf.setmeint(0); uniconf.commit(); time_t old_file_time = file_time(ini_file); WVPASS(old_file_time != -1); WVPASS(old_file_time <= time(NULL)); // utime the ini file into the past time_t real_old_file_time = old_file_time - 5000; utimbuf buf; buf.actime = real_old_file_time; buf.modtime = real_old_file_time; WVPASSEQ(utime(ini_file, &buf), 0); uniconf.setmeint(1); uniconf.commit(); time_t new_file_time = file_time(ini_file); WVPASS(new_file_time != -1); WVPASS(new_file_time > real_old_file_time); unlink(ini_file); } WVTEST_MAIN("refresh") { signal(SIGPIPE, SIG_IGN); UniConfRoot uniconf; WvString ini_file("/tmp/wvtest-uniclientgen-refresh-%s.ini", getpid()); unlink(ini_file); WvString sockname = wvtmpfilename("uniclientgen.t-sock"); UniConfTestDaemon daemon(sockname, WvString("ini:%s", ini_file)); UniClientGen *client_gen = create_client_conn("refresh", sockname); uniconf.mountgen(client_gen); WVPASS(uniconf.xget("key") != "value"); WvFile ini_fd(ini_file, O_WRONLY | O_APPEND | O_CREAT); ini_fd.print("[]\nkey = value\n"); ini_fd.close(); WVPASS(uniconf.refresh()); WVPASS(uniconf.xget("key") == "value"); unlink(ini_file); } #if 0 // Can't run this test -- it takes at least 60 seconds... WVTEST_MAIN("dead uniconfd") { signal(SIGPIPE, SIG_IGN); UniConfRoot uniconf; WvString sockname = get_sockname(); pid_t child = wvfork(); if (child == 0) { UniConfDaemon daemon(uniconf, false, NULL); daemon.setupunixsocket(sockname); WvIStreamList::globallist.append(&daemon, false, "uniconf daemon"); while (true) { WvIStreamList::globallist.runonce(); } _exit(0); } else { WVPASS(child >= 0); UniClientGen *client_gen; while (true) { WvUnixConn *unix_conn; client_gen = new UniClientGen( unix_conn = new WvUnixConn(sockname)); if (!unix_conn || !unix_conn->isok() || !client_gen || !client_gen->isok()) { WVRELEASE(client_gen); wvout->print("Failed to connect, retrying...\n"); wvdelay(100); } else break; } uniconf.mountgen(client_gen); kill(child, SIGSTOP); uniconf.getme(); WVFAIL(client_gen->isok()); kill(child, 9); pid_t rv; while ((rv = waitpid(child, NULL, 0)) != child) { // in case a signal is in the process of being delivered.. if (rv == -1 && errno != EINTR) break; } WVPASS(rv == child); } } #endif int save_callback_calls; static void save_callback() { ++save_callback_calls; } WVTEST_MAIN("SaveCallback") { signal(SIGPIPE, SIG_IGN); UniConfRoot uniconf; WvString ini_file("/tmp/wvtest-uniclientgen-refresh-%s.ini", getpid()); unlink(ini_file); UniIniGen *ini_gen = new UniIniGen(ini_file, 0600, save_callback); uniconf.mountgen(ini_gen); int items; for (items = 0; items < 5; items++) uniconf["Items"].xsetint(items, items); save_callback_calls = 0; uniconf.commit(); WVPASS(save_callback_calls >= items); unlink(ini_file); } WVTEST_MAIN("timeout") { signal(SIGPIPE, SIG_IGN); WvString sockname = wvtmpfilename("unisubtreegen.t-sock"); unlink(sockname); UniConfTestDaemon daemon(sockname, "temp:"); UniConfRoot uniconf; UniClientGen *client_gen = create_client_conn("timeout", sockname); uniconf.mountgen(client_gen); client_gen->set_timeout(1000); uniconf.getme(); WVPASS(client_gen->isok()); kill(daemon.get_pid(), SIGSTOP); uniconf.getme(); WVPASS(!client_gen->isok()); kill(daemon.get_pid(), SIGCONT); } wvstreams-4.6.1/uniconf/t/unidefgen.t.cc0000644000175000001440000000516011036722347017222 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "unidefgen.h" #include "unitempgen.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniDefGen Sanity Test") { UniDefGen *gen = new UniDefGen(new UniTempGen()); UniConfGenSanityTester::sanity_test(gen, "default:temp:"); WVRELEASE(gen); } WVTEST_MAIN("single") { UniConfRoot cfg("default:temp:"); cfg["/users/*"].setme("*1"); cfg["/*/pooper"].setme("*1"); cfg["/*/wonker"].setme("bonker"); cfg["/*/foo"].setme("*3"); cfg["/baz/foo"].setme("foobaz"); WVPASS(cfg["/snooper/pooper"].exists()); WVPASS(cfg["/snooper"].exists()); WVPASS(cfg["/snooper"].haschildren()); WVPASS(cfg["users/blah"].exists()); WVFAIL(cfg["/users/blah"].haschildren()); WVFAIL(cfg["/definitely/not/here"].exists()); WVPASS(cfg["/definitely/not/here"].getme().isnull()); WVPASSEQ(cfg["/snooper/pooper"].getme(), "snooper"); WVPASSEQ(cfg["/bob/wonker"].getme(), "bonker"); // FIXME: Is this the right behaviour? unidefgen.h says this is "undefined" WVPASSEQ(cfg["/bar/foo"].getme(), ""); WVPASSEQ(cfg["/baz/foo"].getme(), "foobaz"); cfg["/users/pooper"].setme("smarch"); WVPASSEQ(cfg["/users/billybob"].getme(), "billybob"); WVPASSEQ(cfg["/users/pooper"].getme(), "smarch"); } WVTEST_MAIN("multi") { UniConfRoot cfg("default:temp:"); cfg["/*/silly/*/billy"].setme("*1"); cfg["/willy/*/nilly/*"].setme("*2"); cfg["/*/*/yoink"].setme("boink"); cfg["/foo/silly/bar/billy"].setme("barfoo"); cfg["/willy/bar/nilly/foo"].setme("foobar"); WVPASSEQ(cfg["/cake/pie/yoink"].getme(), "boink"); WVPASSEQ(cfg["/foo/silly/bar/billy"].getme(), "barfoo"); WVPASSEQ(cfg["/bar/silly/foo/billy"].getme(), "foo"); WVPASSEQ(cfg["/willy/bar/nilly/foo"].getme(), "foobar"); WVPASSEQ(cfg["/willy/foo/nilly/bar"].getme(), "foo"); } #if 0 //FIXME:I don't know whether this is supposed to work or not. (pcolijn) // It doesn't right now; if it's supposed to, uncomment and fix! // // apenwarr 2004/08/04: it's not supposed to work right now, but it's probably // a good idea. WVTEST_MAIN("phrases") { UniConfRoot cfg("default:temp:"); cfg["/*/foo/*/bar"].setme("*1 blah *2"); cfg["/*/wonk/bonk/*"].setme("*2 blah *1"); cfg["/zorp/foo/bork/bar"].setme("zorpbork"); cfg["/plonk/wonk/bonk/honk"].setme("plonkhonk"); WVPASSEQ(cfg["/baz/foo/zoo/bar"].getme(), "zoo blah baz"); WVPASSEQ(cfg["/zorp/foo/bork/bar"].getme(), "zorpbork"); WVPASSEQ(cfg["/turd/wonk/bonk/ferguson"].getme(), "turd blah ferguson"); WVPASSEQ(cfg["/plonk/wonk/bonk/honk"].getme(), "plonkhonk"); } #endif wvstreams-4.6.1/uniconf/t/unitransactiongen.t.cc0000644000175000001440000005550311077124114021010 0ustar wlachusers#include #include #include "uniclientgen.h" #include "uniconf.h" #include "uniconfdaemon.h" #include "uniconfgen-sanitytest.h" #include "uniconfroot.h" #include "unilistgen.h" #include "unitempgen.h" #include "unitransaction.h" #include "unitransactiongen.h" #include "uniunwrapgen.h" #include "uniwatch.h" #include "wvfile.h" #include "wvtest.h" #include "wvunixsocket.h" using std::map; WVTEST_MAIN("UniTransactionGen Sanity Test") { UniTransactionGen *gen = new UniTransactionGen(new UniTempGen()); UniConfGenSanityTester::sanity_test(gen, "transaction:temp:"); WVRELEASE(gen); } static map callbacks1; static map callbacks2; static void check_callback2(const UniConf &handle, const UniConfKey &key) { wverr->print("Callback on key \"%s\" with value \"%s\".\n", key, handle[key].getme()); bool expected = callbacks2.find(key) != callbacks2.end(); WVPASS(expected); if (expected) { WVPASSEQ(callbacks2[key], handle[key].getme()); callbacks2.erase(key); } } static void check_callback1(const UniConf &handle, const UniConfKey &key) { wverr->print("Callback on key \"%s\" with value \"%s\".\n", key, handle[key].getme()); bool expected = callbacks1.find(key) != callbacks1.end(); WVPASS(expected); if (expected) { WVPASSEQ(callbacks1[key], handle[key].getme()); callbacks1.erase(key); } } static UniConfCallback callback2(check_callback2); static UniConfCallback callback1(check_callback1); static void check_iterator(map &_map, const UniConf &handle) { UniConf::RecursiveIter i(handle); for (i.rewind(); i.next();) { bool expected = _map.find(i.ptr()->fullkey()) != _map.end(); WVPASS(expected); if (expected) { WVPASSEQ(_map[i.ptr()->fullkey()], i.ptr()->getme()); _map.erase(i.ptr()->fullkey()); } } WVPASS(_map.empty()); _map.clear(); } WVTEST_MAIN("UniTransactionGen functionality test") { UniTempGen *gen = new UniTempGen(); UniConfRoot one(gen); UniConfRoot two(new UniTransactionGen(new UniUnwrapGen(one))); UniWatch mywatch2(two, callback2); // Test a TransactionGen with no changes. callbacks2["cfg"] = "Filled"; callbacks2["cfg/OpenWall"] = ""; callbacks2["cfg/OpenWall/Harden Proc"] = 1; callbacks2["cfg/OpenWall/Harden RLIMIT"] = 1; callbacks2["cfg/OpenWall/Harden Link"] = 1; callbacks2["cfg/OpenWall/Harden Stack"] = 1; one.xset("cfg", "Filled"); one.xset("cfg/OpenWall/Harden Proc", 1); one.xset("cfg/OpenWall/Harden RLIMIT", 1); one.xset("cfg/OpenWall/Harden Link", 1); one.xset("cfg/OpenWall/Harden Stack", 1); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget(""), ""); WVPASSEQ(two.xget("cfg"), "Filled"); WVPASSEQ(two.xget("cfg/OpenWall"), ""); WVPASSEQ(two.xget("cfg/OpenWall/Harden Proc"), "1"); WVPASSEQ(two.xget("cfg/OpenWall/Harden RLIMIT"), "1"); WVPASSEQ(two.xget("cfg/OpenWall/Harden Link"), "1"); WVPASSEQ(two.xget("cfg/OpenWall/Harden Stack"), "1"); WVPASSEQ(two.xget("cfg/foo"), WvString::null); callbacks2["cfg"] = "Filled"; callbacks2["cfg/OpenWall"] = ""; callbacks2["cfg/OpenWall/Harden Proc"] = 1; callbacks2["cfg/OpenWall/Harden RLIMIT"] = 1; callbacks2["cfg/OpenWall/Harden Link"] = 1; callbacks2["cfg/OpenWall/Harden Stack"] = 1; check_iterator(callbacks2, two); callbacks2["cfg/OpenWall/Harden Proc"] = WvString::null; callbacks2["cfg/OpenWall/Harden Link"] = WvString::null; callbacks2["cfg/OpenWall/Harden RLIMIT"] = WvString::null; callbacks2["cfg/OpenWall/Harden Stack"] = WvString::null; callbacks2["cfg/OpenWall"] = WvString::null; callbacks2["cfg"] = WvString::null; callbacks2[""] = WvString::null; one.xset("", WvString::null); WVPASS(callbacks2.empty()); callbacks2.clear(); // Test gets and callbacks on new values. callbacks2[""] = ""; callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; two.xset("cfg/Global/Have Disk", 1); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget(""), ""); WVPASSEQ(two.xget("cfg"), ""); WVPASSEQ(two.xget("cfg/Global"), ""); WVPASSEQ(two.xget("cfg/Global/Have Disk"), "1"); WVPASSEQ(two.xget("cfg/bar"), WvString::null); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; check_iterator(callbacks2, two); // Test that our changes override their changes. one.xset("cfg/Global/Have Disk", 0); WVPASSEQ(two.xget("cfg/Global/Have Disk"), "1"); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; check_iterator(callbacks2, two); // Test that they DON'T override their changes to child keys. callbacks2["cfg/Global/Have Disk/Really Have Disk"] = 1; one.xset("cfg/Global/Have Disk/Really Have Disk", 1); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/Global/Have Disk/Really Have Disk"), "1"); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; callbacks2["cfg/Global/Have Disk/Really Have Disk"] = 1; check_iterator(callbacks2, two); // Test that underlying callbacks on keys changed to !! strings // that previously were ! strings and were created due to a change // are received. callbacks2["cfg"] = "exists"; one.xset("cfg", "exists"); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg"), "exists"); callbacks2["cfg"] = "exists"; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; callbacks2["cfg/Global/Have Disk/Really Have Disk"] = 1; check_iterator(callbacks2, two); // Test that it changes back to the empty string. Also, after r4_2, // test that deleting keys in the underlying generator to which we // are making changes other than a tree replacement succeeds in // causing the necessary callbacks for children of that key. callbacks2["cfg"] = ""; callbacks2["cfg/Global/Have Disk/Really Have Disk"] = WvString::null; one.xset("cfg", WvString::null); WVPASS(callbacks2.find("cfg") == callbacks2.end()); WVPASS(callbacks2.find("cfg/Global/Have Disk/Really Have Disk") == callbacks2.end()); callbacks2.clear(); WVPASSEQ(two.xget("cfg"), ""); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; check_iterator(callbacks2, two); // Test that underlying callbacks on keys that previously were ! strings, // were created due to a change, and are STILL ! strings are NOT // received. one.xset("cfg/Global", ""); WVPASSEQ(two.xget("cfg/Global"), ""); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; check_iterator(callbacks2, two); // Test we don't get callbacks when we change them back, either. one.xset("cfg/Global", WvString::null); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/Global"), ""); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 1; check_iterator(callbacks2, two); // Test reception of callbacks due to deletions callbacks2["cfg/Global/Have Disk"] = WvString::null; callbacks2["cfg/Global"] = WvString::null; two.xset("cfg/Global", WvString::null); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/Global/Have Disk"), WvString::null); WVPASSEQ(two.xget("cfg/Global"), WvString::null); callbacks2["cfg"] = ""; check_iterator(callbacks2, two); // Test non-reception of underlying callbacks on sections that will be // deleted by a change. one.xset("cfg/Global/Servers/FunFS", 1); one.xset("cfg/Global/Servers", WvString::null); WVPASSEQ(two.xget("cfg/Global"), WvString::null); WVPASSEQ(two.xget("cfg/Global/Servers"), WvString::null); WVPASSEQ(two.xget("cfg/Global/Servers/FunFS"), WvString::null); callbacks2["cfg"] = ""; check_iterator(callbacks2, two); // Test reception of callbacks on changes to replacement sections. callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 0; two.xset("cfg/Global/Have Disk", 0); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/Global"), ""); WVPASSEQ(two.xget("cfg/Global/Have Disk"), "0"); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 0; check_iterator(callbacks2, two); // Test non-creation of keys when deleting subkeys. two.xset("cfg/foo/bar", WvString::null); WVPASSEQ(two.xget("cfg/foo"), WvString::null); WVPASSEQ(two.xget("cfg/foo/bar"), WvString::null); callbacks2["cfg"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 0; check_iterator(callbacks2, two); // Test that they really will be deleted, and also test reception // of callbacks on keys to which nothing is being done. callbacks2["cfg/foo"] = ""; one.xset("cfg/foo/bar", ""); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/foo"), ""); WVPASSEQ(two.xget("cfg/foo/bar"), WvString::null); callbacks2["cfg"] = ""; callbacks2["cfg/foo"] = ""; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Have Disk"] = 0; check_iterator(callbacks2, two); // Test that refresh works. callbacks2["cfg/foo/bar"] = ""; callbacks2["cfg/Global/Have Disk/"] = WvString::null; two.refresh(); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASSEQ(two.xget("cfg/foo/bar"), ""); WVPASSEQ(two.xget("cfg/Global/Have Disk/"), WvString::null); callbacks2["cfg"] = ""; callbacks2["cfg/foo"] = ""; callbacks2["cfg/foo/bar"] = ""; callbacks2["cfg/Global"] = ""; check_iterator(callbacks2, two); // Prepare to test that commit works. callbacks2["cfg/Global"] = WvString::null; callbacks2["cfg/foo/bar"] = WvString::null; callbacks2["cfg/foo"] = WvString::null; callbacks2["cfg"] = WvString::null; callbacks2[""] = WvString::null; one.xset("", WvString::null); callbacks2[""] = ""; callbacks2["cfg"] = ""; callbacks2["cfg/OpenWall"] = ""; callbacks2["cfg/OpenWall/Harden Stack"] = 1; callbacks2["cfg/OpenWall/Harden Link"] = 1; callbacks2["cfg/OpenWall/Harden FIFO"] = 1; callbacks2["cfg/OpenWall/Harden Proc"] = 1; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Servers"] = ""; callbacks2["cfg/Global/Servers/Funfs"] = 1; callbacks2["cfg/Global/Servers/NFS"] = 0; one.xset("cfg/OpenWall/Harden Stack", 1); one.xset("cfg/OpenWall/Harden Link", 1); one.xset("cfg/OpenWall/Harden FIFO", 1); one.xset("cfg/OpenWall/Harden Proc", 1); one.xset("cfg/Global/Servers/Funfs", 1); one.xset("cfg/Global/Servers/NFS", 0); callbacks2["cfg/OpenWall/Harden Stack"] = WvString::null; callbacks2["cfg/OpenWall/Harden Link"] = WvString::null; callbacks2["cfg/OpenWall/Harden FIFO"] = WvString::null; callbacks2["cfg/OpenWall/Harden Proc"] = WvString::null; callbacks2["cfg/OpenWall"] = WvString::null; two.xset("cfg/OpenWall", WvString::null); callbacks2["cfg/OpenWall"] = ""; callbacks2["cfg/OpenWall/Harden Stack"] = 0; callbacks2["cfg/OpenWall/Harden FIFO"] = ""; callbacks2["cfg/OpenWall/Harden Proc"] = 1; callbacks2["cfg/Global/Servers/FunFS"] = 0; two.xset("cfg/OpenWall/Harden Stack", 0); two.xset("cfg/OpenWall/Harden FIFO", ""); two.xset("cfg/OpenWall/Harden Proc", 1); two.xset("cfg/Global/Servers/FunFS", 0); two.xset("cfg/Global/Servers/NFS", 0); UniWatch mywatch1(one, callback1); callbacks1["cfg/OpenWall/Harden Link"] = WvString::null; callbacks1["cfg/OpenWall/Harden Stack"] = 0; callbacks1["cfg/OpenWall/Harden FIFO"] = ""; callbacks1["cfg/Global/Servers/FunFS"] = 0; // Here we go. two.commit(); WVPASS(callbacks2.empty()); callbacks2.clear(); WVPASS(callbacks1.empty()); callbacks1.clear(); callbacks2["cfg"] = ""; callbacks2["cfg/OpenWall"] = ""; callbacks2["cfg/OpenWall/Harden Stack"] = 0; callbacks2["cfg/OpenWall/Harden FIFO"] = ""; callbacks2["cfg/OpenWall/Harden Proc"] = 1; callbacks2["cfg/Global"] = ""; callbacks2["cfg/Global/Servers"] = ""; callbacks2["cfg/Global/Servers/Funfs"] = 0; callbacks2["cfg/Global/Servers/NFS"] = 0; check_iterator(callbacks2, two); callbacks1["cfg"] = ""; callbacks1["cfg/OpenWall"] = ""; callbacks1["cfg/OpenWall/Harden Stack"] = 0; callbacks1["cfg/OpenWall/Harden FIFO"] = ""; callbacks1["cfg/OpenWall/Harden Proc"] = 1; callbacks1["cfg/Global"] = ""; callbacks1["cfg/Global/Servers"] = ""; callbacks1["cfg/Global/Servers/Funfs"] = 0; callbacks1["cfg/Global/Servers/NFS"] = 0; check_iterator(callbacks1, one); } // Test that UniTransactionGen works when mounted on a UniConf subtree. WVTEST_MAIN("UniTransactionGen submount test") { UniConfRoot root("temp:"); UniConf subtree = root["subtree"]; UniConfRoot transaction(new UniTransactionGen(new UniUnwrapGen(subtree))); transaction.remove(); transaction.xset("key", "value"); WVPASSEQ(transaction["key"].getme("default"), WvString("value")); WVPASSEQ(subtree["key"].getme("default"), WvString("default")); transaction.commit(); WVPASSEQ(transaction["key"].getme("default"), WvString("value")); WVPASSEQ(subtree["key"].getme("default"), WvString("value")); } static WvString last_key; static void incr_callback(int *i, const UniConf &handle, const UniConfKey &key) { (*i)++; last_key = handle[key].fullkey(); wvout->print("callback '%s' = '%s'\n", handle[key].fullkey(), handle[key].getme()); } WVTEST_MAIN("excessive callbacks") { int i1 = 0, i2 = 0, i3 = 0; UniConfRoot uni("temp:"); UniWatch w1(uni, wv::bind(&incr_callback, &i1, _1, _2), true); UniWatch w2(uni["a/b"], wv::bind(&incr_callback, &i2, _1, _2), true); uni.xsetint("/a/b/c/1", 11); // a, b, c, 1 uni.xsetint("/a/b/c/2", 22); // 2 uni.xsetint("/a/e/c/3", 33); // e, c, 3 uni.xsetint("/a/e/c/4", 44); // 4 WVPASSEQ(i1, 9); WVPASSEQ(i2, 4); WVPASSEQ(last_key, "a/e/c/4"); UniConfRoot temp("temp:"); UniConf t(temp["t"]); UniWatch w3(temp, wv::bind(&incr_callback, &i3, _1, _2), true); WVPASSEQ(i3, 0); t.mountgen(new UniTransactionGen(new UniUnwrapGen(uni["a"])), true); t.mountgen(new UniTransactionGen(new UniUnwrapGen(uni["a"])), true); i3 = 0; // FIXME uncertain what value should be at this point WVPASS(t.exists()); WVPASS(t["b"].exists()); WVPASSEQ(i3, 0); // start with fresh counters i1 = i2 = i3 = 0; temp.refresh(); WVPASSEQ(i3, 0); temp.commit(); WVPASSEQ(i3, 0); i3 = 0; uni.xsetint("/a/b/c/1", 111); WVPASSEQ(i1, 1); WVPASSEQ(i2, 1); WVPASSEQ(i3, 2); // both unwrapgens notify us i1 = i2 = i3 = 0; t.xsetint("/b/c/2", 222); WVPASSEQ(i1, 0); WVPASSEQ(i2, 0); WVPASSEQ(i3, 1); // only one transactiongen sees the change i1 = i2 = i3 = 0; t.commit(); WVPASSEQ(i1, 1); WVPASSEQ(i2, 1); WVPASSEQ(i3, 1); // opposite transactiongen now sees the change WVPASSEQ(last_key, "t/b/c/2"); WVPASSEQ(uni.xgetint("/a/b/c/2", 0), 222); i1 = i2 = i3 = 0; t.refresh(); WVPASSEQ(i1, 0); WVPASSEQ(i2, 0); WVPASSEQ(i3, 0); t.remove(); i1 = i2 = i3 = 0; t.xsetint("b/c/1", 111); // /, b, c, 1 t.xsetint("b/c/2", 222); // 2 t.xsetint("e/c/3", 33); // e, c, 3 t.xsetint("e/c/4", 44); // 4 WVPASSEQ(i1, 0); WVPASSEQ(i2, 0); WVPASSEQ(i3, 9); i1 = i2 = i3 = 0; t.commit(); WVPASSEQ(i1, 0); // no actual changes made here WVPASSEQ(i2, 0); WVPASSEQ(i3, 0); t.remove(); i1 = i2 = i3 = 0; t.refresh(); WVPASSEQ(i1, 0); WVPASSEQ(i2, 0); WVPASSEQ(i3, 9); i1 = i2 = i3 = 0; uni.refresh(); WVPASSEQ(i1, 0); WVPASSEQ(i2, 0); WVPASSEQ(i3, 0); } static int ncount = 0; class NCounter { public: void callback(const UniConf keyconf, const UniConfKey _key) { ncount++; wvcon->print("got callback for '%s' '%s'\n", keyconf[_key].fullkey(), keyconf[_key].getme()); } }; WVTEST_MAIN("double notifications with daemon") { UniConfRoot uniconf; signal(SIGPIPE, SIG_IGN); WvString sockname("/tmp/unitransgen-%s", getpid()); UniConfTestDaemon daemon(sockname, "temp:", UniConfTestDaemon::autoinc_server_cb); int num_tries = 0; const int max_tries = 20; while (!uniconf.isok() && num_tries < max_tries) { num_tries++; WVFAIL(uniconf.isok()); // Try again... uniconf.unmount(uniconf.whichmount(), true); uniconf.mount(WvString("unix:%s", sockname)); wvdelay(100); } WVPASS(uniconf.isok()); UniWatchList watches; NCounter *foo = new NCounter; UniConfCallback uc(wv::bind(&NCounter::callback, foo, _1, _2)); watches.add(uniconf["Users"], uc); uniconf["users"]["x"].setme("1"); uniconf.commit(); ncount = 0; uniconf["users"]["y"].setme("1"); uniconf.commit(); printf("have ncount = %d\n", ncount); // FIXME This is the problem WVPASSEQ(ncount, 1); delete foo; } WVTEST_MAIN("transaction wrapper") { UniConfRoot uni("temp:"); UniTransaction trans(uni); uni.xset("a/b/c", "foo"); uni.xset("a/c/d", "bar"); uni.xset("b/b", "baz"); WVPASSEQ(uni.xget("a/b/c"), "foo"); WVPASSEQ(uni.xget("a/c/d"), "bar"); WVPASSEQ(uni.xget("b/b"), "baz"); WVPASSEQ(trans.xget("a/b/c"), "foo"); WVPASSEQ(trans.xget("a/c/d"), "bar"); WVPASSEQ(trans.xget("b/b"), "baz"); trans.xset("a/b/c", "baz"); trans.xset("b/b", "foo"); WVPASSEQ(uni.xget("a/b/c"), "foo"); WVPASSEQ(uni.xget("b/b"), "baz"); WVPASSEQ(trans.xget("a/b/c"), "baz"); WVPASSEQ(trans.xget("b/b"), "foo"); trans.refresh(); WVPASSEQ(trans.xget("a/b/c"), "foo"); WVPASSEQ(trans.xget("b/b"), "baz"); trans.xset("a/b/c", "baz"); trans.xset("b/b", "foo"); trans.commit(); WVPASSEQ(uni.xget("a/b/c"), "baz"); WVPASSEQ(uni.xget("b/b"), "foo"); WVPASSEQ(trans.xget("a/b/c"), "baz"); WVPASSEQ(trans.xget("b/b"), "foo"); } WVTEST_MAIN("bachelor generator") { UniConfRoot a("transaction:temp:"); UniTransaction b(a); a.xset("a/b", "foo"); WVPASSEQ(a.xget("a/b"), "foo"); WVPASSEQ(b.xget("a/b"), "foo"); a.refresh(); WVPASSEQ(a.xget("a/b"), WvString::null); WVPASSEQ(b.xget("a/b"), WvString::null); a.xset("a/b", "foo"); WVPASSEQ(a.xget("a/b"), "foo"); WVPASSEQ(b.xget("a/b"), "foo"); a.commit(); WVPASSEQ(a.xget("a/b"), "foo"); WVPASSEQ(b.xget("a/b"), "foo"); a.xset("a/b", "bar"); WVPASSEQ(a.xget("a/b"), "bar"); WVPASSEQ(b.xget("a/b"), "bar"); b.xset("a/b", "baz"); WVPASSEQ(a.xget("a/b"), "bar"); WVPASSEQ(b.xget("a/b"), "baz"); b.refresh(); WVPASSEQ(a.xget("a/b"), "bar"); WVPASSEQ(b.xget("a/b"), "bar"); b.xset("a/b", "baz"); WVPASSEQ(a.xget("a/b"), "bar"); WVPASSEQ(b.xget("a/b"), "baz"); b.commit(); WVPASSEQ(a.xget("a/b"), "baz"); WVPASSEQ(b.xget("a/b"), "baz"); } // this reproduces a really convoluted crash caused by nested generators // when commit() on the outer generator creates an iterator on a subtree // of the inner generator, and then that subtree gets deleted while the // iterator still exists. Nowadays this crash shouldn't be around anymore, // because UniTransactionGen returns only "safe" iterators that can handle // changes to the underlying data structure during their existence. WVTEST_MAIN("nested transaction commit/replace") { UniConfRoot root("temp:"); UniTransaction t1(root); UniTransaction t2(t1); t1[5].remove(); t1[5].xset(6, "hello"); t2[5].remove(); t2[5].xset(6, "yank"); t2[5][6].remove(); WVPASSEQ(t2[5].xget(6), NULL); WVPASSEQ(t1[5].xget(6), "hello"); WVPASS("committing"); t2.commit(); WVPASS("commit done"); WVPASSEQ(t1[6].xget(6), NULL); WVPASS("didn't crash"); } #if 1 // BUGZID: 13167 static int callback_count; static void callback(const UniConf keyconf, const UniConfKey key) { wvout->print("Handling callback with fullkey '%s', value '%s'\n", keyconf[key].fullkey(), keyconf[key].getme()); ++callback_count; } WVTEST_MAIN("transaction and list interaction") { ::unlink("tmp.ini"); WvFile file("tmp.ini", O_WRONLY|O_TRUNC|O_CREAT); file.write("[a]\n" "b = c\n"); WVPASS(file.isok()); UniTempGen *ini = new UniTempGen(); UniTempGen *def = new UniTempGen(); UniConfGenList *l = new UniConfGenList(); l->append(ini, false); l->append(def, false); UniListGen *cfg = new UniListGen(l); UniConfRoot uniconf; uniconf["ini"].mountgen(ini); uniconf["default"].mountgen(def); uniconf["cfg"].mountgen(cfg); UniTransaction uni(uniconf); callback_count = 0; UniWatchList watches; watches.add(uni["ini/a/b"], &callback); watches.add(uni["cfg/a/b"], &callback); (void)UniConfRoot("ini:tmp.ini").copy(uni["/ini"], true); uni.commit(); WVPASSEQ(uni.xget("/ini/a/b"), "c"); WVPASSEQ(uni.xget("/cfg/a/b"), "c"); WVPASSEQ(callback_count, 2); } #endif // BUGZID: 13167 #if 1 // BUGZID: 14057 template int digit(int num) { for (int i = place; i > 1; --i) num /= 10; return num % 10; } template <> int digit<1>(int num) { return num % 10; } template <> int digit<2>(int num) { return num / 10 % 10; } template <> int digit<3>(int num) { return num / 100 % 10; } template <> int digit<4>(int num) { return num / 1000 % 10; } template <> int digit<5>(int num) { return num / 10000 % 10; } static void cb(const UniConf &conf, const UniConfKey &key) { } WVTEST_MAIN("processing many keys") { //signal(SIGALRM, SIG_IGN); // ::alarm(1000); signal(SIGPIPE, SIG_IGN); WvString sockname("/tmp/unitransgen-%s", getpid()); UniConfTestDaemon daemon(sockname, "temp:", UniConfTestDaemon::autoinc_server_cb); UniConfRoot cfg(WvString("transaction:unix:%s", sockname)); printf("Add Callback\n"); fflush(stdout); cfg.add_callback(NULL, "/", UniConfCallback(cb)); printf("Setting\n"); fflush(stdout); for (int i = 0; i < 200; ++i) { int a = digit<5>(i); int b = digit<4>(i); int c = digit<3>(i); int d = digit<2>(i); int e = digit<1>(i); cfg[a][b][c][d][e].setmeint(i); } printf("Committing\n"); fflush(stdout); cfg.commit(); printf("Del Callback\n"); fflush(stdout); cfg.del_callback(NULL, "/"); } #endif // BUGZID: 14057 wvstreams-4.6.1/uniconf/t/unitempgen.t.cc0000644000175000001440000000052611036722347017432 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "unitempgen.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniTempGen Sanity Test") { UniTempGen *gen = new UniTempGen(); UniConfGenSanityTester::sanity_test(gen, "temp:"); WVRELEASE(gen); } // FIXME: could test lots more stuff here, or rather in the Sanity Tester... wvstreams-4.6.1/uniconf/t/unireadonlygen.t.cc0000644000175000001440000000203011036722347020272 0ustar wlachusers#include "uniinigen.h" #include "unireadonlygen.h" #include "uniconfroot.h" #include "wvfile.h" #include "wvtest.h" // NOTE: UniReadOnlyGen violates the "sensible" UniConf semantics tested for // in uniconfgen-sanitytest.h, since setting a value doesn't work. // FIXME: Perhaps the tests should take this into account // defined in uniinigen.t.cc extern WvString inigen(WvStringParm content); WVTEST_MAIN("reading and (not)writing") { WvString inifile = inigen("[S1]\n" "a = b\n" "[{S2}] \n" "c=d \n" "[{S\n3}]\n" "e=f\n"); WvString mon("readonly:ini:%s", inifile); IUniConfGen *gen = wvcreate(mon); UniConfRoot cfg((UniConfGen*)gen); WVPASSEQ(cfg["S1/a"].getme(), "b"); WVPASSEQ(cfg["S2/c"].getme(), "d"); WVPASSEQ(cfg["S\n3/e"].getme(), "f"); cfg["S1/a"].setme("y"); cfg["S2/c"].setme("z"); // values shouldn't have changed WVPASSEQ(cfg["S1/a"].getme(), "b"); WVPASSEQ(cfg["S2/c"].getme(), "d"); ::unlink(inifile); } wvstreams-4.6.1/uniconf/t/uninullgen.t.cc0000644000175000001440000000060111036722347017431 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" WVTEST_MAIN("nullgen basics") { UniConfRoot cfg("null:"); WVFAIL(cfg.haschildren()); cfg.setme("blah"); WVFAIL(cfg.haschildren()); cfg["x"].setme("pah"); WVFAIL(cfg.haschildren()); WVFAIL(cfg["x"].exists()); WVFAIL(cfg["x"].haschildren()); cfg.remove(); WVFAIL(cfg.haschildren()); } wvstreams-4.6.1/uniconf/t/unimountgen.t.cc0000644000175000001440000001223311036722347017625 0ustar wlachusers#include "wvtest.h" #include "wvstream.h" #include "unimountgen.h" #include "uniconf.h" #include "unitempgen.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniMountGen Sanity Test") { UniMountGen *gen = new UniMountGen; gen->mount("/", "temp:", true); // The mount generator doesn't have a moniker UniConfGenSanityTester::sanity_test(gen, WvString::null); WVRELEASE(gen); } WVTEST_MAIN("mountgen basics") { UniMountGen g; WVFAIL(g.haschildren("/")); g.mount("/", "null:", true); WVFAIL(g.haschildren("/")); } WVTEST_MAIN("mounting multiple generators") { // basic stuff UniMountGen g; IUniConfGen *t1 = g.mount("/foo", "temp:", true); IUniConfGen *t2 = g.mount("/bar", "temp:", true); t1->set("bum", "boo"); t2->set("dum", "far"); WVPASSEQ(g.get("/foo/bum"), "boo"); WVPASSEQ(g.get("/bar/dum"), "far"); // nested generators g.set("/foo/gah", "goop"); WVPASSEQ(t1->get("gah"), "goop"); UniTempGen *tg = new UniTempGen; IUniConfGen *t3 = g.mountgen("/foo/mink", tg, true); t3->set("moo", "foo"); WVPASSEQ(g.get("/foo/mink/moo"), "foo"); WVFAIL(t1->get("mink/moo")); UniConfKey topkey; WVPASS(g.whichmount("/foo/mink/fork/bork", &topkey) == tg); WVPASSEQ(WvString(topkey), "foo/mink"); // generator t3 should take precedence t1->set("mink/moo", "cabbage"); WVPASSEQ(g.get("/foo/mink/moo"), "foo"); g.unmount(t3, true); WVPASSEQ(g.get("/foo/mink/moo"), "cabbage"); WVFAIL(g.get("/moo")); t3 = g.mount("/", "temp:", true); t3->set("moo", "foo"); WVPASSEQ(g.get("/moo"), "foo"); /* FIXME: t3 should *not* take precedence, innermost generators should be first * since the generators should be sorted deepest first. */ #if 0 WVPASSEQ(g.get("/foo/bum"), "boo"); t3->set("/foo/bum", "fools"); WVPASSEQ(g.get("/foo/bum"), "boo"); #endif } WVTEST_MAIN("multiple generators - iterators") { UniMountGen g; IUniConfGen *t3 = g.mount("/", "temp:", true); IUniConfGen *t1 = g.mount("/foo", "temp:", true); IUniConfGen *t2 = g.mount("/bar", "temp:", true); t1->set("/", "bung"); t1->set("bum", "foo"); t1->set("bum/bum", "foo"); t1->set("bim", "foo"); t1->set("bam", "foo"); t2->set("/", "bung"); t2->set("dum", "bar"); t2->set("bum", "bar"); t2->set("bum/gum", "bar"); t2->set("bum/scum", "bar"); t2->set("bum/scum/flum", "bar"); t3->set("frump", "bung"); UniMountGen::Iter *i = g.iterator("/foosball"); WVFAIL(i); delete i; i = g.iterator("/foo"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { WVPASSEQ(i->value(), "foo"); num_values++; } WVPASSEQ(num_values, 3); } delete i; i = g.iterator("/bar"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { WVPASSEQ(i->value(), "bar"); num_values++; } WVPASSEQ(num_values, 2); } #if 0 // FIXME: unimountgen iterates badly through nested mounts delete i; i = g.iterator("/"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { WVPASSEQ(i->value(), "bung"); num_values++; } WVPASSEQ(num_values, 3); } #endif delete i; i = g.recursiveiterator("/foo"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { WVPASSEQ(i->value(), "foo"); num_values++; } WVPASSEQ(num_values, 4); } delete i; i = g.recursiveiterator("/bar"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { WVPASSEQ(i->value(), "bar"); num_values++; } WVPASSEQ(num_values, 5); } delete i; #if 0 // FIXME: unimountgen deals badly with nested mounts i = g.recursiveiterator("/"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) num_values++; WVPASSEQ(num_values, 10); } #endif } WVTEST_MAIN("multiple generators - iterating with gaps") { UniMountGen g; // nothing mounted on '/' IUniConfGen *t1 = g.mount("/foo", "temp:", true); IUniConfGen *t2 = g.mount("/bar", "temp:", true); t1->set("/", "foo"); t1->set("bum", "foo"); t1->set("bum/bum", "foo"); t1->set("bim", "foo"); t1->set("bam", "foo"); t2->set("/", "bar"); t2->set("dum", "bar"); t2->set("bum", "bar"); t2->set("bum/gum", "bar"); t2->set("bum/scum", "bar"); t2->set("bum/scum/flum", "bar"); // should be disregarding the fact that nothing is mounted on / and // iterating anyway UniMountGen::Iter *i = g.iterator("/"); if (WVPASS(i)) { int num_values = 0; for (i->rewind(); i->next(); ) { if (!WVPASS(i->value() == "foo" || i->value() == "bar")) wvcon->print("...value was '%s'\n", i->value()); num_values++; } WVPASSEQ(num_values, 2); } delete i; } wvstreams-4.6.1/uniconf/t/unilistgen.t.cc0000644000175000001440000001105611036722347017440 0ustar wlachusers#include "wvtest.h" #include "wvfile.h" #include "wvstringlist.h" #include "uniconfroot.h" #include "uniinigen.h" #include "unilistgen.h" #include "unitempgen.h" #include "unireadonlygen.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniListGen Sanity Test") { UniConfGenList *list = new UniConfGenList(); list->add(new UniTempGen(), true); list->add(new UniTempGen(), true); UniListGen *gen = new UniListGen(list); UniConfGenSanityTester::sanity_test(gen, "list:temp: temp:"); WVRELEASE(gen); } WVTEST_MAIN("Testing refresh()") { ::unlink("tmp.ini"); WvFile file("tmp.ini", O_WRONLY|O_TRUNC|O_CREAT); file.write("[foo]\n" "a = b\n"); WVPASS(file.isok()); UniConfRoot uni("list:ini:/tmp/foobee.ini ini:tmp.ini"); WVPASSEQ(uni["foo"]["a"].getme(), "b"); } WVTEST_MAIN("Testing for use with weaver") { UniTempGen *tmp1 = new UniTempGen(); UniTempGen *tmp2 = new UniTempGen(); UniConfGenList *l = new UniConfGenList(); l->append(tmp1, true); l->append(new UniReadOnlyGen(tmp2), true); UniListGen *unigen = new UniListGen(l); UniConfRoot uniconf(unigen); tmp1->addRef(); tmp2->addRef(); UniConfRoot front(tmp1); UniConfRoot back(tmp2); //should work as a normal generator uniconf.xsetint("Monkey", 1); WVPASS(uniconf.xgetint("Monkey")); WVPASS(front.xgetint("Monkey")); WVFAIL(back.xgetint("Monkey")); WVFAIL(uniconf.xgetint("Banana")); //should read from tmp2 in background back.xsetint("Banana", 1); WVPASS(uniconf.xgetint("Banana")); WVPASS(back.xgetint("Banana")); uniconf.xsetint("Banana", 0); WVFAIL(uniconf.xgetint("Banana")); WVFAIL(front.xgetint("Banana")); // back should still be as it was WVPASS(back.xgetint("Banana")); // testing when both are set to same WVFAIL(uniconf.xgetint("Manana")); uniconf.xsetint("Manana", 1); WVPASS(uniconf.xgetint("Manana")); back.xsetint("Manana", 0); WVPASS(uniconf.xgetint("Manana")); } WVTEST_MAIN("Testing iterator") { UniTempGen *tmp1 = new UniTempGen(); UniTempGen *tmp2 = new UniTempGen(); UniConfGenList *l = new UniConfGenList(); l->append(tmp1, true); l->append(tmp2, true); UniListGen *unigen = new UniListGen(l); UniConfRoot uniconf(unigen); UniConfKey key("key"); uniconf.xset("section/key", "value"); printf("%s\n", uniconf.xget("section/key", "DONG").cstr()); UniConf::Iter i1(uniconf["section"]); for (i1.rewind(); i1.next(); ) { WVPASS(i1().key() == key); } WvString a[5] = {"foo/goose","foo/moose","foo/garoose","foo/setme!","foo/bloing"}, expected[5] = {"bloing", "setme!", "goose", "garoose", "moose"}; int i; bool iterated_properly = true, iter_didnt_mangle = true; for (i = 0; i < 5; i++) uniconf.xsetint(a[i], 1); UniConf::Iter i2(uniconf["foo"]); i = 0; for (i2.rewind(); i2.next(); i++) { //printf("iterated over: %s\n", i2->fullkey().cstr()); if (!(i2->fullkey().removefirst() == expected[i])) iterated_properly = false; } WVPASS(iterated_properly); //verify iterating didn't destroy for (int i = 0; i < 5; i++) if (!(uniconf.xgetint(a[i]) == 1)) iter_didnt_mangle = false; WVPASS(iter_didnt_mangle); WvString expected2[15] = {"bloing", "bloing/foo", "bloing/foo/bloing", "setme!", "setme!/foo", "setme!/foo/setme!", "goose", "goose/foo", "goose/foo/goose", "garoose", "garoose/foo", "garoose/foo/garoose", "moose", "moose/foo", "moose/foo/moose"}; for (i = 0; i < 5; i++) uniconf.xsetint(WvString("%s/%s", a[i] , a[i]), 1); UniConf::RecursiveIter i3(uniconf["foo"]); i = 0; iterated_properly = true; for (i3.rewind(); i3.next(); i++) { //printf("iterated over: %s\n", i3->fullkey().cstr()); if (!(i3->fullkey().removefirst() == expected2[i])) iterated_properly = false; } WVPASS(iterated_properly); //verify iterating didn't destroy iter_didnt_mangle = true; for (int i = 0; i < 5; i++) if (!(uniconf.xgetint(a[i]) == 1)) iter_didnt_mangle = false; WVPASS(iter_didnt_mangle); } WVTEST_MAIN("List of inigens bug 6198") { ::unlink("tmp.ini"); ::unlink("tmp2.ini"); WvFile file("tmp2.ini", O_WRONLY|O_TRUNC|O_CREAT); file.write("[foo]\n" "a = b\n"); WVPASS(file.isok()); UniConfRoot uni("list:ini:tmp.ini ini:tmp2.ini"); WVPASSEQ(uni["foo"].xget("a", "notb"),"b"); } wvstreams-4.6.1/uniconf/t/uniinigen.t.cc0000644000175000001440000001673211077124114017243 0ustar wlachusers#include "uniinigen.h" #include "wvfile.h" #include "wvfileutils.h" #include "uniconfroot.h" #ifdef _WIN32 #include #endif #include "uniwatch.h" #include "wvsystem.h" #include "wvtest.h" #include "uniconfgen-sanitytest.h" #ifdef _WIN32 static inline int mkdir(const char *x, int y) { return mkdir(x); } #endif // Returns the filename where the content was written. This file must be // deleted when no longer needed. Returns WvString::null if unable to create // the file. WvString inigen(WvStringParm content) { WvString ininame = wvtmpfilename("inigen_test.ini"); WvFile file; WVPASS(file.open(ininame, O_CREAT|O_RDWR)); file.write(content); WVPASS(file.isok()); return ininame; } static int childcount(UniConf cfg) { int count = 0; UniConf::Iter i(cfg); for (i.rewind(); i.next(); ) count++; return count; } WVTEST_MAIN("UniIniGen Sanity Test") { WvString inifile("/tmp/inigen-test-%s.ini", getpid()); UniIniGen *gen = new UniIniGen(inifile); UniConfGenSanityTester::sanity_test(gen, WvString("ini:%s", inifile)); WVRELEASE(gen); unlink(inifile); } WVTEST_MAIN("commit-without-refresh") { UniConfRoot cfg("ini:/dev/does-not-exist"); cfg.commit(); cfg.refresh(); cfg.commit(); WVFAIL(cfg.haschildren()); } #ifndef _WIN32 WVTEST_MAIN("ini file permissions") { system("rm -f perm.ini"); system("touch perm.ini"); UniConfRoot cfg("ini:perm.ini"); cfg["foo"].setme("bar"); mode_t oldmask = umask(02); cfg.commit(); umask(oldmask); struct stat statbuf; WVPASS(stat("perm.ini", &statbuf) == 0); WVPASSEQ(statbuf.st_mode, 0100664); //file and permissions 0664 system("rm -f perm.ini"); } #endif WVTEST_MAIN("parsing1") { WvString ininame = inigen("[S1]\n" "a = b\n" "[{S2}] \n" "c=d \n" "[{S\n3}]\n" "e=f\n"); UniConfRoot cfg(WvString("ini:%s", ininame)); WVPASSEQ(cfg["S1/a"].getme(), "b"); WVPASSEQ(cfg["S2/c"].getme(), "d"); WVPASSEQ(cfg["S\n3/e"].getme(), "f"); WVPASSEQ(childcount(cfg), 3); ::unlink(ininame); } WVTEST_MAIN("parsing2") { WvString ininame = inigen("[x]\n" "[]\n" " a = b c \n" " { a\n b} {c } = { a\n b2} {c }\n" "apenwarr = {OBFU}scation!"); UniConfRoot cfg(WvString("ini:%s", ininame)); WVPASSEQ(cfg["a"].getme(), "b c"); WVPASSEQ(cfg[" a\n b} {c "].getme(), " a\n b2} {c "); WVPASSEQ(cfg["apenwarr"].getme(), "{OBFU}scation!"); ::unlink(ininame); } WVTEST_MAIN("parsing3") { WvString ininame = inigen("/ = foo\n"); UniConfRoot cfg(WvString("ini:%s", ininame)); WVPASSEQ(cfg.getme(), "foo"); WVFAIL(cfg.haschildren()); ::unlink(ininame); } WVTEST_MAIN("parsing4") { // first line should be dropped to try to recover, since the entire // file is invalid tcl-encoding. WvString ininame = inigen("{ broken\n/ = boo\n"); UniConfRoot cfg(WvString("ini:%s", ininame)); WVPASSEQ(cfg.getme(), "boo"); WVFAIL(cfg.haschildren()); } WVTEST_MAIN("Setting and getting (bug 6090)") { WvString ininame = inigen(""); UniConfRoot cfg(WvString("ini:%s", ininame)); cfg["mrwise"].setme("{{bork!"); cfg.commit(); WVPASSEQ(cfg["mrwise"].getme(), "{{bork!"); UniConfRoot cfg2(WvString("ini:%s", ininame)); WVPASSEQ(cfg2["mrwise"].getme(), "{{bork!"); ::unlink(ininame); } // This is probably covered by sanity tests now. OTOH, more tests is more // better. WVTEST_MAIN("Trailing slashes") { UniConfRoot cfg("ini:tmp.ini"); cfg["sfllaw"].setme("law"); WVPASSEQ(cfg["sfllaw"].getme(), "law"); WVPASSEQ(cfg["sfllaw/"].getme(), ""); cfg["sfllaw/"].setme("LAW"); WVPASSEQ(cfg["sfllaw"].getme(), "law"); WVPASSEQ(cfg["sfllaw/"].getme(), ""); } static void count_cb(int *i, const UniConf &cfg, const UniConfKey &key) { (*i)++; } WVTEST_MAIN("ini callbacks") { int i = 0; WvString ininame = inigen("a/b/c/1 = 11\n" "a/b/c/2 = 22\n"); UniConfRoot cfg(WvString("ini:%s", ininame)); UniWatch w(cfg, wv::bind(&count_cb, &i, _1, _2), true); WVPASSEQ(i, 0); cfg.refresh(); WVPASSEQ(i, 0); { WvFile f(ininame, O_WRONLY|O_TRUNC); f.print("a/b/c/1 = 111\n" "a/b/c/2 = 222\n"); cfg.refresh(); WVPASSEQ(i, 2); f.print("a/b/c/3 = 333\n"); cfg.refresh(); WVPASSEQ(i, 3); f.print("\n"); cfg.refresh(); WVPASSEQ(i, 3); } cfg.xset("x", "y"); WVPASSEQ(i, 4); cfg.commit(); WVPASSEQ(i, 4); cfg.refresh(); WVPASSEQ(i, 4); ::unlink(ininame); } static void inicmp(WvStringParm key, WvStringParm val, WvStringParm content) { WvString ininame = inigen(""); UniConfRoot cfg(WvString("ini:%s", ininame)); cfg[key].setme(val); cfg.commit(); WvFile f(ininame, O_RDONLY); WvDynBuf buf; f.read(buf, 128*1024); WVPASSEQ(content, buf.getstr()); ::unlink(ininame); } WVTEST_MAIN("writing") { inicmp("/", "test", "/ = test\n"); inicmp("x/y", "z", "\n[x]\ny = z\n"); inicmp("x/y/z", "abc", "\n[x]\ny/z = abc\n"); inicmp("x\n/y/z", "abc", "\n[{x\n}]\ny/z = abc\n"); inicmp("/users/apenwarr", "{OBFU}scation!", "\n[users]\napenwarr = {OBFU}scation!\n"); inicmp("/users/ apenwarr", "pbc ", "\n[users]\n{ apenwarr} = {pbc }\n"); // FIXME: empty-string keys probably *should* be printed, but we don't, // for compatibility with WvConf. This test makes sure it stays that // way (until we think of something better?) inicmp("/foo/blah", "", ""); } static ino_t inode_of(const char *fname) { struct stat st; if (stat(fname, &st) != 0) return 0; else return st.st_ino; } static off_t size_of(const char *fname) { struct stat st; if (stat(fname, &st) != 0) return 0; else return st.st_size; } WVTEST_MAIN("atomic updates") { WvString dirname("atomic-update-dir.tmp"), fname("%s/test.ini", dirname); chmod(dirname, 0700); rm_rf(dirname); WVPASS(!mkdir(dirname, 0700)); // honours umask WVPASS(!chmod(dirname, 0700)); // doesn't include umask // the directory is writable, so we can safely do atomic file replacement. // That means the file inode number will be *different* after doing // a second commit(). UniConfRoot ini(WvString("ini:%s", fname)); ini.xset("useless key", "useless value"); ini.commit(); ino_t inode1 = inode_of(fname); off_t size1 = size_of(fname); WVFAILEQ(inode1, 0); WVFAILEQ(size1, 0); ini.xset("1", "2"); ini.commit(); ino_t inode2 = inode_of(fname); off_t size2 = size_of(fname); WVFAILEQ(inode2, 0); WVFAILEQ(inode1, inode2); WVPASS(size2 > size1); // now let's make the directory non-writable. The inifile inside the // directory is still writable, which means we can update it, but not // atomically. Therefore its inode number *won't* change. WVPASS(!chmod(dirname, 0500)); ini.xset("3", "4"); ini.commit(); ino_t inode3 = inode_of(fname); off_t size3 = size_of(fname); WVFAILEQ(inode3, 0); WVPASSEQ(inode2, inode3); WVPASS(size3 > size2); // clean up chmod(dirname, 0700); rm_rf(dirname); } WVTEST_MAIN("do not refresh if not requested") { WvString ininame = inigen("[foo]\n" "bar = baz\n"); UniConfRoot cfg(WvString("ini:%s", ininame), false); WVFAIL(cfg["foo/bar"].exists()); WVFAILEQ(cfg["foo/bar"].getme(), "baz"); WVPASSEQ(childcount(cfg), 0); ::unlink(ininame); } wvstreams-4.6.1/uniconf/t/unireplicategen.t.cc0000644000175000001440000001452711202637334020437 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "unitempgen.h" #include "unireplicategen.h" #include "wvistreamlist.h" #include "wvtimeutils.h" #include "uniconfgen-sanitytest.h" #include #include #ifdef MACOS #include #else #include #endif WVTEST_MAIN("UniReplicateGen Sanity Test") { UniReplicateGen *gen = new UniReplicateGen(); gen->append(new UniTempGen(), true); UniConfGenSanityTester::sanity_test(gen, "replicate:temp: temp:"); WVRELEASE(gen); } WVTEST_MAIN("basic") { UniConfRoot cfg("replicate:temp: temp:"); WVFAIL(cfg.haschildren()); WVPASS(cfg["/key"].getme().isnull()); cfg["/key"].setme("value"); WVPASS(cfg.haschildren()); WVPASS(cfg["/key"].getme() == "value"); cfg["/key"].setme(WvString::null); WVFAIL(cfg.haschildren()); WVPASS(cfg["/key"].getme().isnull()); } WVTEST_MAIN("propagation") { UniTempGen tmps[2]; tmps[0].set("/key0", "value0"); tmps[0].set("/key", "value0"); tmps[1].set("/key1", "value1"); tmps[1].set("/key", "value1"); UniReplicateGen rep; rep.append(&tmps[1], false); WVPASS(!rep.exists("/key0")); WVPASS(rep.get("/key1") == "value1"); WVPASS(rep.get("/key") == "value1"); WVPASS(!tmps[0].exists("/key1")); WVPASS(tmps[0].get("/key") == "value0"); WVPASS(!tmps[1].exists("/key0")); WVPASS(tmps[1].get("/key") == "value1"); rep.prepend(&tmps[0], false); WVPASS(rep.get("/key0") == "value0"); WVPASS(rep.get("/key1") == "value1"); WVPASS(rep.get("/key") == "value0"); WVPASS(tmps[0].get("/key1") == "value1"); WVPASS(tmps[0].get("/key") == "value0"); WVPASS(tmps[1].get("/key0") == "value0"); WVPASS(tmps[1].get("/key") == "value0"); rep.set("key", "value"); WVPASS(rep.get("key") == "value"); WVPASS(tmps[0].get("key") == "value"); WVPASS(tmps[1].get("key") == "value"); tmps[0].set("key", "value0"); WVPASS(rep.get("key") == "value0"); WVPASS(tmps[0].get("key") == "value0"); WVPASS(tmps[1].get("key") == "value0"); tmps[1].set("key", "value1"); WVPASS(rep.get("key") == "value1"); WVPASS(tmps[0].get("key") == "value1"); WVPASS(tmps[1].get("key") == "value1"); } static int callback_count = 0; static void callback(const UniConf &uniconf, const UniConfKey &key) { ++callback_count; } static void kill_and_harvest(const pid_t pid) { // Never, ever try to kill pid 0 or -1. if (pid <= 0) return; kill(pid, 15); pid_t rv; while ((rv = waitpid(pid, NULL, 0)) != pid) { // in case a signal is in the process of being delivered.. if (rv == -1 && errno != EINTR) break; } WVPASS(rv == pid); } WVTEST_MAIN("retry:uniconfd") { signal(SIGPIPE, SIG_IGN); WvString uniconfd_sock("/tmp/unireplicategen-uniconfd-%s", getpid()); WvString uniconfd_ini("/tmp/unireplicategen-uniconfd-%s.ini", getpid()); WvString ini_moniker("ini:%s", uniconfd_ini); char * uniconfd_argv[] = { (char*)"uniconfd", (char*)"-l", WvString("unix:%s", uniconfd_sock).edit(), ini_moniker.edit(), NULL }; pid_t uniconfd_pid; unlink(uniconfd_ini.cstr()); UniConfRoot cfg(WvString("replicate:{retry:unix:%s 100} temp:", uniconfd_sock)); cfg.add_callback(&callback_count, "/", callback, true); WVPASS(callback_count == 0); int old_callback_count; old_callback_count = callback_count; cfg["/key"].setme("value"); WVPASS(cfg["/key"].getme() == "value"); WVPASS(callback_count > old_callback_count); // FIXME: This is a lot more complicated than using the UniConfTestDaemon // class. However, using it breaks the unit tests a tiny bit and I don't // have time to figure it out. But whatever you do, don't copy this code! // Use the UniConfTestDaemon! if ((uniconfd_pid = fork()) == 0) { execv("uniconf/daemon/uniconfd", uniconfd_argv); _exit(1); } wvdelay(100); // wait for connect { UniConfRoot another_cfg(WvString("retry:unix:%s", uniconfd_sock)); for (;;) { another_cfg.xset("wait", "ping"); if (another_cfg.xget("wait") == "ping") break; wvdelay(100); } } WVPASS(cfg["/key"].getme() == "value"); old_callback_count = callback_count; { UniConfRoot another_cfg(WvString("unix:%s", uniconfd_sock)); WVPASS(another_cfg["/key"].getme() == "value"); another_cfg["/key"].setme("value one"); WVPASS(another_cfg["/key"].getme() == "value one"); } WVPASS(cfg["/key"].getme() == "value one"); WVPASS(callback_count > old_callback_count); kill_and_harvest(uniconfd_pid); unlink(uniconfd_sock.cstr()); WVPASS(cfg["/key"].getme() == "value one"); old_callback_count = callback_count; cfg["/key"].setme("value two"); WVPASS(cfg["/key"].getme() == "value two"); WVPASS(callback_count > old_callback_count); if ((uniconfd_pid = fork()) == 0) { execv("uniconf/daemon/uniconfd", uniconfd_argv); _exit(1); } wvdelay(100); // wait for connect { UniConfRoot another_cfg(WvString("retry:unix:%s", uniconfd_sock)); for (;;) { another_cfg.xset("wait", "pong"); if (another_cfg.xget("wait") == "pong") break; wvdelay(100); } } old_callback_count = callback_count; WVPASS(cfg["/key"].getme() == "value one"); WVPASS(callback_count > old_callback_count); old_callback_count = callback_count; { UniConfRoot another_cfg(WvString("unix:%s", uniconfd_sock)); another_cfg["/key"].setme("value three"); WVPASS(another_cfg["/key"].getme() == "value three"); } WVPASS(cfg["/key"].getme() == "value three"); WVPASS(callback_count > old_callback_count); old_callback_count = callback_count; cfg["/key"].setme("value four"); WVPASS(cfg["/key"].getme() == "value four"); WVPASS(callback_count > old_callback_count); { UniConfRoot another_cfg(WvString("unix:%s", uniconfd_sock)); WVPASS(another_cfg["/key"].getme() == "value four"); } kill_and_harvest(uniconfd_pid); WVPASS(cfg["/key"].getme() == "value four"); unlink(uniconfd_ini); } wvstreams-4.6.1/uniconf/t/wvconfemu.t.cc0000644000175000001440000002136311036722347017272 0ustar wlachusers#include "wvtest.h" #include "wvstring.h" #include "wvconfemu.h" #include "uniinigen.h" #include WVTEST_MAIN("wvconfemu set and get") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf); WvString section = "TestSection", entry = "TestEntry", value = "TestValue", notValue = "NotTestValue", notSection = "No Such Section", notEntry = "No Such Entry"; // get existing key cfg.set(section, entry, value); WVPASSEQ(cfg.get(section, entry, notValue), value); // get nonexistant key WVPASSEQ(cfg.get(section, notEntry, notValue), notValue); WVPASSEQ(cfg.get(notSection, entry, notValue), notValue); } WVTEST_MAIN("wvconfemu delete with empty key name") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf); WvString section = "TestSection", entry = "TestEntry", value = "TestValue", notValue = "NotTestValue"; WVPASSEQ(cfg.get(section, entry, notValue), notValue); cfg.set(section, entry, value); WVPASSEQ(cfg.get(section, entry, notValue), value); cfg.set(section, "", value); WVPASSEQ(cfg.get(section, entry, notValue), value); { WvConfigSection *sect = cfg[section]; WVPASS(sect != NULL); WvConfigEntryList::Iter i(*sect); int count = 0; for (i.rewind(); i.next(); ) { WVPASSEQ(i->value, value); WVPASSEQ(i->name, entry); ++count; } WVPASS(count == 1); } cfg.set(section, "", ""); WVPASSEQ(cfg.get(section, entry, notValue), value); { WvConfigSection *sect = cfg[section]; WVPASS(sect != NULL); WvConfigEntryList::Iter i(*sect); int count = 0; for (i.rewind(); i.next(); ) { WVPASSEQ(i->value, value); WVPASSEQ(i->name, entry); ++count; } WVPASS(count==1); } } WVTEST_MAIN("wvconfemu delete with NULL") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf); WvString section = "TestSection", entry = "TestEntry", value = "TestValue", notValue = "NotTestValue"; cfg.set(section, entry, value); WVPASSEQ(cfg.get(section, entry, notValue), value); cfg.set(section, entry, NULL); WVPASSEQ(cfg.get(section, entry, notValue), notValue); WvConfigSection *sect = cfg[section]; WVPASS(sect != NULL); WvConfigEntryList::Iter i(*sect); for (i.rewind(); i.next(); ) WVFAILEQ(i->name, entry); } WVTEST_MAIN("wvconfemu delete with empty string") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf); WvString section = "TestSection", entry = "TestEntry", value = "TestValue", notValue = "NotTestValue"; cfg.set(section, entry, value); WVPASSEQ(cfg.get(section, entry, notValue), value); cfg.set(section, entry, ""); WVPASSEQ(cfg.get(section, entry, notValue), notValue); WvConfigSection *sect = cfg[section]; WVPASS(sect != NULL); WvConfigEntryList::Iter i(*sect); for (i.rewind(); i.next(); ) WVFAILEQ(i->name, entry); } WVTEST_MAIN("wvconfemu iterating while not mounted at root of UniConf tree") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf["/branch"]); WvString section = "TestSection", entry = "TestEntry", value = "TestValue", notValue = "NotTestValue"; cfg.set(section, entry, value); WVPASSEQ(cfg.get(section, entry, notValue), value); WvConfigSection *sect = cfg[section]; WvConfigSection::Iter i(*sect); for (i.rewind(); sect && i.next(); ) { printf("name: %s\n", i->name.cstr()); printf("value: %s\n", i->value.cstr()); WVPASSEQ(i->name, entry); } #if 0 UniConfKey myroot("/root"); UniConf myconf(uniconf[myroot]["/foo/bar/baz"]); fprintf(stderr, "from root: %s\n", myconf.fullkey().cstr()); fprintf(stderr, "from myroot: %s\n", myconf.fullkey(myroot).cstr()); assert(false); #endif } #if 0 WVTEST_MAIN("Multiple Generators mounted on the Uniconf") { { UniTempGen *tmp1 = new UniTempGen(); UniTempGen *tmp2 = new UniTempGen(); UniConfRoot cfg1(tmp1), cfg2(tmp2); UniConf uniconf(cfg1); WvConfEmu cfg(uniconf); uniconf["foo"].mountgen(tmp1); uniconf["foo/bar"].mountgen(tmp2); cfg2.setmeint(1); WVPASS(uniconf.xgetint("foo/bar", 0)); WvConfigSection *sect = cfg["foo/bar"]; WVPASS(sect); } } #endif // emulate bug 9769 class UniBuggyGen: public UniTempGen { public: UniBuggyGen(): UniTempGen() { } virtual bool exists(const UniConfKey &) { return false; } }; // see bug 9664 and bug 9769 WVTEST_MAIN("UniRetryGen not ready") { UniConfRoot cfg("temp:"); cfg["foo"].setme("bar"); cfg["retrygen"].mountgen(new UniBuggyGen()); cfg["baz"].setme("blah"); WvConfEmu conf(cfg); WvConfEmu::Iter emuiter(conf); for (emuiter.rewind(); emuiter.next();) { WvConfigSection &emusect = *emuiter; WVPASS(emuiter.ptr()); WvConfigEntry *entry = emusect["foo"]; WVFAIL(entry); } } WVTEST_MAIN("Editing while iterating") { UniConfRoot uniconf("temp:"); uniconf["section"].xset("ICRASH/24", "crash1"); uniconf["section"].xset("UCRASH/MeCRASH", "crash2"); uniconf["section"].xset("WECRASH", "crash3"); WvConfEmu cfg(uniconf); WvConfigSection *sect = cfg["section"]; if (WVPASS(sect)) { WvConfigEntryList::Iter i(*sect); for (i.rewind(); i.next();) { WVPASS(cfg.get("section", i->name, "")); cfg.set("section", i->name, NULL); i.rewind(); } WVPASS("Didn't crash, or cause valgrind errors?"); } } WVTEST_MAIN("wvconfemu setbool") { UniConfRoot uniconf("temp:"); WvConfEmu cfg(uniconf); bool c1, c2, c3; cfg.setint("Foo", "Blah", 1); cfg.add_setbool(&c1, "Foo", ""); cfg.add_setbool(&c2, "", "Bar"); cfg.add_setbool(&c3, "Foo", "Bar"); c1 = false; c2 = false; c3 = false; cfg.setint("Chicken", "Poop", 1); WVPASS(!c1 && !c2 && !c3); // set it to the same value, no change event cfg.setint("Foo", "Blah", 1); WVPASS(!c1 && !c2 && !c3); cfg.setint("Foo", "Blah", 2); WVPASS(c1 && !c2 && !c3); c1 = false; cfg.setint("Something", "Bar", 1); WVPASS(!c1 && c2 && !c3); c2 = false; cfg.setint("Foo", "Bar", 1); WVPASS(c1 && c2 && c3); c1 = c2 = c3 = false; cfg.delete_section("Foo"); WVPASS(c1 && c2 && c3); WVPASS(c1); WVPASS(c2); WVPASS(c3); cfg.del_setbool(&c1, "Foo", ""); cfg.del_setbool(&c2, "", "Bar"); cfg.del_setbool(&c3, "Foo", "Bar"); } WVTEST_MAIN("wvconfemu addname") { UniConfRoot uniconf("temp:"); WvConfEmu cfg(uniconf); WvStringList sl; cfg.add_addname(&sl, "sect1", ""); cfg.add_addname(&sl, "sect2", "foo"); cfg.add_addname(&sl, "sect3", "bar"); cfg.set("sect1", "bar", "x"); cfg.set("sect2", "foo", "x"); cfg.set("sect2", "foo", "y"); cfg.set("sect3", "baz", "x"); // should not get notified! WVPASSEQ(sl.popstr(), "bar"); WVPASSEQ(sl.popstr(), "foo"); WVPASSEQ(sl.popstr(), "foo"); WVPASS(sl.isempty()); cfg.del_addname(&sl, "sect1", ""); cfg.del_addname(&sl, "sect2", "foo"); cfg.del_addname(&sl, "sect3", "bar"); } WVTEST_MAIN("wvconfemu isempty") { UniConfGen *unigen = new UniTempGen; UniConfRoot uniconf(unigen); WvConfEmu cfg(uniconf["cfg"]); cfg.setint("Montreal", "dcoombs", 1); WvConfigSectionEmu *sect = cfg["Montreal"]; WVPASS(sect && !sect->isempty()); cfg.set("Montreal", "dcoombs", NULL); WVPASS(!sect || sect->isempty()); bool never_ran = true; if (sect) { WvConfigSectionEmu::Iter i(*sect); for (i.rewind(); i.next(); ) never_ran = false; } WVPASS(never_ran); } WVTEST_MAIN("wvconfemu empty section") { int pass; for (pass=0; pass<2; ++pass) { UniConfRoot uni("temp:"); switch (pass) { case 0: uni.xset("Users/test", "passwd"); break; case 1: uni.xset("Users/test", ""); break; } WvConfEmu cfg(uni); int num_items = 0; WvConfigSectionList::Iter sect(cfg); for (sect.rewind(); sect.next(); ) { WvConfigEntryList::Iter ent(*sect); for (ent.rewind(); ent.next(); ) { ++num_items; } } switch (pass) { case 0: WVPASS(num_items == 1); break; case 1: WVPASS(num_items == 0); break; } } } wvstreams-4.6.1/uniconf/t/uniconfd.t.cc0000644000175000001440000003062411124271223017054 0ustar wlachusers#include "wvtest.h" #include "uniclientconn.h" #include "uniconfdaemon.h" #include "uniconfroot.h" #include "unitempgen.h" #include "wvstringlist.h" #include "wvistreamlist.h" #include "wvunixsocket.h" #include "wvstreamclone.h" #include "wvlog.h" #include "wvtclstring.h" #include "wvtcp.h" #include "wvfile.h" #include "wvpipe.h" #include "wvstringlist.h" #include "wvfileutils.h" #include /**** Generic daemon testing helpers ****/ DeclareWvList(WvStringList); class UniConfDaemonTestConn : public WvStreamClone { public: UniConfDaemonTestConn(IWvStream *s, WvStringList *_commands, WvStringListList *_expected_responses) : WvStreamClone(s), commands(_commands), expected_responses(_expected_responses), log("UniConfDaemonTestConn", WvLog::Debug) { uses_continue_select = true; } virtual ~UniConfDaemonTestConn() { log("Destructing\n"); terminate_continue_select(); } virtual void close() { log("Closing connection\n"); WvStreamClone::close(); } virtual void execute() { WvStreamClone::execute(); // order is always process responses to last command (or conn), // then send the next command // if we're out of expected responses, that means we're done if (expected_responses->count()) { while (expected_responses->first()->count()) { WvString line = blocking_getline(-1); WvString expected = expected_responses->first()->popstr(); log(">> '%s' (expect: '%s')\n", line, expected); WVPASS(!strcmp(line.cstr(), expected.cstr())); } expected_responses->unlink_first(); if (commands->count() > 0) { WvString command = commands->popstr(); print("%s\n", command); log("<< %s\n", command); } } // expecting nothing more, can close if (!expected_responses->count()) { log("no more responses expected, closing\n"); close(); if (isok()) log("um, why are we still ok?\n"); } } private: WvStringList *commands; WvStringListList *expected_responses; WvLog log; }; /**** Daemon surprise close test and helpers ****/ #if 0 static void spin(WvIStreamList &l) { int max; for (max = 0; max < 100 && l.select(10); max++) { wvcon->print("."); l.callback(); } wvcon->print("\n"); WVPASS(max < 100); } static void appendbuf(WvStream &s, void *_buf) { wvcon->print("append!\n"); WvDynBuf *buf = (WvDynBuf *)_buf; s.read(*buf, 10240); } static void linecmp(WvIStreamList &sl, WvBuf &buf, const char *w1, const char *w2 = NULL, const char *w3 = NULL) { wvcon->print("Awaiting '%s' '%s' '%s'\n", w1, w2, w3); spin(sl); WvString line = wvtcl_getword(buf, "\r\n"); WVPASS(line); if (!line) return; WvStringList l; wvtcl_decode(l, line); size_t nargs = w3 ? 3 : (w2 ? 2 : 1); WVPASS(l.count() < 4); WVPASSEQ(l.popstr(), w1); if (nargs >= 2) WVPASSEQ(l.popstr(), w2); if (nargs >= 3) WVPASSEQ(l.popstr(), w3); } WVTEST_MAIN("daemon surprise close") { WvIStreamList l; WVPASSEQ(WvIStreamList::globallist.count(), 0); spin(WvIStreamList::globallist); signal(SIGPIPE, SIG_IGN); WvIPPortAddr addr("0.0.0.0:4113"); UniConfRoot cfg("temp:"); UniConfDaemon daemon(cfg, false, NULL); spin(l); WVPASS(daemon.isok()); daemon.setuptcpsocket(addr); WVPASS(daemon.isok()); spin(l); WvDynBuf buf; WvTCPConn tcp(addr); tcp.setcallback(appendbuf, &buf); WVPASS(tcp.isok()); l.append(&daemon, false); l.append(&tcp, false); linecmp(l, buf, "HELLO"); WVPASS(tcp.isok()); tcp.write("SET /x/y z\n"); tcp.close(); spin(l); //linecmp(l, buf, "NOTICE", "", ""); //linecmp(l, buf, "NOTICE", "x", ""); //linecmp(l, buf, "NOTICE", "x/y", "z"); } #endif /**** Daemon multimount test ****/ WVTEST_MAIN("daemon multimount") { signal(SIGPIPE, SIG_IGN); UniConfRoot cfg("temp:"); cfg["pickles"].setme("foo"); cfg["subtree/fries"].setme("bar1"); cfg["subtree/ketchup"].setme("bar2"); cfg["subt"].mount("temp:"); cfg["subt/mayo"].setme("baz"); UniConfDaemon daemon(cfg, false, NULL); WvStringList commands; commands.append("subt / 1"); WvStringListList expected_responses; WvStringList hello_response; hello_response.append(WvString("HELLO {UniConf Server ready.} %s", UNICONF_PROTOCOL_VERSION)); expected_responses.add(&hello_response, false); WvStringList expected_quit_response; expected_quit_response.append("VAL subtree {}"); expected_quit_response.append("VAL subtree/fries bar1"); expected_quit_response.append("VAL subtree/ketchup bar2"); expected_quit_response.append("VAL subt {}"); expected_quit_response.append("VAL subt/mayo baz"); expected_quit_response.append("VAL pickles foo"); expected_quit_response.append("OK "); expected_responses.add(&expected_quit_response, false); WvString pipename = wvtmpfilename("uniconfd.t-pipe"); daemon.listen(WvString("unix:%s", pipename)); WvUnixAddr addr(pipename); WvUnixConn *sock = new WvUnixConn(addr); UniConfDaemonTestConn conn(sock, &commands, &expected_responses); WvIStreamList::globallist.append(&conn, false, "connection"); WvIStreamList::globallist.append(&daemon, false, "daemon"); wvcon->print("You are about to enter the no spin zone\n"); while (!WvIStreamList::globallist.isempty() && conn.isok() && daemon.isok()) { wvcon->print("Spinning: streams left: %s\n", WvIStreamList::globallist.count()); WvIStreamList::globallist.runonce(); } WVPASS(daemon.isok()); WvIStreamList::globallist.zap(); } /**** Daemon quit test ****/ // sort of useless: this functionality already exists in // daemon/tests and is automatically exercised. furthermore, we only // test that the server responds with 'OK' upon close (rather than // actually testing whether or not it closed). leaving this // here as a simple (generic) example to write future tests WVTEST_MAIN("daemon quit") { UniConfRoot cfg("temp:"); signal(SIGPIPE, SIG_IGN); cfg["pickles"].setme("foo"); cfg["subtree/fries"].setme("bar1"); cfg["subtree/ketchup"].setme("bar2"); UniConfDaemon daemon(cfg, false, NULL); WvStringList commands; commands.append("quit"); WvStringListList expected_responses; WvStringList hello_response; hello_response.append(WvString("HELLO {UniConf Server ready.} %s", UNICONF_PROTOCOL_VERSION)); expected_responses.add(&hello_response, false); WvStringList expected_quit_response; expected_quit_response.append("OK "); expected_responses.add(&expected_quit_response, false); WvString pipename = wvtmpfilename("uniconfd.t-pipe"); daemon.listen(WvString("unix:%s", pipename)); WvUnixAddr addr(pipename); WvUnixConn *sock = new WvUnixConn(addr); UniConfDaemonTestConn conn(sock, &commands, &expected_responses); WvIStreamList::globallist.append(&conn, false, "conn"); WvIStreamList::globallist.append(&daemon, false, "daemon"); wvcon->print("You are about to enter the no spin zone\n"); while (!WvIStreamList::globallist.isempty() && conn.isok() && daemon.isok()) { wvcon->print("Spinning: streams left: %s\n", WvIStreamList::globallist.count()); WvIStreamList::globallist.runonce(); } WVPASS(daemon.isok()); WvIStreamList::globallist.zap(); } /**** Daemon proxying test ****/ // test that proxying between two uniconf daemons works // e.g.: client -> uniconfd -> uniconfd static WvPipe * setup_master_daemon(bool implicit_root, WvString &masterpipename, WvString &ininame) { ininame = wvtmpfilename("uniconfd.t-ini"); WvString pidfile = wvtmpfilename("uniconfd.t-mpid"); WvFile stuff(ininame, (O_CREAT | O_WRONLY)); stuff.print("pickles/apples/foo=1\n"); stuff.print("pickles/mangos/bar=1\n"); stuff.close(); masterpipename = wvtmpfilename("uniconfd.t-sock"); WvString inimount("/cfg=ini:%s", ininame); WvString mount1, mount2; if (implicit_root) mount1 = inimount; else { mount1 = "/=temp:"; mount2 = inimount; } WvString lmoniker("unix:%s", masterpipename); const char * const uniconfd_args[] = { "uniconf/daemon/uniconfd", "-d", "--pid-file", pidfile.cstr(), "-l", lmoniker.cstr(), mount1.cstr(), mount2.cstr(), NULL }; return new WvPipe(uniconfd_args[0], uniconfd_args, false, true, false); } static WvPipe * setup_slave_daemon(bool implicit_root, WvStringParm masterpipename, WvString &slavepipename) { slavepipename = wvtmpfilename("uniconfd.t-sock"); WvString pidfile = wvtmpfilename("uiconfd.t-spid"); WvString rootmount; if (implicit_root) rootmount.append("/=retry:unix:%s", masterpipename); else rootmount.append("/=retry:cache:unix:%s", masterpipename); WvString lmoniker("unix:%s", slavepipename); const char * const uniconfd_args[] = { "uniconf/daemon/uniconfd", "--pid-file", pidfile.cstr(), "-l", lmoniker, rootmount.cstr(), NULL }; return new WvPipe(uniconfd_args[0], uniconfd_args, false, false, false); } static void wait_for_pipe_ready(WvStringParm pipename) { // If we can't get a connection in 100ms, something is seriously wrong.. WvUnixAddr addr(pipename); WvUnixConn *sock = new WvUnixConn(addr); WvString line; line = sock->getline(100); while (!line) { WVRELEASE(sock); sock = new WvUnixConn(addr); line = sock->getline(100); } WVRELEASE(sock); wvcon->print("Pipe ready! (%s)\n", line); } static void daemon_proxy_test(bool implicit_root) { wvcon->print("Setting up master daemon.\n"); WvString masterpipename, ininame; WvPipe *master = setup_master_daemon(implicit_root, masterpipename, ininame); master->setcallback(wv::bind(WvPipe::ignore_read, wv::ref(*master))); master->nowrite(); wait_for_pipe_ready(masterpipename); wvcon->print("Setting up slave daemon.\n"); WvString slavepipename; WvPipe *slave = setup_slave_daemon(implicit_root, masterpipename, slavepipename); slave->setcallback(wv::bind(WvPipe::ignore_read, wv::ref(*slave))); slave->nowrite(); wait_for_pipe_ready(slavepipename); WvStringList commands; commands.append("get /cfg/pickles/apples/foo"); commands.append("subt /"); WvStringListList expected_responses; WvStringList hello_response; hello_response.append(WvString("HELLO {UniConf Server ready.} %s", UNICONF_PROTOCOL_VERSION)); expected_responses.add(&hello_response, false); WvStringList expected_get_response; expected_get_response.append("ONEVAL cfg/pickles/apples/foo 1"); expected_responses.add(&expected_get_response, false); WvStringList expected_subt_response; expected_subt_response.append("VAL cfg {}"); expected_responses.add(&expected_subt_response, false); WvUnixAddr addr(slavepipename); WvUnixConn *sock = new WvUnixConn(addr); UniConfDaemonTestConn conn(sock, &commands, &expected_responses); WvIStreamList::globallist.append(&conn, false, "conn"); wvcon->print("Spinning: streams left: %s\n", WvIStreamList::globallist.count()); while (!WvIStreamList::globallist.isempty() && conn.isok()) { wvcon->print("Spinning: streams left: %s\n", WvIStreamList::globallist.count()); WvIStreamList::globallist.runonce(); } WvIStreamList::globallist.zap(); WVRELEASE(master); WVRELEASE(slave); unlink(slavepipename.cstr()); unlink(masterpipename.cstr()); unlink(ininame.cstr()); } WVTEST_MAIN("daemon proxying - with cache") { signal(SIGPIPE, SIG_IGN); daemon_proxy_test(false); } WVTEST_MAIN("daemon proxying - cfg the only mount") { signal(SIGPIPE, SIG_IGN); daemon_proxy_test(true); } wvstreams-4.6.1/uniconf/t/uniconftree.t.cc0000644000175000001440000000224211036722347017575 0ustar wlachusers#include "wvtest.h" #include "uniconftree.h" WVTEST_MAIN("univaluetree basics") { UniConfValueTree t(NULL, "key", "value"); WVPASSEQ(t.value(), "value"); WVFAIL(t.haschildren()); UniConfValueTree t2(&t, "key2", "value2"); WVPASS(t.haschildren()); WVFAIL(t2.haschildren()); } bool keyvalcomp(const UniConfValueTree *a, const UniConfValueTree *b) { return a && b && a->key() == b->key() && a->value() == b->value(); } WVTEST_MAIN("empty recursive compare") { UniConfValueTree a(NULL, "key", "value"); UniConfValueTree b(NULL, "key", "value"); WVPASS(a.compare(&b, keyvalcomp)); WVFAIL(a.compare(NULL, keyvalcomp)); new UniConfValueTree(&a, 1, 1); WVFAIL(a.compare(&b, keyvalcomp)); WVFAIL(b.compare(&a, keyvalcomp)); new UniConfValueTree(&b, 1, 1); WVPASS(a.compare(&b, keyvalcomp)); } WVTEST_MAIN("recursive compare") { UniConfValueTree a(NULL, "key", "value"); UniConfValueTree b(NULL, "key", "value"); for (int i = 1; i <= 1000; i++) new UniConfValueTree(&a, i, i); for (int i = 1000; i >= 1; i--) new UniConfValueTree(&b, i, i); WVPASS(a.compare(&b, keyvalcomp)); } wvstreams-4.6.1/uniconf/t/uniconfgen-sanitytest.cc0000644000175000001440000003066611062545375021370 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2006 Net Integration Technologies, Inc. * * Basic sanity tests that all UniConf generators should probably pass */ #include "uniconfgen-sanitytest.h" #include "uniconf.h" #include "uniconfdaemon.h" #include "uniconfgen.h" #include "uniconfroot.h" #include "uniwatch.h" #include "wvfork.h" #include "wvistreamlist.h" #include "wvlog.h" #include "wvtest.h" #include #include #include #ifndef _WIN32 #include #endif void UniConfTestDaemon::boring_server_cb(WvStringParm sockname, WvStringParm server_moniker) { { wverr->close(); time_t start = time(NULL); UniConfRoot uniconf(server_moniker); UniConfDaemon daemon(uniconf, false, NULL); unlink(sockname); daemon.listen(WvString("unix:%s", sockname)); WvIStreamList::globallist.append(&daemon, false, "uniconfd"); // Make sure to commit suicide after half an hour, just in case while (time(NULL) < start + 30*60) { WvIStreamList::globallist.runonce(); // usleep(1000); // should not be necessary } } _exit(0); } void UniConfTestDaemon::autoinc_server_cb(WvStringParm sockname, WvStringParm server_moniker) { { wverr->close(); time_t start = time(NULL); UniConfRoot uniconf(server_moniker); UniConfDaemon daemon(uniconf, false, NULL); unlink(sockname); daemon.listen(WvString("unix:%s", sockname)); WvIStreamList::globallist.append(&daemon, false, "uniconfd"); // Make sure to commit suicide after half an hour, just in case while (time(NULL) < start + 30*60) { uniconf.setmeint(uniconf.getmeint()+1); WvIStreamList::globallist.runonce(); // usleep(1000); // should not be necessary } } _exit(0); } UniConfTestDaemon::UniConfTestDaemon(WvStringParm _sockname, WvStringParm _server_moniker, UniConfDaemonServerCb server_cb) : sockname(_sockname), server_moniker(_server_moniker) { pid_t child = wvfork(); if (child == 0) server_cb(sockname, server_moniker); WVPASS(child > 0); server_pid = child; return; } UniConfTestDaemon::~UniConfTestDaemon() { #ifndef _WIN32 // Never, ever, try to kill pids -1 or 0. if (server_pid <= 0) fprintf(stderr, "Refusing to kill pid %i.\n", (int)server_pid); else kill(server_pid, 15); int status; pid_t rv; while ((rv = waitpid(server_pid, &status, 0)) != server_pid) { // in case a signal is in the process of being delivered... if (rv == -1 && errno != EINTR) break; } WVPASSEQ(rv, server_pid); WVPASS(WIFSIGNALED(status)); #endif unlink(sockname); } void UniConfGenSanityTester::clear_generator(IUniConfGen *g) { WvLog log("clear_generator"); UniConfGen::Iter *ii = g->iterator("/"); if (ii) { for (ii->rewind(); ii->next(); ) { log("removing %s (val %s)\n", ii->key(), ii->value()); g->set(ii->key(), WvString::null); } delete ii; } } void UniConfGenSanityTester::sanity_test(IUniConfGen *g, WvStringParm moniker) { test_haschildren_gen(g); test_haschildren_moniker(moniker); test_trailing_slashes(g, moniker); test_iter_sanity(moniker); test_recursive_iter_sanity(moniker); } void UniConfGenSanityTester::test_haschildren_gen(IUniConfGen *g) { clear_generator(g); WVFAIL(g->haschildren("/")); g->set("/", "blah"); g->commit(); WVFAIL(g->haschildren("/")); g->set("/x", "pah"); g->commit(); WVPASS(g->haschildren("/")); WVFAIL(g->haschildren("/x")); // Setting a section to an empty string is different from deleting it. g->set("/", WvString("")); WVPASS(g->haschildren("/")); WVFAIL(g->haschildren("/x")); g->set("/", WvString::null); g->commit(); WVFAIL(g->haschildren("/")); clear_generator(g); } // FIXME: This tests different things from the non-moniker test. They should // be combined, accept a regular UniConf as a parameter, and let the caller // worry about how to make one. void UniConfGenSanityTester::test_haschildren_moniker(WvStringParm moniker) { if (!moniker) return; // Checking notifications.. (we will assume that we are getting the // right keys for now) UniConfGenSanityTester::CbCounter notifywatcher; UniConfRoot cfg(moniker); UniWatch watcher(cfg["/"], wv::bind(&UniConfGenSanityTester::CbCounter::callback, ¬ifywatcher, _1, _2)); WVFAIL(cfg.haschildren()); WVPASSEQ(cfg.getme(), WvString::empty); WVPASS(cfg.exists()); WVFAIL(cfg["x"].exists()); notifywatcher.cbs = 0; cfg.setme("blah"); cfg.commit(); WVFAIL(cfg.haschildren()); WVPASS(cfg.exists()); // Note: We might get more than one notification for the change, e.g. if // we are using a UniListGen. WVPASSLT(0, notifywatcher.cbs); int old_cbs = notifywatcher.cbs; cfg["x"].setme("pah"); cfg.commit(); WVPASS(cfg["x"].exists()); WVPASS(cfg.haschildren()); WVFAIL(cfg["x"].haschildren()); WVPASSLT(old_cbs, notifywatcher.cbs); // Don't send notifications if the key doesn't change old_cbs = notifywatcher.cbs; cfg["x"].setme("pah"); cfg.commit(); WVPASSEQ(notifywatcher.cbs, old_cbs); cfg.remove(); cfg.commit(); WVFAIL(cfg.haschildren()); // We should get notifications for both /x and / being deleted WVPASSLT(old_cbs + 1, notifywatcher.cbs); // FIXME: UniIniGen fails this test. See BUGZID:22439 #if 0 // Don't send notifications if the key doesn't change old_cbs = notifywatcher.cbs; cfg.remove(); cfg.commit(); WVPASSEQ(notifywatcher.cbs, old_cbs); WVFAIL(cfg.exists()); WVPASSEQ(cfg.getme(), WvString::null); WVFAIL(cfg["x"].exists()); WVPASSEQ(cfg["x"].getme(), WvString::null); #endif } void UniConfGenSanityTester::test_trailing_slashes(IUniConfGen *g, WvStringParm moniker) { clear_generator(g); g->set("", "xyzzy"); g->commit(); WVPASSEQ(g->get("/"), "xyzzy"); WVPASSEQ(g->get("///"), "xyzzy"); WVPASSEQ(g->get(""), "xyzzy"); WVPASSEQ(g->get("//"), "xyzzy"); WVPASSEQ(g->get("///simon"), WvString::null); WVPASSEQ(g->get("///simon/"), WvString::null); WVPASSEQ(g->get("/simon///"), WvString::null); g->set("//simon", "law"); g->commit(); WVPASSEQ(g->get("/Simon"), "law"); WVPASSEQ(g->get("simon///"), WvString::null); g->set("//simon/", "LAW"); g->commit(); WVPASSEQ(g->get("/siMON"), "law"); WVPASSEQ(g->get("simon///"), WvString::null); WVFAIL(g->haschildren("simon//")); g->set("//simon/law", "1"); g->commit(); WVPASSEQ(g->get("/simon/law"), "1"); g->set("//simon/", WvString::null); g->commit(); WVPASSEQ(g->get("/simon/law"), WvString::null); WVFAIL(g->haschildren("simon///")); // Test that we delete immediate and recursive children when we delete a // section g->set("//simon/law", "1"); g->set("//simon/law/foo", "1"); g->set("//simon/law/foo/bar", "1"); g->commit(); WVPASSEQ(g->get("/simon/law"), "1"); WVPASSEQ(g->get("/simon/law/foo"), "1"); WVPASSEQ(g->get("/simon/law/foo/bar"), "1"); g->set("//simon/", WvString::null); g->commit(); WVPASSEQ(g->get("/simon/law"), WvString::null); WVPASSEQ(g->get("/simon/law/foo"), WvString::null); WVPASSEQ(g->get("/simon/law/foo/bar"), WvString::null); WVFAIL(g->haschildren("simon///law//foo")); WVFAIL(g->haschildren("simon///law//")); WVFAIL(g->haschildren("simon///")); // Test that we delete immediate and recursive autovivified children when // we delete a section g->set("//simon/law/foo/bar", "1"); g->commit(); WVPASSEQ(g->get("/simon/law"), WvString::null); WVPASSEQ(g->get("/simon/law/foo"), WvString::null); WVPASSEQ(g->get("/simon/law/foo/bar"), "1"); g->set("//simon/", WvString::null); g->commit(); WVPASSEQ(g->get("/simon/law"), WvString::null); WVPASSEQ(g->get("/simon/law/foo"), WvString::null); WVPASSEQ(g->get("/simon/law/foo/bar"), WvString::null); WVFAIL(g->haschildren("simon///law//foo/")); WVFAIL(g->haschildren("simon///law//")); WVFAIL(g->haschildren("simon///")); if (!!moniker) { UniConfRoot cfg(moniker); cfg.setme("xyzzy"); cfg.commit(); WVPASSEQ(cfg.xget("/"), "xyzzy"); WVPASSEQ(cfg.xget("///"), "xyzzy"); WVPASSEQ(cfg[""].getme(), "xyzzy"); WVPASSEQ(cfg[""][""]["/"].xget("/"), "xyzzy"); WVPASSEQ(cfg[""][""]["/"]["simon"].xget(""), WvString::null); WVPASSEQ(cfg[""][""]["/"]["simon"].xget("///"), WvString::null); cfg[""]["/"][""]["simon"].setme("law"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"].xget("simon"), "law"); WVPASSEQ(cfg[""][""]["/"]["simon"].getme(), "law"); WVPASSEQ(cfg[""][""]["/"]["simon"].xget(""), WvString::null); WVPASSEQ(cfg[""][""]["/"]["simon"].xget("///"), WvString::null); cfg[""]["/"][""]["simon"].xset("/", "LAW"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"].xget("simon"), "law"); WVPASSEQ(cfg[""][""]["/"].xget("simon/"), ""); WVPASSEQ(cfg[""][""]["/"]["simon"].getme(), "law"); WVPASSEQ(cfg[""][""]["/"]["simon"].xget(""), WvString::null); WVPASSEQ(cfg[""][""]["/"]["simon"].xget("///"), WvString::null); WVFAIL(cfg[""]["simon"][""].haschildren()); WVFAIL(cfg["simon"]["/"].haschildren()); cfg[""][""]["/"]["simon"].xset("/law", "1"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"]["simon"][""].xget("/law"), "1"); cfg[""][""]["/"]["simon"]["law"].xset("", "2"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"]["simon"][""].xget("/law"), "1"); cfg[""][""]["/"]["simon"]["law"].xset("/", "3"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"]["simon"][""].xget("/law"), "1"); cfg[""]["/"][""]["simon"].xset("/", "LAW"); cfg.commit(); WVPASSEQ(cfg[""][""]["/"].xget("simon"), "law"); WVPASSEQ(cfg[""][""]["/"].xget("simon/"), ""); cfg[""][""]["/"]["simon"][""].remove(); cfg.commit(); WVPASSEQ(cfg[""][""]["/"]["simon"][""].xget("/law"), WvString::null); WVFAIL(cfg[""]["simon"]["/"].haschildren()); WVPASSEQ(cfg[""].getme(), "xyzzy"); // ensure keys with trailing slashes don't get created as blank // keys cfg["foo"]["bar"][""].setme("value"); WVFAIL(cfg["foo"]["bar"].haschildren()); WVPASSEQ(cfg["foo"]["bar"][""].getme(), WvString::null); WVPASSEQ(cfg["foo"]["bar"].getme(), WvString::null); WVPASSEQ(cfg["foo"].getme(), WvString::null); } clear_generator(g); } // FIXME: Won't run for generators that have no moniker void UniConfGenSanityTester::test_iter_sanity(WvStringParm moniker) { if (!moniker) return; UniConfRoot root(moniker); root.remove(); root.commit(); root.xset("Foo/0", "Bar"); root.xset("Foo/1", "Baz"); root.xset("Foo/1/a", "Baz"); root.xset("Foo/2", "Baz"); root.xset("Bar/q", "Baz"); UniConf::Iter ii(root["Foo"]); int jj; for (jj = 0, ii.rewind(); ii.next(); jj++) { WVPASSEQ(ii->key().printable(), WvString(jj)); } // Check that we only iterated over three things WVPASSEQ(jj, 3); } // FIXME: Won't run for generators that have no moniker void UniConfGenSanityTester::test_recursive_iter_sanity(WvStringParm moniker) { if (!moniker) return; UniConfRoot root(moniker); root.remove(); root.commit(); root.xset("Foo/a", "1"); root.xset("Foo/b", "2"); root.xset("Foo/b/c", "3"); root.xset("Foo/d/e", "5"); root.xset("Bar/q", "Baz"); UniConf::RecursiveIter ii(root["/Foo"]); int jj = 0; for (ii.rewind(); ii.next(); ) { jj++; int val = ii->getmeint(); if (ii->fullkey().printable() == "Foo/d") { WVPASSEQ(val, 0); // The fourth value we read is Foo/d, which is autovivified val = 4; } WVFAILEQ(ii->fullkey().printable(), ii->getme()); WVPASSEQ(val, jj); //WVPASSEQ(ii->fullkey().printable(), ii->getme()); } // Check that we iterated over the four entries under Foo, as well as the // auto-vivified Foo/d WVPASSEQ(jj, 5); } wvstreams-4.6.1/uniconf/t/uniretrygen.t.cc0000644000175000001440000000735711036722347017643 0ustar wlachusers#include "wvtest.h" #include "uniconfroot.h" #include "unitempgen.h" #include "uniretrygen.h" #include "uniclientgen.h" #include "uniconfgen-sanitytest.h" #include "wvfileutils.h" #include #include #include struct UniRetryGenTester { WvString socket; WvString ini; pid_t uniconfd_pid; UniRetryGenTester() : socket("/tmp/uniretrygen-uniconfd-%s", getpid()), ini("/tmp/uniretrygen-uniconfd.ini-%s", getpid()), uniconfd_pid(0) { } }; void wait_for_daemon(UniRetryGenTester t) { UniConfRoot another_cfg(WvString("retry:unix:%s", t.socket)); for (;;) { another_cfg.xset("wait", "pong"); if (another_cfg.xget("wait") == "pong") break; fprintf(stderr, "still waiting for connection.\n"); wvdelay(100); } fprintf(stderr, "managed to connect\n"); } WVTEST_MAIN("UniRetryGen Sanity Test") { UniRetryGen *gen = new UniRetryGen("temp:"); UniConfGenSanityTester::sanity_test(gen, "retry:temp:"); WVRELEASE(gen); } WVTEST_MAIN("UniRetryGen: uniconfd") { signal(SIGPIPE, SIG_IGN); UniRetryGenTester t; unlink(t.ini); UniConfRoot cfg(WvString("retry:unix:%s 100", t.socket)); cfg["/key"].setme("value"); WVPASS(!cfg["/key"].exists()); { UniConfTestDaemon daemon(t.socket, WvString("ini:%s", t.ini)); wait_for_daemon(t); wvdelay(100); // guarantee that the retry interval has expired cfg["/key"].setme("value"); WVPASSEQ(cfg["/key"].getme(), "value"); cfg.commit(); } // no delay necessary: we disconnect right away WVPASS(!cfg["/key"].exists()); { UniConfTestDaemon daemon(t.socket, WvString("ini:%s", t.ini)); wait_for_daemon(t); wvdelay(100); // guarantee that the retry interval has expired WVPASSEQ(cfg["/key"].getme(), "value"); cfg.commit(); } WVPASS(!cfg["/key"].exists()); } bool reconnected = false; void reconnect_cb(UniRetryGen &uni) { reconnected = true; } WVTEST_MAIN("UniRetryGen: reconnect callback") { signal(SIGPIPE, SIG_IGN); UniRetryGenTester t; unlink(t.ini); UniConfRoot cfg; cfg.mountgen(new UniRetryGen(WvString("unix:%s", t.socket), UniRetryGen::ReconnectCallback(reconnect_cb), 100)); reconnected = false; UniConfTestDaemon daemon(t.socket, WvString("ini:%s", t.ini)); wait_for_daemon(t); wvdelay(100); // guarantee that the retry interval has expired cfg.getme(); // Do something to reconnect WVPASS(reconnected); } WVTEST_MAIN("UniRetryGen: immediate reconnect") { signal(SIGPIPE, SIG_IGN); UniRetryGenTester t; unlink(t.ini); // Need to set the reconnect delay to 0 to read immediately UniConfRoot cfg(WvString("retry:unix:%s 0", t.socket)); { UniConfTestDaemon daemon(t.socket, WvString("ini:%s", t.ini)); wait_for_daemon(t); cfg["/key"].setme("value"); WVPASSEQ(cfg["/key"].getme(), "value"); cfg.commit(); } // don't check anything before restarting so cfg doesn't know that // uniconfd has disconnected. { UniConfTestDaemon daemon(t.socket, WvString("ini:%s", t.ini)); wait_for_daemon(t); cfg.getme(); // Do something to reconnect WVPASSEQ(cfg["/key"].getme(), "value"); } WVPASS(!cfg["/key"].exists()); } WVTEST_MAIN("UniRetryGen: mount point exists") { // bug 9769 UniConfRoot uniconf("temp:"); WVPASS(uniconf["foo"].mount("retry:unix:/tmp/foobar")); WVPASS(uniconf["foo"].exists()); WVPASSEQ(uniconf["foo"].xget("", WvString::null), ""); WVFAIL(uniconf["foo/bar"].exists()); WVPASSEQ(uniconf["foo"].xget(""), WvString::null); } wvstreams-4.6.1/uniconf/t/uniunwrapgen.t.cc0000644000175000001440000000672511077124114020001 0ustar wlachusers#include "uniconfdaemon.h" #include "uniconfroot.h" #include "unitempgen.h" #include "uniunwrapgen.h" #include "uniconfgen-sanitytest.h" #include "wvtest.h" #include "wvtimeutils.h" #include WVTEST_MAIN("UniUnwrapGen Sanity Test") { UniConfRoot cfg("temp:"); UniUnwrapGen *gen = new UniUnwrapGen(cfg["/"]); UniConfGenSanityTester::sanity_test(gen, ""); WVRELEASE(gen); } static int itcount(UniConfGen::Iter *i) { int count = 0; wverr->print("start\n"); for (i->rewind(); i->next(); ) { wverr->print("visited %s\n", i->key()); count++; } wverr->print("end\n"); delete i; return count; } WVTEST_MAIN("unwrap basics") { UniConfRoot cfg("temp:"); cfg.xset("foo/blah/1/2/3", "x1"); cfg.xset("foo/blah/1/3/3", "x2"); cfg.xset("boo/fah", "fah string"); cfg["foo2"].mountgen(new UniUnwrapGen(cfg["foo"]), true); cfg["foo3"].mountgen(new UniUnwrapGen(cfg["foo2"]), true); WVPASSEQ(cfg.xget("foo2/blah/1/2/3"), "x1"); WVPASSEQ(cfg.xget("foo3/blah/1/3/3"), "x2"); UniUnwrapGen g(cfg); WVPASSEQ(itcount(g.iterator("/")), 4); WVPASSEQ(itcount(g.recursiveiterator("/foo")), 6); WVPASSEQ(itcount(g.recursiveiterator("/foo2")), 6); WVPASSEQ(itcount(g.recursiveiterator("/foo3")), 6); WVPASSEQ(itcount(g.recursiveiterator("/")), 23); cfg.xset("foo3/fork", "forky"); WVPASSEQ(itcount(g.recursiveiterator("/foo")), 7); WVPASSEQ(itcount(g.recursiveiterator("/")), 26); } WVTEST_MAIN("unwrapgen root") { UniTempGen *temp = new UniTempGen; UniConfRoot cfg(temp, true); cfg.xsetint("/a/b/c", 5); WVPASS(temp->exists("/a/b")); WVPASS(!temp->get("/a/b").isnull()); WVFAIL(temp->exists("a/b/")); WVFAIL(!temp->get("a/b/").isnull()); WVPASS(cfg["/a/b"].exists()); WVFAIL(cfg["/a/b/"].exists()); WVFAIL(cfg["/a/b"][""].exists()); WVFAIL(!cfg["/a/b"][""].getme().isnull()); UniUnwrapGen *g = new UniUnwrapGen(cfg["a"]); WVPASS(g->exists("/")); WVPASS(!g->get("/").isnull()); WVPASS(g->exists("")); WVPASS(!g->get("").isnull()); WVPASS(g->exists("b")); WVPASS(!g->get("b").isnull()); WVFAIL(g->exists("b/")); WVFAIL(!g->get("b/").isnull()); UniConfRoot gcfg(g, true); WVPASS(gcfg.exists()); // WVFAIL(gcfg[""].exists()); WVPASS(gcfg["b"].exists()); WVFAIL(gcfg["b/"].exists()); WVFAIL(gcfg["b"][""].exists()); } WVTEST_MAIN("unwrapgen callbacks") { signal(SIGPIPE, SIG_IGN); WvString sockname("/tmp/uniunwrapgen-%s", getpid()); UniConfTestDaemon daemon(sockname, "temp:"); printf("Creating a unix: gen\n"); UniConfRoot cfg(WvString("unix:%s", sockname)); printf("Waiting for daemon to start.\n"); fflush(stdout); int num_tries = 0; const int max_tries = 20; while (!cfg.isok() && num_tries < max_tries) { num_tries++; WVFAIL(cfg.isok()); // Try again... cfg.unmount(cfg.whichmount(), true); cfg.mount(WvString("unix:%s", sockname)); wvdelay(100); } if (WVPASS(cfg.isok())) printf("Connected to daemon.\n"); else printf("Connection failed.\n"); fflush(stdout); WVPASSEQ(cfg.xget("a"), WvString::null); WVPASSEQ(cfg.xget("a"), WvString::null); cfg.xset("a", "foo"); WVPASSEQ(cfg.xget("a"), "foo"); printf("Wrapping it in an unwrap: gen\n"); UniConfRoot unwrap(new UniUnwrapGen(cfg)); WVPASSEQ(unwrap.xget("a"), "foo"); } wvstreams-4.6.1/uniconf/t/unifastregetgen.t.cc0000644000175000001440000000414611036722347020453 0ustar wlachusers#include "unifastregetgen.h" #include "unislowgen.h" #include "unitempgen.h" #include "uniconfroot.h" #include "wvtest.h" #include "uniconfgen-sanitytest.h" WVTEST_MAIN("UniFastRegetGen Sanity Test") { UniFastRegetGen *gen = new UniFastRegetGen(new UniTempGen); UniConfGenSanityTester::sanity_test(gen, "fast-reget:temp:"); WVRELEASE(gen); } WVTEST_MAIN("fast-reget") { UniTempGen *t = new UniTempGen; UniSlowGen *slow = new UniSlowGen(t); UniConfRoot uni(new UniFastRegetGen(slow), true); slow->reset_slow(); // initial get needs to retrieve entire tree t->set("x/y/z", 5); WVPASSEQ(uni.xgetint("x/y/z"), 5); WVPASSEQ(slow->how_slow(), 3); slow->reset_slow(); // regets are free WVPASSEQ(uni.xgetint("x/y/z"), 5); WVPASSEQ(uni.xgetint("x/y/z"), 5); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); // notifications are processed uni.xset("x/y/z", 7); WVPASSEQ(uni.xgetint("x/y/z"), 7); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); // updates directly inside inner generator are free t->set("x/y/z", 9); t->set("x", 10); WVPASSEQ(uni.xgetint("x/y/z"), 9); WVPASSEQ(uni.xgetint("x"), 10); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); // known null parents should make child lookups free WvString nil; WVPASSEQ(uni.xget("a/b/c"), nil); slow->reset_slow(); WVPASSEQ(uni.xget("a/b/d"), nil); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); // but a parent then becoming non-null should not automatically make // an already-looked-up child non-free t->set("a/b", 99); WVPASSEQ(uni.xget("a/b/d"), nil); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); // checking children of non-nil nodes takes time and is not cached WVPASSEQ(uni["a/b"].haschildren(), false); WVPASSEQ(uni["a/b"].haschildren(), false); WVPASSEQ(slow->how_slow(), 2); slow->reset_slow(); // but checking children of nil nodes is trivial, so it's fast WVPASSEQ(uni["a/b/d"].haschildren(), false); WVPASSEQ(slow->how_slow(), 0); slow->reset_slow(); } wvstreams-4.6.1/uniconf/t/unitempgenvsdaemon.t.cc0000644000175000001440000000506711077124114021165 0ustar wlachusers#include "uniconfroot.h" #include "unireadonlygen.h" #include "unicachegen.h" #include "unitempgen.h" #include "unilistgen.h" #include "uniinigen.h" #include "uniconfgen-sanitytest.h" #include "wvistreamlist.h" #include "wvfile.h" #include "wvunixsocket.h" #include "wvtest.h" #include "wvtimeutils.h" #include #include #include #include // write out a temporary ini file for use, saves flushing entries static void write_ini(WvString &ininame) { ininame = WvString("/tmp/unitempgenvsdaemonini-%s", getpid()); WvFile outfile(ininame, O_CREAT | O_RDWR | O_TRUNC); outfile.print("%s\n%s\n", "[eth0]", "dhcpd = 1"); outfile.close(); } WVTEST_MAIN("tempgen/cachegen basics") { signal(SIGPIPE, SIG_IGN); WvString ininame; write_ini(ininame); WvString sockname = WvString("/tmp/unitempgensock-%s", getpid()); struct stat sock_exist; if (stat(sockname, &sock_exist) == 0) { WVFAIL(true || "Socket filename already exists"); unlink(ininame); exit(1); } UniConfTestDaemon daemon(sockname, WvString("ini:%s", ininame)); // Wait for child to become responsive { WvString root("retry:unix:%s", sockname); UniConfRoot cfg_ok(root); for (;;) { cfg_ok.xset("/tmp/dummy", "foo"); if (cfg_ok.xget("/tmp/dummy") == "foo") break; wvdelay(100); } } /* Setup subtree root */ WvString root("subtree:unix:%s cfg", sockname); UniConfRoot cfg(root); int initial_value = cfg["eth0"].xgetint("dhcpd", 0); cfg["eth0"].xsetint("dhcpd", !initial_value); cfg.commit(); int new_value = cfg["eth0"].xgetint("dhcpd", 0); WVFAILEQ(initial_value, new_value); unlink(ininame); } WVTEST_MAIN("cache:subtree:unix assertion failure") { signal(SIGPIPE, SIG_IGN); WvString ininame; write_ini(ininame); WvString sockname = WvString("/tmp/unitempgensock2-%s", getpid()); UniConfTestDaemon daemon(sockname, WvString("ini:%s", ininame)); // Wait for child to become responsive { WvString root("retry:unix:%s", sockname); UniConfRoot cfg_ok(root); for (;;) { cfg_ok.xset("/tmp/dummy", "foo"); if (cfg_ok.xget("/tmp/dummy") == "foo") break; wvdelay(100); } } /* Setup subtree root */ WvString root("cache:subtree:unix:%s cfg", sockname); UniConfRoot cfg(root); WvUnixConn unixconn(sockname); WVPASS(unixconn.isok()); unlink(ininame); } wvstreams-4.6.1/uniconf/t/uniconfkey.t.cc0000644000175000001440000001577411036722347017444 0ustar wlachusers#include "wvtest.h" #include "uniconfkey.h" WVTEST_MAIN("slash collapsing") { WVPASSEQ(UniConfKey().printable(), ""); WVPASSEQ(UniConfKey().numsegments(), 0); WVPASSEQ(UniConfKey("").printable(), ""); WVPASSEQ(UniConfKey("").numsegments(), 0); WVPASSEQ(UniConfKey("/").printable(), ""); WVPASSEQ(UniConfKey("////").printable(), ""); WVPASSEQ(UniConfKey("///").numsegments(), 0); WVPASSEQ(UniConfKey("foo").printable(), "foo"); WVPASSEQ(UniConfKey("foo").numsegments(), 1); WVPASSEQ(UniConfKey("/foo").printable(), "foo"); WVPASSEQ(UniConfKey("/foo").numsegments(), 1); WVPASSEQ(UniConfKey("foo/").printable(), "foo/"); WVPASSEQ(UniConfKey("foo/").numsegments(), 2); WVPASSEQ(UniConfKey("/foo/").printable(), "foo/"); WVPASSEQ(UniConfKey("/foo/").numsegments(), 2); WVPASSEQ(UniConfKey("//bar").printable(), "bar"); WVPASSEQ(UniConfKey("///bar").printable(), "bar"); WVPASSEQ(UniConfKey("bar//").printable(), "bar/"); WVPASSEQ(UniConfKey("bar///").printable(), "bar/"); WVPASSEQ(UniConfKey("///bar////").printable(), "bar/"); WVPASSEQ(UniConfKey("fred/barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("/fred/barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("fred//barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("fred///barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("/fred///barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("///fred///barney").printable(), "fred/barney"); WVPASSEQ(UniConfKey("fred/barney/").printable(), "fred/barney/"); WVPASSEQ(UniConfKey("fred/barney///").printable(), "fred/barney/"); WVPASSEQ(UniConfKey("/fred/barney/").printable(), "fred/barney/"); WVPASSEQ(UniConfKey("//fred///barney/").printable(), "fred/barney/"); WVPASSEQ(UniConfKey("///fred////barney///").printable(), "fred/barney/"); WVPASSEQ(UniConfKey("larry//////curly//////moe").printable(), "larry/curly/moe"); WVPASSEQ(UniConfKey("larry//////curly//////moe////////").printable(), "larry/curly/moe/"); WVPASSEQ(UniConfKey("////larry/////curly////moe///////").printable(), "larry/curly/moe/"); } WVTEST_MAIN("equality") { WVPASS(UniConfKey() == UniConfKey("/")); WVPASS(UniConfKey("") == UniConfKey("/")); WVPASS(UniConfKey("baz") == UniConfKey("/baz")); WVPASS(UniConfKey("ack/nak") == UniConfKey("//ack///nak")); WVFAIL(UniConfKey("a") == UniConfKey("a/")); WVFAIL(UniConfKey("/a") == UniConfKey("a/")); } WVTEST_MAIN("composition") { WVPASS(UniConfKey(UniConfKey("simon"), UniConfKey("")) == UniConfKey("simon/")); WVPASSEQ(UniConfKey(UniConfKey("simon"), UniConfKey("")).printable(), "simon/"); WVPASS(UniConfKey(UniConfKey("simon"), UniConfKey("/")) == UniConfKey("simon/")); WVPASSEQ(UniConfKey(UniConfKey("simon"), UniConfKey("/")).printable(), "simon/"); UniConfKey tmp(UniConfKey("simon"), UniConfKey("/")); WVPASS(UniConfKey(tmp, UniConfKey("law")) == UniConfKey("simon/law")); WVPASSEQ(UniConfKey(tmp, UniConfKey("law")).printable(), "simon/law"); WVPASS(UniConfKey(UniConfKey("simon/"), UniConfKey("")) == UniConfKey("simon/")); WVPASSEQ(UniConfKey(UniConfKey("simon/"), UniConfKey("")).printable(), "simon/"); WVPASS(UniConfKey(UniConfKey("simon/"), UniConfKey("law")) == UniConfKey("simon/law")); WVPASSEQ(UniConfKey(UniConfKey("simon/"), UniConfKey("law")).printable(), "simon/law"); } WVTEST_MAIN("subkeys") { WVPASS(UniConfKey().suborsame(UniConfKey(""))); WVPASS(UniConfKey().suborsame(UniConfKey("cfg/ini"))); WVPASS(UniConfKey("").suborsame(UniConfKey("cfg/ini"))); WVPASS(UniConfKey("/").suborsame(UniConfKey("cfg/ini"))); WVPASS(UniConfKey("cfg").suborsame(UniConfKey("cfg/ini"))); WVPASS(UniConfKey("cfg/").suborsame(UniConfKey("cfg/ini"))); WVPASS(UniConfKey("/cfg/ini").suborsame(UniConfKey("cfg/ini"))); WVFAIL(UniConfKey("/cfg/ini/foo").suborsame(UniConfKey("cfg/ini"))); WVFAIL(UniConfKey("/ini/cfg").suborsame(UniConfKey("cfg/ini"))); WVPASSEQ(UniConfKey().subkey(UniConfKey("")).printable(), ""); WVPASSEQ(UniConfKey().subkey(UniConfKey("cfg/ini")).printable(), "cfg/ini"); WVPASSEQ(UniConfKey("/").subkey(UniConfKey("cfg/ini")).printable(), "cfg/ini"); WVPASSEQ(UniConfKey("cfg").subkey(UniConfKey("cfg/ini")).printable(), "ini"); WVPASSEQ(UniConfKey("/cfg/ini").subkey(UniConfKey("cfg/ini")).printable(), ""); } WVTEST_MAIN("members") { UniConfKey key("//this///is/a/key"); WVPASSEQ(key.printable(), "this/is/a/key"); key.append("/end//key"); WVPASSEQ(key.printable(), "this/is/a/key/end/key"); key.prepend("/start/key"); WVPASSEQ(key.printable(), "start/key/this/is/a/key/end/key"); WVPASS(!key.isempty()); WVPASS(!key.iswild()); WVPASS(!key.hastrailingslash()); WVPASSEQ(key.numsegments(), 8); WVPASSEQ(key.segment(0).printable(), "start"); UniConfKey sub(key.segment(3)); WVPASSEQ(key.segment(3).printable(), "is"); WVPASSEQ(key.segment(7).printable(), "key"); WVPASSEQ(key.pop(3).printable(), "start/key/this"); WVPASSEQ(key.printable(), "is/a/key/end/key"); WVPASSEQ(key.first(3).printable(), "is/a/key"); WVPASSEQ(key.last(3).printable(), "key/end/key"); WVPASSEQ(key.removefirst(3).printable(), "end/key"); WVPASSEQ(key.removelast(3).printable(), "is/a"); WVPASSEQ(key.range(1, 4).printable(), "a/key/end"); key = UniConfKey("foo/bar"); WVPASSEQ(key.printable(), "foo/bar"); WVPASS(key.compareto("foo/bar") == 0); WVPASS(key.compareto("Foo/Bar") == 0); WVPASS(key.compareto("foo/a") > 0); WVPASS(key.compareto("foo/bar/a") < 0); WVPASS(key.compareto("foo/z") < 0); WVPASS(key.compareto("g") < 0); WVPASS(key.suborsame("foo/bar")); WVPASS(key.suborsame("foo/bar/baz")); WVPASS(!key.suborsame("foo")); WVPASS(!key.suborsame("foo/baz")); WVPASS(!key.suborsame("green")); WVPASSEQ(key.subkey("foo/bar/baz").printable(), "baz"); } WVTEST_MAIN("range") { WVPASSEQ(UniConfKey().range(0,0).printable(), ""); WVPASSEQ(UniConfKey().range(0,1).printable(), ""); WVPASSEQ(UniConfKey().range(1,2).printable(), ""); WVPASSEQ(UniConfKey("").range(0,0).printable(), ""); WVPASSEQ(UniConfKey("").range(0,1).printable(), ""); WVPASSEQ(UniConfKey("").range(1,2).printable(), ""); WVPASSEQ(UniConfKey("fred").range(0,0).printable(), ""); WVPASSEQ(UniConfKey("fred").range(0,1).printable(), "fred"); WVPASSEQ(UniConfKey("fred").range(1,2).printable(), ""); WVPASSEQ(UniConfKey("fred/barney").range(0,0).printable(), ""); WVPASSEQ(UniConfKey("fred/barney").range(0,1).printable(), "fred"); WVPASSEQ(UniConfKey("fred/barney").range(1,2).printable(), "barney"); WVPASSEQ(UniConfKey("fred/barney").range(0,2).printable(), "fred/barney"); WVPASSEQ(UniConfKey("fred/barney/betty").range(0,2).printable(), "fred/barney"); WVPASSEQ(UniConfKey("fred/barney/betty").range(1,3).printable(), "barney/betty"); WVPASSEQ(UniConfKey("fred/barney/betty").range(2,3).printable(), "betty"); } wvstreams-4.6.1/uniconf/unifilesystemgen.cc0000644000175000001440000000535711036722347020153 0ustar wlachusers#include "unifilesystemgen.h" #include "wvfile.h" #include "wvdiriter.h" #include "wvfileutils.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #include #include #include #include WV_LINK(UniFileSystemGen); static IUniConfGen *creator(WvStringParm s, IObject *) { return new UniFileSystemGen(s, 0777); } WvMoniker UniFileSystemGenMoniker("fs", creator); UniFileSystemGen::UniFileSystemGen(WvStringParm _dir, mode_t _mode) : dir(_dir), mode(_mode) { } static bool key_safe(const UniConfKey &key) { UniConfKey::Iter i(key); for (i.rewind(); i.next(); ) { if (*i == "." || *i == ".." || *i == "") return false; // unsafe key segments } // otherwise a safe filename return true; } WvString UniFileSystemGen::get(const UniConfKey &key) { WvString null; if (!key_safe(key)) return null; WvString path("%s/%s", dir, key); // WARNING: this code depends on the ability to open() a directory // as long as we don't read it, because we want to fstat() it after. WvFile file(path, O_RDONLY); if (!file.isok()) return null; // unreadable; pretend it doesn't exist struct stat st; if (fstat(file.getrfd(), &st) < 0) return null; // openable but can't stat? That's odd. if (S_ISREG(st.st_mode)) { WvDynBuf buf; while (file.isok()) file.read(buf, 4096); if (file.geterr()) return null; else return buf.getstr(); } else return ""; // exists, but pretend it's an empty file } void UniFileSystemGen::set(const UniConfKey &key, WvStringParm value) { if (!key_safe(key)) return; WvString base("%s/%s", dir, key.removelast(1)); WvString path("%s/%s", dir, key); mkdirp(base, mode); if (value.isnull()) rm_rf(path); else { WvFile file(path, O_WRONLY|O_CREAT|O_TRUNC, mode & 0666); file.write(value); } } void UniFileSystemGen::setv(const UniConfPairList &pairs) { setv_naive(pairs); } class UniFileSystemGenIter : public UniConfGen::Iter { private: UniFileSystemGen *gen; WvDirIter i; UniConfKey rel; public: UniFileSystemGenIter(UniFileSystemGen *_gen, WvStringParm path, const UniConfKey &_rel) : gen(_gen), i(path, false), rel(_rel) { } ~UniFileSystemGenIter() { } void rewind() { i.rewind(); } bool next() { return i.next(); } UniConfKey key() const { return i->relname; } WvString value() const { return gen->get(WvString("%s/%s", rel, i->relname)); } }; UniConfGen::Iter *UniFileSystemGen::iterator(const UniConfKey &key) { if (!key_safe(key)) return NULL; return new UniFileSystemGenIter(this, WvString("%s/%s", dir, key), key); } wvstreams-4.6.1/uniconf/uniautogen.cc0000644000175000001440000000401211036722347016722 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A UniConf moniker that uses an .ini file to look up which moniker it * should use to find the config file/subtree for a particular application. */ #include "uniconfroot.h" #include "unisubtreegen.h" #include "wvlinkerhack.h" WV_LINK(UniAutoGen); /** * The moniker from which the auto: moniker retrieves its own settings. * It's a bit silly to override this (since the point is to autoconfigure, * and manually configuring the autoconfiguration thing is silly) but it's * useful for writing unit tests. */ WvString uniautogen_moniker("default:ini:/etc/uniconf.conf"); /* * A moniker for finding the "right" config generator for a particular * application, given the application name. * * For example, for moniker "auto:org/gnome/Nautilus", we would: * * - open /etc/uniconf.conf. * - look for org/gnome/Nautilus in there. * - if it exists, use that value as the config moniker, and return. * - else, look for org/gnome * - if it exists, go get that config moniker, take the subtree * "Nautilus" from there, and return. * - else, look for org * - if it exists, go get that config moniker, take the subtree * "gnome/Nautilus" from there, and return. * - else, look for / * - if it exists, go get that config moniker, take the subtree * "org/gnome/Nautilus" from there, and return. * - else, return a null: generator. */ static IUniConfGen *creator(WvStringParm s, IObject *_obj) { UniConfRoot cfg((UniConfGen *) wvcreate(uniautogen_moniker, _obj), true); const UniConfKey appname(s); for (int i = appname.numsegments(); i >= 0; i--) { UniConfKey prefix(appname.first(i)), suffix(appname.removefirst(i)); if (!!cfg.xget(prefix)) { return new UniSubtreeGen(wvcreate(cfg.xget(prefix)), suffix); } } return wvcreate("null:"); } static WvMoniker autoreg("auto", creator); wvstreams-4.6.1/uniconf/uniinigen.cc0000644000175000001440000003274511062545075016547 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generator for .ini files. */ #include "uniinigen.h" #include "strutils.h" #include "unitempgen.h" #include "wvfile.h" #include "wvmoniker.h" #include "wvstringmask.h" #include "wvtclstring.h" #include #include "wvlinkerhack.h" WV_LINK(UniIniGen); static IUniConfGen *creator(WvStringParm s, IObject*) { return new UniIniGen(s); } WvMoniker UniIniGenMoniker("ini", creator); /***** UniIniGen *****/ UniIniGen::UniIniGen(WvStringParm _filename, int _create_mode, UniIniGen::SaveCallback _save_cb) : filename(_filename), create_mode(_create_mode), log(_filename), save_cb(_save_cb) { // Create the root, since this generator can't handle it not existing. UniTempGen::set(UniConfKey::EMPTY, WvString::empty); memset(&old_st, 0, sizeof(old_st)); } void UniIniGen::set(const UniConfKey &key, WvStringParm value) { UniTempGen::set(key, value); // Re-create the root, since this generator can't handle it not existing. if (value.isnull() && key.isempty()) UniTempGen::set(UniConfKey::EMPTY, WvString::empty); } UniIniGen::~UniIniGen() { } bool UniIniGen::refresh() { WvFile file(filename, O_RDONLY); #ifndef _WIN32 struct stat statbuf; if (file.isok() && fstat(file.getrfd(), &statbuf) == -1) { log(WvLog::Warning, "Can't stat '%s': %s\n", filename, strerror(errno)); file.close(); } if (file.isok() && (statbuf.st_mode & S_ISVTX)) { file.close(); file.seterr(EAGAIN); } if (file.isok() // guarantes statbuf is valid from above && statbuf.st_ctime == old_st.st_ctime && statbuf.st_dev == old_st.st_dev && statbuf.st_ino == old_st.st_ino && statbuf.st_blocks == old_st.st_blocks && statbuf.st_size == old_st.st_size) { log(WvLog::Debug3, "refresh: file hasn't changed; do nothing.\n"); return true; } memcpy(&old_st, &statbuf, sizeof(statbuf)); #endif if (!file.isok()) { log(WvLog::Warning, "Can't open '%s' for reading: %s\n" "...starting with blank configuration.\n", filename, file.errstr()); return false; } // loop over all Tcl words in the file UniTempGen *newgen = new UniTempGen(); newgen->set(UniConfKey::EMPTY, WvString::empty); UniConfKey section; WvDynBuf buf; while (buf.used() || file.isok()) { if (file.isok()) { // read entire lines to ensure that we get whole values char *line = file.blocking_getline(-1); if (line) { buf.putstr(line); buf.put('\n'); // this was auto-stripped by getline() } } WvString word; while (!(word = wvtcl_getword(buf, WVTCL_NASTY_NEWLINES, false)).isnull()) { //log(WvLog::Info, "LINE: '%s'\n", word); char *str = trim_string(word.edit()); int len = strlen(str); if (len == 0) continue; // blank line if (str[0] == '#') { // a comment line. FIXME: we drop it completely! //log(WvLog::Debug5, "Comment: \"%s\"\n", str + 1); continue; } if (str[0] == '[' && str[len - 1] == ']') { // a section name str[len - 1] = '\0'; WvString name(wvtcl_unescape(trim_string(str + 1))); section = UniConfKey(name); //log(WvLog::Debug5, "Refresh section: \"%s\"\n", section); continue; } // we possibly have a key = value line WvConstStringBuffer line(word); static const WvStringMask nasty_equals("="); WvString name = wvtcl_getword(line, nasty_equals, false); if (!name.isnull() && line.used()) { name = wvtcl_unescape(trim_string(name.edit())); if (!!name) { UniConfKey key(name); key.prepend(section); WvString value = line.getstr(); assert(*value == '='); value = wvtcl_unescape(trim_string(value.edit() + 1)); newgen->set(key, value.unique()); //log(WvLog::Debug5, "Refresh: (\"%s\", \"%s\")\n", // key, value); continue; } } // if we get here, the line was tcl-decoded but not useful. log(WvLog::Warning, "Ignoring malformed input line: \"%s\"\n", word); } if (buf.used() && !file.isok()) { // EOF and some of the data still hasn't been used. Weird. // Let's remove a line of data and try again. size_t offset = buf.strchr('\n'); assert(offset); // the last thing we put() is *always* a newline! WvString line1(trim_string(buf.getstr(offset).edit())); if (!!line1) // not just whitespace log(WvLog::Warning, "XXX Ignoring malformed input line: \"%s\"\n", line1); } } if (file.geterr()) { log(WvLog::Warning, "Error reading from config file: %s\n", file.errstr()); WVRELEASE(newgen); return false; } // switch the trees and send notifications hold_delta(); UniConfValueTree *oldtree = root; UniConfValueTree *newtree = newgen->root; root = newtree; newgen->root = NULL; dirty = false; oldtree->compare(newtree, wv::bind(&UniIniGen::refreshcomparator, this, _1, _2)); delete oldtree; unhold_delta(); WVRELEASE(newgen); UniTempGen::refresh(); return true; } // returns: true if a==b bool UniIniGen::refreshcomparator(const UniConfValueTree *a, const UniConfValueTree *b) { if (a) { if (b) { if (a->value() != b->value()) { // key changed delta(b->fullkey(), b->value()); // CHANGED return false; } return true; } else { // key removed // Issue notifications for every that is missing. a->visit(wv::bind(&UniIniGen::notify_deleted, this, _1, _2), NULL, false, true); return false; } } else // a didn't exist { assert(b); // key added delta(b->fullkey(), b->value()); // ADDED return false; } } #ifndef _WIN32 bool UniIniGen::commit_atomic(WvStringParm real_filename) { struct stat statbuf; if (lstat(real_filename, &statbuf) == -1) { if (errno != ENOENT) return false; } else if (!S_ISREG(statbuf.st_mode)) return false; WvString tmp_filename("%s.tmp%s", real_filename, getpid()); WvFile file(tmp_filename, O_WRONLY|O_TRUNC|O_CREAT, 0000); if (file.geterr()) { log(WvLog::Warning, "Can't write '%s': %s\n", tmp_filename, strerror(errno)); unlink(tmp_filename); file.close(); return false; } save(file, *root); // write the changes out to our temp file mode_t theumask = umask(0); umask(theumask); fchmod(file.getwfd(), create_mode & ~theumask); file.close(); if (file.geterr() || rename(tmp_filename, real_filename) == -1) { log(WvLog::Warning, "Can't write '%s': %s\n", filename, strerror(errno)); unlink(tmp_filename); return false; } return true; } #endif void UniIniGen::commit() { if (!dirty) return; UniTempGen::commit(); #ifdef _WIN32 // Windows doesn't support all that fancy stuff, just open the // file and be done with it WvFile file(filename, O_WRONLY|O_TRUNC|O_CREAT, create_mode); save(file, *root); // write the changes out to our file file.close(); if (file.geterr()) { log(WvLog::Warning, "Can't write '%s': %s\n", filename, file.errstr()); return; } #else WvString real_filename(filename); char resolved_path[PATH_MAX]; if (realpath(filename, resolved_path) != NULL) real_filename = resolved_path; if (!commit_atomic(real_filename)) { WvFile file(real_filename, O_WRONLY|O_TRUNC|O_CREAT, create_mode); struct stat statbuf; if (fstat(file.getwfd(), &statbuf) == -1) { log(WvLog::Warning, "Can't write '%s' ('%s'): %s\n", filename, real_filename, strerror(errno)); return; } fchmod(file.getwfd(), (statbuf.st_mode & 07777) | S_ISVTX); save(file, *root); if (!file.geterr()) { /* We only reset the sticky bit if all went well, but before * we close it, because we need the file descriptor. */ statbuf.st_mode = statbuf.st_mode & ~S_ISVTX; fchmod(file.getwfd(), statbuf.st_mode & 07777); } else log(WvLog::Warning, "Error writing '%s' ('%s'): %s\n", filename, real_filename, file.errstr()); } #endif dirty = false; } // may return false for strings that wvtcl_escape would escape anyway; this // may not escape tcl-invalid strings, but that's on purpose so we can keep // old-style .ini file compatibility (and wvtcl_getword() and friends can // still parse them anyway). static bool absolutely_needs_escape(WvStringParm s, const char *sepchars) { const char *cptr; int numbraces = 0; bool inescape = false, inspace = false; if (isspace((unsigned char)*s)) return true; // leading whitespace needs escaping for (cptr = s; *cptr; cptr++) { if (inescape) inescape = false; // fine else if (!numbraces && strchr(sepchars, *cptr)) return true; // one of the magic characters, and not escaped else if (*cptr == '\\') inescape = true; else if (*cptr == '{') numbraces++; else if (*cptr == '}') numbraces--; inspace = isspace((unsigned char)*cptr); if (numbraces < 0) // yikes! mismatched braces will need some help. return false; } if (inescape || inspace) return true; // terminating backslash or whitespace... evil. if (numbraces != 0) return true; // uneven number of braces, can't be good // otherwise, I guess we're safe. return false; } static void printsection(WvStream &file, const UniConfKey &key, UniIniGen::SaveCallback save_cb) { WvString s; static const WvStringMask nasties("\r\n[]"); if (absolutely_needs_escape(key, "\r\n[]")) s = wvtcl_escape(key, nasties); else s = key; // broken up for optimization, no temp wvstring created //file.print("\n[%s]\n", s); file.print("\n["); file.print(s); file.print("]\n"); if (!!save_cb) save_cb(); } static void printkey(WvStream &file, const UniConfKey &_key, WvStringParm _value, UniIniGen::SaveCallback save_cb) { WvString key, value; static const WvStringMask nasties("\r\n\t []=#"); if (absolutely_needs_escape(_key, "\r\n[]=#\"")) key = wvtcl_escape(_key, nasties); else if (_key == "") key = "/"; else key = _key; // value is more relaxed, since we don't use wvtcl_getword after we grab // the "key=" part of each line if (absolutely_needs_escape(_value, "\r\n")) value = wvtcl_escape(_value, WVTCL_NASTY_SPACES); else value = _value; // need to escape []#= in key only to distinguish a key/value // pair from a section name or comment and to delimit the value // broken up for optimization, no temp wvstring created //file.print("%s = %s\n", key, value); file.print(key); file.print(" = "); file.print(value); file.print("\n"); if (!!save_cb) save_cb(); } static void save_sect(WvStream &file, UniConfValueTree &toplevel, UniConfValueTree §, bool &printedsection, bool recursive, UniIniGen::SaveCallback save_cb) { UniConfValueTree::Iter it(sect); for (it.rewind(); it.next(); ) { UniConfValueTree &node = *it; // FIXME: we never print empty-string ("") keys, for compatibility // with WvConf. Example: set x/y = 1; delete x/y; now x = "", because // it couldn't be NULL while x/y existed, and nobody auto-deleted it // when x/y went away. Therefore we would try to write x = "" to the // config file, but that's not what WvConf would do. // // The correct fix would be to auto-delete x if the only reason it // exists is for x/y. But since that's hard, we'll just *never* // write lines for "" entries. Icky, but it works. if (!!node.value())// || !node.haschildren()) { if (!printedsection) { printsection(file, toplevel.fullkey(), save_cb); printedsection = true; } printkey(file, node.fullkey(&toplevel), node.value(), save_cb); } // print all children, if requested if (recursive && node.haschildren()) save_sect(file, toplevel, node, printedsection, recursive, save_cb); } } void UniIniGen::save(WvStream &file, UniConfValueTree &parent) { // parent might be NULL, so it really should be a pointer, not // a reference. Oh well... if (!&parent) return; if (parent.fullkey() == root->fullkey()) { // the root itself is a special case, since it's not in a section, // and it's never NULL (so we don't need to write it if it's just // blank) if (!!parent.value()) printkey(file, parent.key(), parent.value(), save_cb); } bool printedsection = false; save_sect(file, parent, parent, printedsection, false, save_cb); UniConfValueTree::Iter it(parent); for (it.rewind(); it.next(); ) { UniConfValueTree &node = *it; printedsection = false; save_sect(file, node, node, printedsection, true, save_cb); } } wvstreams-4.6.1/uniconf/uniwatch.cc0000644000175000001440000000130111036722347016364 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class that does add_callback when created and del_callback when * destroyed. See uniwatch.h */ #include "uniwatch.h" #include "uniconfroot.h" UniWatch::UniWatch(const UniConf &_cfg, const UniConfCallback &_cb, bool _recurse) : cfg(_cfg), cb(_cb), recurse(_recurse) { cfg.add_callback(this, cb, recurse); } UniWatch::UniWatch(const UniConf &_cfg, bool *b, bool _recurse) : cfg(_cfg), cb(wv::bind(&UniConfRoot::setbool_callback, b, _1, _2)), recurse(_recurse) { cfg.add_callback(this, cb, recurse); } UniWatch::~UniWatch() { cfg.del_callback(this, recurse); } wvstreams-4.6.1/uniconf/uniconfkey.cc0000644000175000001440000001637011036722347016730 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf hierarchical key path abstraction. */ #include "wvassert.h" #include "wvstream.h" #include "uniconfkey.h" #include "wvhash.h" #include #include #include unsigned WvHash(const UniConfKey &k) { int numsegs = k.right - k.left; unsigned result; switch (numsegs) { case 0: result = 0; break; case 1: result = WvHash(k.store->segments[k.left]); break; default: result = WvHash(k.store->segments[k.left]) ^ WvHash(k.store->segments[k.right - 1]) ^ numsegs; break; } return result; } // The initial value of 1 for the ref_count of these guarantees // that they won't ever be deleted UniConfKey::Store UniConfKey::EMPTY_store(1, 1); UniConfKey::Store UniConfKey::ANY_store(1, 1, "*"); UniConfKey::Store UniConfKey::RECURSIVE_ANY_store(1, 1, "..."); UniConfKey UniConfKey::EMPTY(&EMPTY_store, 0, 0); UniConfKey UniConfKey::ANY(&ANY_store, 0, 1); UniConfKey UniConfKey::RECURSIVE_ANY(&RECURSIVE_ANY_store, 0, 1); UniConfKey::Store::Store(int size, int _ref_count, WvStringParm key) : segments(size), ref_count(_ref_count) { if (!key) return; WvStringList parts; parts.split(key, "/"); segments.resize(parts.count()); WvStringList::Iter part(parts); for (part.rewind(); part.next(); ) { if (!*part) continue; segments.append(*part); } if (!!key && key[key.len()-1] == '/' && segments.used() > 0) segments.append(Segment()); } UniConfKey &UniConfKey::collapse() { if ((right - left == 1 && !store->segments[right-1]) || right == left) { if (--store->ref_count == 0) delete store; store = &EMPTY_store; left = right = 0; ++store->ref_count; } return *this; } void UniConfKey::unique() { if (store->ref_count == 1) return; store->ref_count--; Store *old_store = store; store = new Store(right - left, 1); for (int i=left; isegments.append(old_store->segments[i]); right -= left; left = 0; } UniConfKey::UniConfKey(const UniConfKey &_path, const UniConfKey &_key) : store(new Store(_path.numsegments() + _key.numsegments() + 1, 1)), left(0), right(0) { bool hastrailingslash = _key.isempty() || _key.hastrailingslash(); for (int i=_path.left; i<_path.right; ++i) { const Segment &segment = _path.store->segments[i]; if (!segment) continue; store->segments.append(segment); ++right; } for (int j=_key.left; j<_key.right; ++j) { const Segment &segment = _key.store->segments[j]; if (!segment) continue; store->segments.append(segment); ++right; } if (hastrailingslash) { store->segments.append(""); ++right; } collapse(); } void UniConfKey::append(const UniConfKey &_key) { bool hastrailingslash = _key.isempty() || _key.hastrailingslash(); unique(); store->segments.resize(right - left + _key.right - _key.left + 1); for (int j=_key.left; j<_key.right; ++j) { const Segment &segment = _key.store->segments[j]; if (!segment) continue; store->segments.replace(right, segment); ++right; } if (hastrailingslash) { store->segments.replace(right, ""); ++right; } collapse(); } void UniConfKey::prepend(const UniConfKey &_key) { unique(); int shift = 0; for (int j=_key.left; j<_key.right; ++j) { if (!!_key.store->segments[j]) ++shift; } store->segments.resize(shift + right - left, shift); for (int j=_key.left; j<_key.right; ++j) { const Segment &segment = _key.store->segments[j]; if (!segment) continue; store->segments.replace(left + j - _key.left, segment); ++right; } collapse(); } bool UniConfKey::iswild() const { for (int i=left; isegments[i].iswild()) return true; return false; } UniConfKey UniConfKey::pop(int n) { if (n == 0) return UniConfKey(); unique(); if (n > right - left) n = right - left; if (n < 0) n = 0; int old_left = left; left += n; UniConfKey result(store, old_left, left); collapse(); return result.collapse(); } UniConfKey UniConfKey::range(int i, int j) const { if (j > right - left) j = right - left; if (i < 0) i = 0; if (j < i) j = i; return UniConfKey(store, left + i, left + j).collapse(); } WvString UniConfKey::printable() const { switch (right - left) { case 0: return WvString::empty; case 1: return store->segments[left]; default: { WvDynBuf buf; for (int i=left; isegments[i]); if (i < right-1) buf.put('/'); } return buf.getstr(); } } } int UniConfKey::compareto(const UniConfKey &other) const { int i, j; for (i=left, j=other.left; isegments[i], other.store->segments[j]); if (val != 0) return val; } if (i == right) { if (j == other.right) return 0; else return -1; } else return 1; } bool UniConfKey::matches(const UniConfKey &pattern) const { // TODO: optimize this function if (*this == pattern) return true; UniConfKey head(pattern.first()); // handle * wildcard if (head == UniConfKey::ANY) { if (isempty()) return false; return removefirst().matches(pattern.removefirst()); } // handle ... wildcard if (head == UniConfKey::RECURSIVE_ANY) { UniConfKey tail(pattern.removefirst()); if (tail.isempty()) return true; // recursively matches anything for (int n = 0; ; ++n) { UniConfKey part(removefirst(n)); if (part.matches(tail)) return true; if (part.isempty()) break; } return false; } // no other wildcard arrangements currently supported return false; } bool UniConfKey::suborsame(const UniConfKey &key) const { int n = numsegments(); if (hastrailingslash()) n -= 1; if (key.first(n) == first(n)) return true; return false; } bool UniConfKey::suborsame(const UniConfKey &key, UniConfKey &subkey) const { int n = numsegments(); // Compensate for the directory-style naming convention of the // trailing slash. if (hastrailingslash()) n -= 1; if (key.first(n) == first(n)) { subkey = key.removefirst(n); return true; } return false; } UniConfKey UniConfKey::subkey(const UniConfKey &key) const { UniConfKey answer; wvassert(suborsame(key, answer), "this = '%s'\nkey = '%s'", printable(), key); return answer; } wvstreams-4.6.1/uniconf/unifastregetgen.cc0000644000175000001440000000454611036722347017752 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2002-2005 Net Integration Technologies, Inc. * * A lightweight but slightly dangerous version of UniCacheGen. */ #include #include "unifastregetgen.h" #include "uniconftree.h" #include "wvmoniker.h" // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the // given moniker. static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniFastRegetGen(wvcreate(s, _obj)); } static WvMoniker reg("fast-reget", creator); UniFastRegetGen::UniFastRegetGen(IUniConfGen *_inner) : UniFilterGen(_inner), tree(NULL) { tree = new UniConfValueTree(NULL, "/", UniFilterGen::get("/")); } UniFastRegetGen::~UniFastRegetGen() { if (tree) { delete tree; tree = NULL; } } void UniFastRegetGen::gencallback(const UniConfKey &key, WvStringParm value) { if (tree == NULL) return; // initialising UniConfValueTree *t = tree->find(key); if (t) // never previously retrieved; don't cache it t->setvalue(value); UniFilterGen::gencallback(key, value); } WvString UniFastRegetGen::get(const UniConfKey &key) { if (!tree) { wvassert(tree, "key: '%s'", key); abort(); } // Keys with trailing slashes can't have values set on them if (key.hastrailingslash()) return WvString::null; UniConfValueTree *t = tree->find(key); if (!t) { UniConfKey parentkey(key.removelast()); get(parentkey); // guaranteed to create parent node t = tree->find(parentkey); assert(t); WvString value; if (!t->value().isnull()) // if parent is null, child guaranteed null value = UniFilterGen::get(key); new UniConfValueTree(t, key.last(), value); return value; } else return t->value(); } bool UniFastRegetGen::exists(const UniConfKey &key) { // even if inner generator has a more efficient version of exists(), // do it this way so we can cache the result. return !get(key).isnull(); } bool UniFastRegetGen::haschildren(const UniConfKey &key) { if (!tree) { wvassert(tree, "key: '%s'", key); abort(); } // if we already know the node is null, we can short circuit this one UniConfValueTree *t = tree->find(key); if (t && t->value().isnull()) return false; // definitely no children return UniFilterGen::haschildren(key); } wvstreams-4.6.1/uniconf/uninullgen.cc0000644000175000001440000000062011036722347016725 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A generator that is always empty and rejects changes. */ #include "uninullgen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(UniNullGen); static IUniConfGen *creator(WvStringParm, IObject*) { return new UniNullGen(); } static WvMoniker reg("null", creator); wvstreams-4.6.1/uniconf/uniretrygen.cc0000644000175000001440000001360711036722347017131 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConfGen that reconnects to an inner generator whenever the inner * generator is no longer OK. */ #include "uniretrygen.h" #include "wvmoniker.h" #include "wvtclstring.h" #include "wvstringlist.h" #include "wvlinkerhack.h" WV_LINK(UniRetryGen); #if 0 #define DPRINTF(format, args...) fprintf(stderr, format ,##args); #else #define DPRINTF if (0) printf #endif static IUniConfGen *creator(WvStringParm encoded_params, IObject *_obj) { DPRINTF("encoded_params = %s\n", encoded_params.cstr()); WvStringList params; wvtcl_decode(params, encoded_params); if (params.count() == 0) return NULL; WvString moniker = params.popstr(); if (params.count() == 0) return new UniRetryGen(moniker); WvString retry_interval_ms_str = params.popstr(); time_t retry_interval_ms = retry_interval_ms_str.num(); if (retry_interval_ms < 0) retry_interval_ms = 0; return new UniRetryGen(moniker, UniRetryGen::ReconnectCallback(), retry_interval_ms); } static WvMoniker reg("retry", creator); /***** UniRetryGen *****/ UniRetryGen::UniRetryGen(WvStringParm _moniker, ReconnectCallback _reconnect_callback, time_t _retry_interval_ms) : UniFilterGen(NULL), log(WvString("UniRetryGen %s", _moniker), WvLog::Debug1), moniker(_moniker), reconnect_callback(_reconnect_callback), retry_interval_ms(_retry_interval_ms), next_reconnect_attempt(wvtime()) { DPRINTF("UniRetryGen::UniRetryGen(%s, %ld)\n", moniker.cstr(), retry_interval_ms); maybe_reconnect(); } void UniRetryGen::maybe_reconnect() { if (!inner()) { if (!(wvtime() < next_reconnect_attempt)) { IUniConfGen *gen = wvcreate(moniker); if (!gen) { DPRINTF("UniRetryGen::maybe_reconnect: !gen\n"); return; } if (gen->isok()) { DPRINTF("UniRetryGen::maybe_reconnect: gen->isok()\n"); log("Connected\n"); setinner(gen); if (!!reconnect_callback) reconnect_callback(*this); } else { DPRINTF("UniRetryGen::maybe_reconnect: !gen->isok()\n"); WVRELEASE(gen); next_reconnect_attempt = msecadd(next_reconnect_attempt, retry_interval_ms); } } } } void UniRetryGen::maybe_disconnect() { if (inner() && !inner()->isok()) { DPRINTF("UniRetryGen::maybe_disconnect: inner() && !inner()->isok()\n"); log("Disconnected\n"); IUniConfGen *old_inner = inner(); setinner(NULL); WVRELEASE(old_inner); next_reconnect_attempt = msecadd(wvtime(), retry_interval_ms); } } void UniRetryGen::commit() { maybe_reconnect(); if (UniFilterGen::isok()) UniFilterGen::commit(); maybe_disconnect(); } bool UniRetryGen::refresh() { maybe_reconnect(); bool result; if (UniFilterGen::isok()) result = UniFilterGen::refresh(); else result = false; maybe_disconnect(); return result; } void UniRetryGen::prefetch(const UniConfKey &key, bool recursive) { maybe_reconnect(); if (UniFilterGen::isok()) UniFilterGen::prefetch(key, recursive); maybe_disconnect(); } WvString UniRetryGen::get(const UniConfKey &key) { maybe_reconnect(); WvString result; if (UniFilterGen::isok()) { result = UniFilterGen::get(key); DPRINTF("UniRetryGen::get(%s) returns %s\n", key.printable().cstr(), result.cstr()); } else if (key == "") { result = ""; DPRINTF("UniRetryGen::get(%s) returns %s because it is root key\n", key.printable().cstr(), result.cstr()); } else { DPRINTF("UniRetryGen::get(%s): !isok()\n", key.printable().cstr()); result = WvString::null; } maybe_disconnect(); return result; } void UniRetryGen::set(const UniConfKey &key, WvStringParm value) { maybe_reconnect(); if (UniFilterGen::isok()) UniFilterGen::set(key, value); maybe_disconnect(); } bool UniRetryGen::exists(const UniConfKey &key) { maybe_reconnect(); DPRINTF("UniRetryGen::exists(%s)\n", key.printable().cstr()); bool result; if (UniFilterGen::isok()) { result = UniFilterGen::exists(key); DPRINTF("UniRetryGen::exists: returns %s\n", result? "true": "false"); } else { DPRINTF("UniRetryGen::exists: !isok()\n"); if (key == "") { // here we assume that at least the mount point exists // see void UniMountGen::makemount() that create all the keys with // an empty string result = true; } else { result = false; } } maybe_disconnect(); return result; } bool UniRetryGen::haschildren(const UniConfKey &key) { maybe_reconnect(); bool result; if (UniFilterGen::isok()) result = UniFilterGen::haschildren(key); else result = false; maybe_disconnect(); return result; } bool UniRetryGen::isok() { maybe_reconnect(); bool result = UniFilterGen::isok(); maybe_disconnect(); return result; } UniConfGen::Iter *UniRetryGen::iterator(const UniConfKey &key) { maybe_reconnect(); Iter *result; if (UniFilterGen::isok()) result = UniFilterGen::iterator(key); else result = NULL; maybe_disconnect(); return result; } UniConfGen::Iter *UniRetryGen::recursiveiterator(const UniConfKey &key) { maybe_reconnect(); Iter *result = UniFilterGen::recursiveiterator(key); maybe_disconnect(); return result; } wvstreams-4.6.1/uniconf/unimountgen.cc0000644000175000001440000002341511036722347017124 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines a UniConfGen that manages a tree of UniConfGen instances. */ #include "unimountgen.h" #include "wvmoniker.h" #include "wvhash.h" #include "wvstrutils.h" #include "unilistiter.h" #include "wvstringtable.h" #include /***** UniMountGen *****/ UniMountGen::UniMountGen() { // nothing special } UniMountGen::~UniMountGen() { zap(); } WvString UniMountGen::get(const UniConfKey &key) { UniGenMount *found = findmount(key); if (!found) { // if there are keys that _do_ have a mount under this one, // then we consider it to exist (as a key with a blank value) if (has_subkey(key, NULL)) return ""; return WvString::null; } return found->gen->get(trimkey(found->key, key)); } void UniMountGen::set(const UniConfKey &key, WvStringParm value) { UniGenMount *found = findmount(key); if (!found) return; found->gen->set(trimkey(found->key, key), value); } struct UniMountGen::UniGenMountPairs { UniGenMount *mount; WvString key; UniConfPairList pairs; UniGenMountPairs(UniGenMount *_mount) : mount(_mount) { if (mount) key = mount->key; } }; void UniMountGen::setv(const UniConfPairList &pairs) { UniGenMountPairsDict mountpairs(mounts.count()); { MountList::Iter m(mounts); for (m.rewind(); m.next(); ) mountpairs.add(new UniGenMountPairs(m.ptr()), true); } { UniConfPairList::Iter pair(pairs); for (pair.rewind(); pair.next(); ) { UniGenMount *found = findmount(pair->key()); if (!found) continue; UniConfPair *trimmed = new UniConfPair(trimkey(found->key, pair->key()), pair->value()); mountpairs[found->key]->pairs.add(trimmed, true); } } UniGenMountPairsDict::Iter i(mountpairs); for (i.rewind(); i.next(); ) i->mount->gen->setv(i->pairs); } bool UniMountGen::exists(const UniConfKey &key) { UniGenMount *found = findmount(key); //fprintf(stdout, "unimountgen:exists:found %p\n", found); if (found && found->gen->exists(trimkey(found->key, key))) return true; else //if there's something mounted and set on a subkey, this key must //*exist* along the way return has_subkey(key, found); } bool UniMountGen::haschildren(const UniConfKey &key) { UniGenMount *found = findmount(key); // fprintf(stdout, "haschildren:found %p\n", found); if (found && found->gen->haschildren(trimkey(found->key, key))) return true; // if we get here, the generator we used didn't have a subkey. We want // to see if there's anyone mounted at a subkey of the requested key; if // so, then we definitely have a subkey. return has_subkey(key, found); } bool UniMountGen::has_subkey(const UniConfKey &key, UniGenMount *found) { MountList::Iter i(mounts); for (i.rewind(); i.next(); ) { if (key.suborsame(i->key) && key < i->key) { //fprintf(stdout, "%s has_subkey %s : true\n", key.printable().cstr(), // i->key.printable().cstr()); return true; } // the list is sorted innermost-first. So if we find the key // we started with, we've finished searching all children of it. if (found && (i->gen == found->gen)) break; } //fprintf(stdout, "%s has_subkey false \n", key.printable().cstr()); return false; } bool UniMountGen::refresh() { hold_delta(); bool result = true; MountList::Iter i(mounts); for (i.rewind(); i.next(); ) result = result && i->gen->refresh(); unhold_delta(); return result; } void UniMountGen::commit() { hold_delta(); MountList::Iter i(mounts); for (i.rewind(); i.next();) i->gen->commit(); unhold_delta(); } IUniConfGen *UniMountGen::mount(const UniConfKey &key, WvStringParm moniker, bool refresh) { IUniConfGen *gen = wvcreate(moniker); if (gen) mountgen(key, gen, refresh); // assume always succeeds for now #if DEBUG assert(gen && "Moniker doesn't get us a generator!"); #endif if (gen && !gen->exists("/")) gen->set("/", ""); return gen; } IUniConfGen *UniMountGen::mountgen(const UniConfKey &key, IUniConfGen *gen, bool refresh) { if (!gen) return NULL; UniGenMount *newgen = new UniGenMount(gen, key); gen->add_callback(this, wv::bind(&UniMountGen::gencallback, this, newgen->key, _1, _2)); hold_delta(); delta(key, WvString()); makemount(key); if (gen && refresh) gen->refresh(); mounts.prepend(newgen, true); delta(key, get(key)); unhold_delta(); if (!gen->exists("/")) gen->set("/", ""); return gen; } void UniMountGen::unmount(IUniConfGen *gen, bool commit) { if (!gen) return; MountList::Iter i(mounts); for (i.rewind(); i.next() && i->gen != gen; ) ; if (i->gen != gen) return; hold_delta(); if (commit) gen->commit(); gen->del_callback(this); UniConfKey key(i->key); IUniConfGen *next = NULL; delta(key, WvString()); // Find the first generator mounted past the one we're removing (if // any). This way we can make sure that each generator still has keys // leading up to it (in case they lost their mountpoint due to the // unmounted generator) i.xunlink(); if (i.next()) next = i->gen; for (i.rewind(); i.next() && i->gen != next; ) { if (key.suborsame(i->key) && key != i->key) { makemount(i->key); delta(i->key, get(i->key)); } } unhold_delta(); } void UniMountGen::zap() { while (!mounts.isempty()) unmount(mounts.first()->gen, false); } IUniConfGen *UniMountGen::whichmount(const UniConfKey &key, UniConfKey *mountpoint) { MountList::Iter i(mounts); for (i.rewind(); i.next(); ) { if (i->key.suborsame(key)) { if (mountpoint) *mountpoint = i->key; return i->gen; } } return NULL; } bool UniMountGen::ismountpoint(const UniConfKey &key) { MountList::Iter i(mounts); for (i.rewind(); i.next(); ) { if (i->key == key) return true; } return false; } static int wvstrcmp(const WvString *l, const WvString *r) { return strcmp(*l, *r); } UniMountGen::Iter *UniMountGen::iterator(const UniConfKey &key) { UniGenMount *found = findmount(key); if (found) return found->gen->iterator(trimkey(found->key, key)); else { // deal with elements mounted on nothingness. // FIXME: this is really a hack, and should (somehow) be dealt with // in a more general way. ListIter *it = new ListIter(this); MountList::Iter i(mounts); WvStringTable t(10); for (i.rewind(); i.next(); ) { if (key.numsegments() < i->key.numsegments() && key.suborsame(i->key)) { // trim off any stray segments coming between the virtual // "key" we're iterating over and the mount UniConfKey k1 = i->key.first(key.numsegments() + 1); UniConfKey k2 = k1.last(); // final "key" should be size 1 if (!t[k2]) t.add(new WvString(k2), true); } } WvStringTable::Sorter s(t, &::wvstrcmp); for (s.rewind(); s.next();) it->add(*s); return it; } } // FIXME: this function will be rather slow if you try to iterate over multiple // generators and the latency level is high (as is the case with e.g.: the tcp generator). // the fast path will only kick in if you iterate over a single generator. UniMountGen::Iter *UniMountGen::recursiveiterator(const UniConfKey &key) { UniGenMount *found = findmountunder(key); if (found) return found->gen->recursiveiterator(trimkey(found->key, key)); else return UniConfGen::recursiveiterator(key); } UniMountGen::UniGenMount *UniMountGen::findmount(const UniConfKey &key) { // Find the needed generator and keep it as a lastfound MountList::Iter i(mounts); for (i.rewind(); i.next(); ) { if (i->key.suborsame(key)) return i.ptr(); } return NULL; } UniMountGen::UniGenMount *UniMountGen::findmountunder(const UniConfKey &key) { UniMountGen::UniGenMount * foundmount = NULL; int num_found_mounts = 0; // Find the needed generator and keep it as a lastfound MountList::Iter i(mounts); for (i.rewind(); i.next(); ) { // key lies beneath mount (only care about the first) if (i->key.suborsame(key) && !foundmount) { foundmount = i.ptr(); num_found_mounts++; } // mount lies beneath key else if (key.suborsame(i->key)) { num_found_mounts++; } } if (num_found_mounts == 1 && foundmount) return foundmount; return NULL; } void UniMountGen::gencallback(const UniConfKey &base, const UniConfKey &key, WvStringParm value) { delta(UniConfKey(base, key), value); } void UniMountGen::makemount(const UniConfKey &key) { // Create any keys needed leading up to the mount generator so that the // mountpoint exists UniConfKey::Iter i(key); UniConfKey points; for (i.rewind(); i.next(); ) { points.append(*i); if (get(points).isnull()) set(points, ""); } // Set the mountpoint in the sub generator instead of on the generator // itself (since set will set it on the generator, instead of making the // mountpoint) UniGenMount *found = findmount(points.removelast()); if (!found) return; if (found->gen->get(trimkey(found->key, key)).isnull()) found->gen->set(trimkey(found->key, key), ""); } wvstreams-4.6.1/uniconf/unisecuregen.cc0000644000175000001440000001254611036722347017253 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * UniSecureGen is a UniConfGen for checking permissions before allowing * access to a UniConf tree. See unisecuregen.h and unipermgen.h. */ #include "unisecuregen.h" #include "wvmoniker.h" #include "wvstringlist.h" #include "wvtclstring.h" #include "wvlog.h" #include "wvbuf.h" #include "wvlinkerhack.h" WV_LINK(UniSecureGen); static IUniConfGen *creator(WvStringParm s, IObject *) { return new UniSecureGen(s); } static WvMoniker reg("perm", creator); UniSecureGen::UniSecureGen(WvStringParm moniker, UniPermGen *_perms) : UniFilterGen(NULL) { WvString mainmon(moniker), permmon; if (!_perms) { WvConstInPlaceBuf buf(moniker, moniker.len()); permmon = wvtcl_getword(buf); mainmon = wvtcl_getword(buf); IUniConfGen *_perms = wvcreate(permmon); assert(_perms); perms = new UniPermGen(_perms); perms->refresh(); } IUniConfGen *main = wvcreate(mainmon); setinner(main); } UniSecureGen::UniSecureGen(IUniConfGen *_gen, UniPermGen *_perms) : UniFilterGen(_gen) { assert(_perms); perms = _perms; perms->refresh(); } void UniSecureGen::setcredentials(const UniPermGen::Credentials &_cred) { cred.user = _cred.user; cred.groups.zap(); WvStringTable::Iter i(_cred.groups); for (i.rewind(); i.next(); ) cred.groups.add(new WvString(*i), true); } void UniSecureGen::setcredentials(WvStringParm user, const WvStringList &groups) { cred.user = user; cred.groups.zap(); WvStringList::Iter i(groups); for (i.rewind(); i.next(); ) cred.groups.add(new WvString(*i), true); } bool UniSecureGen::refresh() { perms->refresh(); return UniFilterGen::refresh(); } void UniSecureGen::commit() { perms->commit(); UniFilterGen::commit(); } WvString UniSecureGen::get(const UniConfKey &key) { if (findperm(key, UniPermGen::READ)) { WvString val = UniFilterGen::get(key); return val; } return WvString::null; } bool UniSecureGen::exists(const UniConfKey &key) { if (findperm(key.removelast(), UniPermGen::EXEC)) return UniFilterGen::exists(key); return false; } void UniSecureGen::set(const UniConfKey &key, WvStringParm value) { if (findperm(key, UniPermGen::WRITE)) UniFilterGen::set(key, value); } bool UniSecureGen::haschildren(const UniConfKey &key) { if (findperm(key, UniPermGen::EXEC)) return UniFilterGen::haschildren(key); return false; } class _UniSecureIter : public UniConfGen::Iter { UniFilterGen::Iter *it; UniSecureGen *gen; UniConfKey subpath; public: _UniSecureIter(UniFilterGen::Iter *_it, UniSecureGen *_gen, UniConfKey _subpath) : it(_it), gen(_gen), subpath(_subpath) { } virtual ~_UniSecureIter() { delete it; } virtual void rewind() { it->rewind(); } virtual bool next() { return it->next(); } virtual UniConfKey key() const { return it->key(); } // if we've come this far, this is ok virtual WvString value() const { UniConfKey realkey = it->key(); realkey.prepend(subpath); return gen->get(realkey); } }; UniConfGen::Iter *UniSecureGen::iterator(const UniConfKey &key) { // we don't check the permissions on keys returned by the iterator, but // that's okay: since this iterator is non-recursive, and we've checked // permissions on the parent key, we know we're allowed to at least read // the *names* of all child keys (even if the value itself is unreadable) if (findperm(key, UniPermGen::EXEC)) return new _UniSecureIter(UniFilterGen::iterator(key), this, key); return NULL; } UniConfGen::Iter *UniSecureGen::recursiveiterator(const UniConfKey &key) { // FIXME: this needs to check permissions on *every* key, not just the // top one, so we'll cheat: use the default UniConfGen recursiveiterator // instead, which just calls the non-recursive iterator recursively. // This can be bad for performance, but not in any of the situations // we currently need. (ie. security is usually done on the server side, // but it's the client-to-server connection that needs a fast recursive // iterator, so it'll be fine.) if (findperm(key, UniPermGen::EXEC)) return UniConfGen::recursiveiterator(key); return NULL; } void UniSecureGen::gencallback(const UniConfKey &key, WvStringParm value) { if (findperm(key, UniPermGen::READ)) delta(key, value); } bool UniSecureGen::findperm(const UniConfKey &key, UniPermGen::Type type) { if (!drilldown(key)) return false; else return perms->getperm(key, cred, type); } bool UniSecureGen::drilldown(const UniConfKey &key) { UniConfKey check; UniConfKey left = key; while (!left.isempty()) { // check the exec perm if (!perms->getperm(check, cred, UniPermGen::EXEC)) return false; // move the first segment of left to check // note that when left is empty, we exit the loop before checking the // last segment. That's on purpose: the last segment is the 'file' // and we only need to check the 'directories' check.append(left.first()); left = left.removefirst(); } return true; } wvstreams-4.6.1/uniconf/uniunwrapgen.cc0000644000175000001440000000650011036722347017272 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A totally evil UniConfGen that "unwraps" a UniConf object by turning it * back into a UniConfGen. See uniunwrapgen.h. */ #include "uniconfroot.h" #include "uniunwrapgen.h" #include "wvlinkerhack.h" WV_LINK(UniUnwrapGen); UniUnwrapGen::UniUnwrapGen(const UniConf &inner) { refreshing = committing = false; setinner(inner); } UniUnwrapGen::~UniUnwrapGen() { UniConfRoot *root = xinner.rootobj(); if (root) root->mounts.del_callback(this); } void UniUnwrapGen::setinner(const UniConf &inner) { UniConfRoot *root = xinner.rootobj(); if (root) root->mounts.del_callback(this); xinner = inner; xfullkey = xinner.fullkey(); root = xinner.rootobj(); if (root) root->mounts.add_callback(this, wv::bind(&UniUnwrapGen::gencallback, this, _1, _2)); } UniConf UniUnwrapGen::_sub(const UniConfKey &key) { if (key.isempty()) return xinner; else return xinner[key]; } void UniUnwrapGen::commit() { if (!committing) { committing = true; xinner.commit(); committing = false; } } bool UniUnwrapGen::refresh() { if (!refreshing) { refreshing = true; bool ret = xinner.refresh(); refreshing = false; return ret; } return true; } void UniUnwrapGen::prefetch(const UniConfKey &key, bool recursive) { _sub(key).prefetch(recursive); } WvString UniUnwrapGen::get(const UniConfKey &key) { return _sub(key).getme(); } void UniUnwrapGen::set(const UniConfKey &key, WvStringParm value) { _sub(key).setme(value); } void UniUnwrapGen::setv(const UniConfPairList &pairs) { // Extremely evil. This pokes directly into UniMountGen, because we // don't want to expose setv to users. xinner.rootobj()->mounts.setv(pairs); } bool UniUnwrapGen::exists(const UniConfKey &key) { return _sub(key).exists(); } bool UniUnwrapGen::haschildren(const UniConfKey &key) { return _sub(key).haschildren(); } bool UniUnwrapGen::isok() { IUniConfGen *gen = xinner.whichmount(); return gen ? gen->isok() : false; } class UniUnwrapGen::Iter : public UniConfGen::Iter { UniConf::Iter i; public: Iter(const UniConf &cfg) : i(cfg) { } virtual ~Iter() { } /***** Overridden members *****/ virtual void rewind() { i.rewind(); } virtual bool next() { return i.next(); } virtual UniConfKey key() const { return i->key(); } virtual WvString value() const { return i->getme(); } }; class UniUnwrapGen::RecursiveIter : public UniConfGen::Iter { UniConf::RecursiveIter i; public: RecursiveIter(const UniConf &cfg) : i(cfg) { } virtual ~RecursiveIter() { } /***** Overridden members *****/ virtual void rewind() { i.rewind(); } virtual bool next() { return i.next(); } virtual UniConfKey key() const { return i->key(); } virtual WvString value() const { return i->getme(); } }; UniConfGen::Iter *UniUnwrapGen::iterator(const UniConfKey &key) { return new Iter(_sub(key)); } UniConfGen::Iter *UniUnwrapGen::recursiveiterator(const UniConfKey &key) { return new RecursiveIter(_sub(key)); } void UniUnwrapGen::gencallback(const UniConfKey &key, WvStringParm value) { UniConfKey subkey; if (xfullkey.suborsame(key, subkey)) delta(subkey, value); } wvstreams-4.6.1/uniconf/uniconf.cc0000644000175000001440000002055211122170511016176 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines a hierarchical registry abstraction. See uniconf.h. */ #include "uniconf.h" #include "uniconfroot.h" #include "uniconfgen.h" #include "wvstream.h" #include #include #include UniConf::UniConf(UniConfRoot *root, const UniConfKey &fullkey) : xroot(root), xfullkey(fullkey) { // nothing special } UniConf::UniConf() : xroot(NULL), xfullkey(UniConfKey::EMPTY) { // nothing special } UniConf::UniConf(const UniConf &other) : xroot(other.xroot), xfullkey(other.xfullkey) { // nothing special } UniConf::~UniConf() { // nothing special } UniConfKey UniConf::fullkey(const UniConfKey &k) const { return k.subkey(xfullkey); } bool UniConf::exists() const { return xroot->mounts.exists(xfullkey); } bool UniConf::haschildren() const { return xroot->mounts.haschildren(xfullkey); } void UniConf::prefetch(bool recursive) const { xroot->mounts.prefetch(xfullkey, recursive); } WvString UniConf::getme(WvStringParm defvalue) const { WvString value = xroot->mounts.get(xfullkey); if (value.isnull()) return defvalue; return value; } int UniConf::getmeint(int defvalue) const { return xroot->mounts.str2int(getme(), defvalue); } void UniConf::setme(WvStringParm value) const { xroot->mounts.set(xfullkey, value); } void UniConf::setmeint(int value) const { setme(WvString(value)); } void UniConf::move(const UniConf &dst) const { dst.remove(); copy(dst, true); remove(); } void UniConf::copy(const UniConf &dst, bool force) const { // do the main key first dst.setme(getme()); // now all the children RecursiveIter i(*this); for (i.rewind(); i.next(); ) { UniConf dst2 = dst[i->fullkey(*this)]; if (force || dst2.getme().isnull()) dst2.setme(i->getme()); } } bool UniConf::refresh() const { return xroot->mounts.refresh(); } void UniConf::commit() const { xroot->mounts.commit(); } IUniConfGen *UniConf::mount(WvStringParm moniker, bool refresh) const { return xroot->mounts.mount(xfullkey, moniker, refresh); } IUniConfGen *UniConf::mountgen(IUniConfGen *gen, bool refresh) const { return xroot->mounts.mountgen(xfullkey, gen, refresh); } void UniConf::unmount(IUniConfGen *gen, bool commit) const { return xroot->mounts.unmount(gen, commit); } bool UniConf::ismountpoint() const { return xroot->mounts.ismountpoint(xfullkey); } IUniConfGen *UniConf::whichmount(UniConfKey *mountpoint) const { return xroot->mounts.whichmount(xfullkey, mountpoint); } bool UniConf::isok() const { IUniConfGen *gen = whichmount(); return gen && gen->isok(); } void UniConf::add_callback(void *cookie, const UniConfCallback &callback, bool recurse) const { xroot->add_callback(cookie, xfullkey, callback, recurse); } void UniConf::del_callback(void *cookie, bool recurse) const { xroot->del_callback(cookie, xfullkey, recurse); } void UniConf::add_setbool(bool *flag, bool recurse) const { xroot->add_setbool(xfullkey, flag, recurse); } void UniConf::del_setbool(bool *flag, bool recurse) const { xroot->del_setbool(xfullkey, flag, recurse); } void UniConf::hold_delta() { xroot->mounts.hold_delta(); } void UniConf::unhold_delta() { xroot->mounts.unhold_delta(); } void UniConf::clear_delta() { xroot->mounts.clear_delta(); } void UniConf::flush_delta() { xroot->mounts.flush_delta(); } void UniConf::dump(WvStream &stream, bool everything) const { UniConf::RecursiveIter it(*this); for (it.rewind(); it.next(); ) { WvString value(it->getme()); if (everything || !!value) stream.print("%s = %s\n", it->fullkey(), value); } } /***** UniConf::Iter *****/ UniConf::Iter::Iter(const UniConf &_top) : IterBase(_top) { it = _top.rootobj()->mounts.iterator(top.fullkey()); if (!it) it = new UniConfGen::NullIter; } /***** UniConf::RecursiveIter *****/ UniConf::RecursiveIter::RecursiveIter(const UniConf &_top) : IterBase(_top) { it = _top.rootobj()->mounts.recursiveiterator(top.fullkey()); if (!it) it = new UniConfGen::NullIter; } /***** UniConf::XIter *****/ UniConf::XIter::XIter(const UniConf &_top, const UniConfKey &pattern) : IterBase(_top), pathead(pattern.first()), pattail(pattern.removefirst()), subit(NULL), it(NULL), recit(NULL) { if (! pathead.iswild()) { // optimization to collect as many consecutive non-wildcard // segments as possible in one go while (! pattail.isempty()) { UniConfKey patnext(pattail.first()); if (patnext.iswild()) break; pathead.append(patnext); pattail = pattail.removefirst(); } } } UniConf::XIter::~XIter() { cleanup(); } void UniConf::XIter::cleanup() { if (subit) { delete subit; subit = NULL; } if (it) { delete it; it = NULL; } if (recit) { delete recit; recit = NULL; } } void UniConf::XIter::rewind() { cleanup(); ready = false; if (pathead.isempty()) { current = top; ready = current.exists(); } else if (pathead == UniConfKey::RECURSIVE_ANY) { recit = new UniConf::RecursiveIter(top); recit->rewind(); if (UniConfKey::EMPTY.matches(pattail)) { // pattern includes self current = top; ready = current.exists(); } } else if (pathead == UniConfKey::ANY) { it = new UniConf::Iter(top); it->rewind(); } else { // non-wildcard segment current = top[pathead]; if (pattail.isempty()) { // don't bother recursing if there are no deeper wildcard // elements (works together with optimization in constructor) ready = current.exists(); } else { // more wildcards, setup recursion enter(current); } } } inline bool UniConf::XIter::qnext() { if (subit) // currently in a sub-iterator { bool found = subit->next(); if (found) { current = **subit; return true; } else { // end of this sub-iterator delete subit; subit = NULL; return false; } } else // no sub-iterator at all return false; } void UniConf::XIter::enter(const UniConf &child) { subit = new UniConf::XIter(child, pattail); subit->rewind(); } bool UniConf::XIter::next() { if (ready) { ready = false; return true; } while (!qnext()) { // UniConfKey::ANY if (it && it->next()) { /* Not needed for now since we don't match partial keys if (! pathead.matches(it->key())) break; */ enter(**it); continue; } // UniConfKey::RECURSIVE_ANY if (recit && recit->next()) { enter(**recit); continue; } // anything else or finished return false; } // if we get here, qnext() returned true return true; } /***** UniConf::SortedIterBase *****/ UniConf::SortedIterBase::SortedIterBase(const UniConf &root, UniConf::SortedIterBase::Comparator comparator) : IterBase(root), xcomparator(comparator), xkeys() { } UniConf::SortedIterBase::~SortedIterBase() { _purge(); } int UniConf::SortedIterBase::defcomparator(const UniConf &a, const UniConf &b) { return a.fullkey().compareto(b.fullkey()); } static UniConf::SortedIterBase::Comparator innercomparator = NULL; static bool wrapcomparator(const UniConf &a, const UniConf &b) { return innercomparator(a, b) < 0; } void UniConf::SortedIterBase::_purge() { count = xkeys.size(); xkeys.clear(); } void UniConf::SortedIterBase::_rewind() { index = 0; count = xkeys.size(); // This code is NOT reentrant because qsort makes it too hard innercomparator = xcomparator; std::sort(xkeys.begin(), xkeys.end(), wrapcomparator); } bool UniConf::SortedIterBase::next() { if (index >= count) return false; current = xkeys[index]; index += 1; return true; } wvstreams-4.6.1/uniconf/unicachegen.cc0000644000175000001440000000371711036722347017030 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that stores keys in memory. */ #include "uniconf.h" #include "unicachegen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(UniCacheGen); // if 'obj' is non-NULL and is a UniConfGen, wrap that; otherwise wrap the // given moniker. static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniCacheGen(wvcreate(s, _obj)); } static WvMoniker reg("cache", creator); /***** UniCacheGen *****/ UniCacheGen::UniCacheGen(IUniConfGen *_inner) : log("UniCache", WvLog::Debug1), inner(_inner) { if (inner) inner->add_callback(this, wv::bind(&UniCacheGen::deltacallback, this, _1, _2)); refreshed_once = false; } UniCacheGen::~UniCacheGen() { inner->del_callback(this); WVRELEASE(inner); } bool UniCacheGen::isok() { return inner->isok(); } bool UniCacheGen::refresh() { if (!refreshed_once) { bool ret = inner->refresh(); loadtree(); refreshed_once = true; return ret; } else return false; } void UniCacheGen::commit() { inner->commit(); } void UniCacheGen::loadtree(const UniConfKey &key) { UniConfGen::Iter *i = inner->recursiveiterator(key); if (!i) return; //assert(false); for (i->rewind(); i->next(); ) { WvString value(i->value()); //fprintf(stderr, "Key: '%s'\n", i->key().cstr()); //fprintf(stderr, " Val: '%s'\n", value.cstr()); if (!!value) UniTempGen::set(i->key(), value); } delete i; } void UniCacheGen::deltacallback(const UniConfKey &key, WvStringParm value) { UniTempGen::set(key, value); } void UniCacheGen::set(const UniConfKey &key, WvStringParm value) { inner->set(key, value); } WvString UniCacheGen::get(const UniConfKey &key) { //inner->get(key); inner->flush_buffers(); // update all pending notifications return UniTempGen::get(key); } wvstreams-4.6.1/uniconf/unibachelorgen.cc0000644000175000001440000000141111036722347017531 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * A UniConf generator that refuses to commit() or refresh(). This is * useful in blocking propogation of these messages upstream. */ #include "unibachelorgen.h" #include "wvmoniker.h" static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniBachelorGen(wvcreate(s, _obj)); } static WvMoniker moniker("bachelor", creator); UniBachelorGen::UniBachelorGen(IUniConfGen *inner) : UniFilterGen(inner) { } UniBachelorGen::UniBachelorGen(WvStringParm moniker) : UniFilterGen(NULL) { setinner(wvcreate(moniker)); } void UniBachelorGen::commit() { } bool UniBachelorGen::refresh() { return false; } wvstreams-4.6.1/uniconf/unifstreegen.cc0000644000175000001440000000406311036722347017250 0ustar wlachusers#include "uniconfgen.h" #include "unimountgen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #include "wvlog.h" #include "unifiltergen.h" class UniAutoMountGen : public UniFilterGen { WvString dir; UniMountGen *mount; IUniConfGen *treegen; WvLog log; public: UniAutoMountGen(WvStringParm _dir) : UniFilterGen(mount = new UniMountGen), dir(_dir), log(WvString("AutoMount '%s'", dir), WvLog::Info) { log("Starting.\n"); mount->mount("/", WvString("readonly:fs:%s", dir), true); treegen = mount->whichmount("/", NULL); } virtual ~UniAutoMountGen() { log("Stopping.\n"); } virtual bool keymap(const UniConfKey &key, UniConfKey &mapped_key) { automount(key); return UniFilterGen::keymap(key, mapped_key); } void automount(const UniConfKey &key) { IUniConfGen *parent = mount->whichmount(key, NULL); if (parent && parent != treegen && parent->haschildren("/")) return; // don't bother; already mounted a parent log("Automount for '%s'\n", key); for (int count = key.numsegments(); count >= 0; count--) { UniConfKey k(key.first(count)); if (mount->ismountpoint(k)) { log("Key '%s' already mounted.\n", k); return; // already mounted } WvString filename("%s/%s", dir, k); log("Filename is '%s'\n", filename); mount->mount(k, WvString("ini:%s", filename), true); log("Key '%s' newly mounted.\n", k); return; // newly mounted } // just plain not found log("Key '%s' not found.\n", key); } virtual Iter *recursiveiterator(const UniConfKey &key) { // don't try to optimize this like UniMountGen does, because we're // going to mount things *as* we iterate through them, not sooner. // Use the default UniConfGen implementation, which just recursively // calls iterator(). return UniConfGen::recursiveiterator(key); } }; WV_LINK(UniFsTreeGen); static IUniConfGen *creator(WvStringParm s, IObject *) { return new UniAutoMountGen(s); } WvMoniker UniFsTreeGenMoniker("fstree", creator); wvstreams-4.6.1/uniconf/unigenhack_s.cc0000644000175000001440000000164411036722347017212 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A file that, if you link to it, will ensure that you get the various * standard UniConf generators linked into your application. This is * important if you use static linking and construction via monikers, as * otherwise the linker will try to be smart and leave out the not- * directly-referenced files. * * See also unigenhack.cc. */ #include "wvlinkerhack.h" WV_LINK(UniGenHack); WV_LINK_TO(UniIniGen); WV_LINK_TO(UniListGen); WV_LINK_TO(UniDefGen); WV_LINK_TO(UniClientGen); WV_LINK_TO(UniAutoGen); WV_LINK_TO(UniCacheGen); WV_LINK_TO(UniNullGen); WV_LINK_TO(UniPermGen); WV_LINK_TO(UniReadOnlyGen); WV_LINK_TO(UniReplicateGen); WV_LINK_TO(UniRetryGen); WV_LINK_TO(UniSecureGen); WV_LINK_TO(UniSubtreeGen); WV_LINK_TO(UniUnwrapGen); #ifdef _WIN32 WV_LINK_TO(UniPStoreGen); WV_LINK_TO(UniRegistryGen); #endif wvstreams-4.6.1/uniconf/unigenhack.cc0000644000175000001440000000066311036722347016670 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A placeholder for applications that want to link to UniConf moniker * objects, but are linking dynamically to wvstreams instead of statically * (in which case, you *always* get all the monikers anyway). * * See unigenhack_s.cc for what happens when you link statically. */ #include "wvlinkerhack.h" WV_LINK(UniGenHack); wvstreams-4.6.1/uniconf/unipermgen.cc0000644000175000001440000001030511036722347016717 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * UniPermGen is a UniConfGen for holding Unix-style permissions. See * unipermgen.h. */ #include "unipermgen.h" #include "unidefgen.h" #include "wvmoniker.h" #include "wvstringlist.h" #include "wvtclstring.h" #include "wvstream.h" #include "wvlinkerhack.h" WV_LINK(UniPermGen); UniPermGen::UniPermGen(IUniConfGen *_gen) : UniFilterGen(_gen) { } UniPermGen::UniPermGen(WvStringParm moniker) : UniFilterGen(NULL) { IUniConfGen *gen = wvcreate(moniker); assert(gen && "Moniker doesn't get us a generator!"); setinner(gen); } void UniPermGen::setowner(const UniConfKey &path, WvStringParm owner) { inner()->set(WvString("%s/owner", path), owner); } WvString UniPermGen::getowner(const UniConfKey &path) { WvString owner = inner()->get(WvString("%s/owner", path)); if (!owner && !path.isempty()) owner = getowner(path.removelast()); return owner; } void UniPermGen::setgroup(const UniConfKey &path, WvStringParm group) { inner()->set(WvString("%s/group", path), group); } WvString UniPermGen::getgroup(const UniConfKey &path) { WvString group = inner()->get(WvString("%s/group", path)); if (!group && !path.isempty()) group = getgroup(path.removelast()); return group; } void UniPermGen::setperm(const UniConfKey &path, Level level, Type type, bool val) { inner()->set(WvString("%s/%s-%s", path, level2str(level), type2str(type)), val); } bool UniPermGen::getperm(const UniConfKey &path, const Credentials &cred, Type type) { WvString owner = getowner(path); WvString group = getgroup(path); Level level; if (!!owner && cred.user == owner) level = USER; else if (!!group && cred.groups[group]) level = GROUP; else level = WORLD; bool perm = getoneperm(path, level, type); // wverr->print("getperm(%s/%s, %s/%s, %s,%s-%s) = %s\n", // cred.user, cred.groups.count(), owner, group, // path, level2str(level), type2str(type), perm); return perm; } /// retrieve an individual permission. If there's no explicit permission /// of that type set for that object, proceed up the tree so that children /// can inherit permissions from their parents. bool UniPermGen::getoneperm(const UniConfKey &path, Level level, Type type) { int val = str2int(inner()->get(WvString("%s/%s-%s", path, level2str(level), type2str(type))), -1); if (val == -1) { if (path.isempty()) { // nothing found: use default switch (type) { case READ: return false; case WRITE: return false; case EXEC: return false; } } else return getoneperm(path.removelast(), level, type); } return val; } void UniPermGen::chmod(const UniConfKey &path, unsigned int user, unsigned int group, unsigned int world) { static const int r = 4; static const int w = 2; static const int x = 1; setperm(path, USER, READ, (user & r)); setperm(path, USER, WRITE, (user & w)); setperm(path, USER, EXEC, (user & x)); setperm(path, GROUP, READ, (group & r)); setperm(path, GROUP, WRITE, (group & w)); setperm(path, GROUP, EXEC, (group & x)); setperm(path, WORLD, READ, (world & r)); setperm(path, WORLD, WRITE, (world & w)); setperm(path, WORLD, EXEC, (world & x)); } void UniPermGen::chmod(const UniConfKey &path, unsigned int mode) { unsigned int user = (mode & 0700) >> 6; unsigned int group = (mode & 0070) >> 3; unsigned int world = (mode & 0007); chmod(path, user, group, world); } WvString UniPermGen::level2str(Level level) { switch (level) { case USER: return "user"; case GROUP: return "group"; case WORLD: return "world"; } assert(false && "Something in the Level enum wasn't covered"); return WvString::null; } WvString UniPermGen::type2str(Type type) { switch (type) { case READ: return "read"; case WRITE: return "write"; case EXEC: return "exec"; } assert(false && "Something in the Type enum wasn't covered"); return WvString::null; } wvstreams-4.6.1/uniconf/uniclientgen.cc0000644000175000001440000002477711036722347017254 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UniClientGen is a UniConfGen for retrieving data from the * UniConfDaemon. */ #include "uniclientgen.h" #include "unilistiter.h" #include "wvaddr.h" #include "wvfile.h" #include "wvlinkerhack.h" #include "wvmoniker.h" #include "wvresolver.h" #include "wvsslstream.h" #include "wvstrutils.h" #include "wvstringmask.h" #include "wvtclstring.h" #include "wvtcp.h" WV_LINK(UniClientGen); #ifndef _WIN32 #include "wvunixsocket.h" static IUniConfGen *unixcreator(WvStringParm s, IObject *) { WvConstInPlaceBuf buf(s, s.len()); WvString dst(wvtcl_getword(buf)); if (!dst) dst = ""; return new UniClientGen(new WvUnixConn(dst), dst); } static WvMoniker unixreg("unix", unixcreator); #endif static IUniConfGen *tcpcreator(WvStringParm _s, IObject *) { WvConstInPlaceBuf buf(_s, _s.len()); WvString dst(wvtcl_getword(buf)); if (!dst) dst = ""; WvString s = dst; char *cptr = s.edit(); if (!strchr(cptr, ':')) // no default port s.append(":%s", DEFAULT_UNICONF_DAEMON_TCP_PORT); return new UniClientGen(new WvTCPConn(s), dst); } static IUniConfGen *sslcreator(WvStringParm _s, IObject *) { WvConstInPlaceBuf buf(_s, _s.len()); WvString dst(wvtcl_getword(buf)); if (!dst) dst = ""; WvString s = dst; char *cptr = s.edit(); if (!strchr(cptr, ':')) // no default port s.append(":%s", DEFAULT_UNICONF_DAEMON_SSL_PORT); return new UniClientGen(new WvSSLStream(new WvTCPConn(s), NULL), dst); } static IUniConfGen *wvstreamcreator(WvStringParm s, IObject *_obj) { return new UniClientGen(wvcreate(s, _obj)); } #ifdef WITH_SLP #include "wvslp.h" // FIXME: Only gets the first static IUniConfGen *slpcreator(WvStringParm s, IObject *) { WvStringList serverlist; if (slp_get_servs("uniconf.niti", serverlist)) { WvString server = serverlist.popstr(); printf("Creating connection to: %s\n", server.cstr()); return new UniClientGen(new WvTCPConn(server), s); } return NULL; } static WvMoniker slpreg("slp", slpcreator); #endif static WvMoniker tcpreg("tcp", tcpcreator); static WvMoniker sslreg("ssl", sslcreator); static WvMoniker wvstreamreg1("wvstream", wvstreamcreator); static WvMoniker wvstreamreg2("wv", wvstreamcreator); /***** UniClientGen *****/ UniClientGen::UniClientGen(IWvStream *stream, WvStringParm dst) : log(WvString("UniClientGen to %s", dst.isnull() && stream->src() ? *stream->src() : WvString(dst))), timeout(60*1000), version(0) { cmdinprogress = cmdsuccess = false; result_list = NULL; conn = new UniClientConn(stream, dst); conn->setcallback(wv::bind(&UniClientGen::conncallback, this)); WvIStreamList::globallist.append(conn, false, "uniclientconn-via-gen"); } UniClientGen::~UniClientGen() { if (isok()) conn->writecmd(UniClientConn::REQ_QUIT, ""); WvIStreamList::globallist.unlink(conn); WVRELEASE(conn); } time_t UniClientGen::set_timeout(time_t _timeout) { if (_timeout < 1000) timeout = 1000; else timeout = _timeout; return timeout; } bool UniClientGen::isok() { return (conn && conn->isok()); } bool UniClientGen::refresh() { conn->writecmd(UniClientConn::REQ_REFRESH); return do_select(); } void UniClientGen::flush_buffers() { // this ensures that all keys pending notifications are dealt with while (conn->isok() && conn->isreadable()) conn->callback(); } void UniClientGen::commit() { conn->writecmd(UniClientConn::REQ_COMMIT); do_select(); } WvString UniClientGen::get(const UniConfKey &key) { WvString value; conn->writecmd(UniClientConn::REQ_GET, wvtcl_escape(key)); if (do_select()) { if (result_key == key) value = result; // else // seterror("Error: server sent wrong key pair."); } return value; } void UniClientGen::set(const UniConfKey &key, WvStringParm newvalue) { //set_queue.append(new WvString(key), true); hold_delta(); if (newvalue.isnull()) conn->writecmd(UniClientConn::REQ_REMOVE, wvtcl_escape(key)); else conn->writecmd(UniClientConn::REQ_SET, spacecat(wvtcl_escape(key), wvtcl_escape(newvalue), ' ')); flush_buffers(); unhold_delta(); } void UniClientGen::setv(const UniConfPairList &pairs) { hold_delta(); UniConfPairList::Iter i(pairs); if (version >= 19) { // Much like how VAL works, SETV continues sending key-value pairs // until it sends a terminating SETV, which has no arguments. for (i.rewind(); i.next(); ) { conn->writecmd(UniClientConn::REQ_SETV, spacecat(wvtcl_escape(i->key()), wvtcl_escape(i->value()), ' ')); } conn->writecmd(UniClientConn::REQ_SETV); } else { for (i.rewind(); i.next(); ) { set(i->key(), i->value()); } } unhold_delta(); } bool UniClientGen::haschildren(const UniConfKey &key) { conn->writecmd(UniClientConn::REQ_HASCHILDREN, wvtcl_escape(key)); if (do_select()) { if (result_key == key && result == "TRUE") return true; } return false; } UniClientGen::Iter *UniClientGen::do_iterator(const UniConfKey &key, bool recursive) { assert(!result_list); result_list = new UniListIter(this); conn->writecmd(UniClientConn::REQ_SUBTREE, WvString("%s %s", wvtcl_escape(key), WvString(recursive))); if (do_select()) { ListIter *it = result_list; result_list = NULL; return it; } else { delete result_list; result_list = NULL; return NULL; } } UniClientGen::Iter *UniClientGen::iterator(const UniConfKey &key) { return do_iterator(key, false); } UniClientGen::Iter *UniClientGen::recursiveiterator(const UniConfKey &key) { return do_iterator(key, true); } void UniClientGen::conncallback() { UniClientConn::Command command = conn->readcmd(); static const WvStringMask nasty_space(' '); switch (command) { case UniClientConn::NONE: // do nothing break; case UniClientConn::REPLY_OK: cmdsuccess = true; cmdinprogress = false; break; case UniClientConn::REPLY_FAIL: result_key = WvString::null; cmdsuccess = false; cmdinprogress = false; break; case UniClientConn::REPLY_CHILD: { WvString key(wvtcl_getword(conn->payloadbuf, nasty_space)); WvString value(wvtcl_getword(conn->payloadbuf, nasty_space)); if (!key.isnull() && !value.isnull()) { result_key = key; result = value; cmdsuccess = true; } cmdinprogress = false; break; } case UniClientConn::REPLY_ONEVAL: { WvString key(wvtcl_getword(conn->payloadbuf, nasty_space)); WvString value(wvtcl_getword(conn->payloadbuf, nasty_space)); if (!key.isnull() && !value.isnull()) { result_key = key; result = value; cmdsuccess = true; } cmdinprogress = false; break; } case UniClientConn::PART_VALUE: { WvString key(wvtcl_getword(conn->payloadbuf, nasty_space)); WvString value(wvtcl_getword(conn->payloadbuf, nasty_space)); if (!key.isnull() && !value.isnull()) { if (result_list) result_list->add(key, value); } break; } case UniClientConn::EVENT_HELLO: { WvStringList greeting; wvtcl_decode(greeting, conn->payloadbuf.getstr(), nasty_space); WvString server(greeting.popstr()); WvString version_string(greeting.popstr()); if (server.isnull() || strncmp(server, "UniConf", 7)) { // wrong type of server! log(WvLog::Error, "Connected to a non-UniConf server!\n"); cmdinprogress = false; cmdsuccess = false; conn->close(); } else { version = 0; sscanf(version_string, "%d", &version); log(WvLog::Debug3, "UniConf version %s.\n", version); } break; } case UniClientConn::EVENT_NOTICE: { WvString key(wvtcl_getword(conn->payloadbuf, nasty_space)); WvString value(wvtcl_getword(conn->payloadbuf, nasty_space)); delta(key, value); } default: // discard unrecognized commands break; } } // FIXME: horribly horribly evil!! bool UniClientGen::do_select() { wvstime_sync(); hold_delta(); cmdinprogress = true; cmdsuccess = false; time_t remaining = timeout; const time_t clock_error = 10*1000; WvTime timeout_at = msecadd(wvstime(), timeout); while (conn->isok() && cmdinprogress) { // We would really like to run the "real" wvstreams globallist // select loop here, but we can't because we may already be inside // someone else's callback or something. So we'll wait on *only* this // connection. // // We could do this using alarm()s, but because of very strage behaviour // due to inherit_request in post_select when calling the long WvStream::select() // prototype as we do here we have to do the remaining stuff outselves time_t last_remaining = remaining; bool result = conn->select(remaining, true, false); remaining = msecdiff(timeout_at, wvstime()); if (result) conn->callback(); else if (remaining <= 0 && remaining > -clock_error) { log(WvLog::Warning, "Command timeout; connection closed.\n"); cmdinprogress = false; cmdsuccess = false; conn->close(); } if (result || remaining <= -clock_error || remaining >= last_remaining + clock_error) { if (!result) log(WvLog::Debug, "Clock appears to have jumped; resetting" " connection remaining.\n"); remaining = timeout; timeout_at = msecadd(wvstime(), timeout); } } // if (!cmdsuccess) // seterror("Error: server timed out on response."); unhold_delta(); return cmdsuccess; } wvstreams-4.6.1/uniconf/unireplicategen.cc0000644000175000001440000001640211036722347017730 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * A UniConf generator that replicates multiple generators, prioritized * by order. */ #include "uniconf.h" #include "unireplicategen.h" #include "wvmoniker.h" #include "wvstringlist.h" #include "wvtclstring.h" #include "wvlinkerhack.h" WV_LINK(UniReplicateGen); #if 0 #define DPRINTF(format, args...) fprintf(stderr, format ,##args); #else #define DPRINTF if (0) printf #endif static IUniConfGen *creator(WvStringParm s, IObject *_obj) { IUniConfGenList gens; DPRINTF("encoded_monikers = %s\n", s.cstr()); WvStringList monikers; wvtcl_decode(monikers, s); DPRINTF("monikers = %s\n", monikers.join(",").cstr()); WvStringList::Iter i(monikers); for (i.rewind(); i.next(); ) { if (_obj) _obj->addRef(); IUniConfGen *gen = wvcreate(*i, _obj); if (gen) gens.append(gen, false); } if (_obj) _obj->release(); return new UniReplicateGen(gens); } static WvMoniker reg("replicate", creator); /***** UniReplicateGen *****/ UniReplicateGen::UniReplicateGen() : processing_callback(false) { } UniReplicateGen::UniReplicateGen(const IUniConfGenList &_gens, bool auto_free) : processing_callback(false) { IUniConfGenList::Iter i(_gens); for (i.rewind(); i.next(); ) { Gen *gen = new Gen(i.ptr(), auto_free); if (gen) { gens.append(gen, true); gen->gen->add_callback(this, wv::bind(&UniReplicateGen::deltacallback, this, gen, _1, _2)); } } replicate(); } UniReplicateGen::~UniReplicateGen() { GenList::Iter i(gens); for (i.rewind(); i.next(); ) i->gen->del_callback(this); } void UniReplicateGen::prepend(IUniConfGen *_gen, bool auto_free) { Gen *gen = new Gen(_gen, auto_free); if (gen) { gens.prepend(gen, true); gen->gen->add_callback(this, wv::bind(&UniReplicateGen::deltacallback, this, gen, _1, _2)); replicate(); } } void UniReplicateGen::append(IUniConfGen *_gen, bool auto_free) { Gen *gen = new Gen(_gen, auto_free); if (gen) { gens.append(gen, true); gen->gen->add_callback(this, wv::bind(&UniReplicateGen::deltacallback, this, gen, _1, _2)); replicate(); } } bool UniReplicateGen::isok() { return first_ok() != NULL; } bool UniReplicateGen::refresh() { bool result = true; replicate_if_any_have_become_ok(); GenList::Iter i(gens); for (i.rewind(); i.next(); ) { if (!i->gen->refresh()) result = false; } return result; } void UniReplicateGen::commit() { replicate_if_any_have_become_ok(); GenList::Iter i(gens); for (i.rewind(); i.next(); ) { i->gen->commit(); } } void UniReplicateGen::deltacallback(Gen *src_gen, const UniConfKey &key, WvStringParm value) { DPRINTF("UniReplicateGen::deltacallback(%s, %s)\n", key.printable().cstr(), value.cstr()); if (!processing_callback) { DPRINTF("UniReplicateGen::deltacallback(): !processing_callback\n"); processing_callback = true; GenList::Iter j(gens); for (j.rewind(); j.next(); ) { if (!j->isok()) continue; if (j.ptr() != src_gen) { DPRINTF("UniReplicateGen::deltacallback: %p->set(%s, %s)\n", j.ptr(), key.printable().cstr(), value.cstr()); j->gen->set(key, value); } } delta(key, value); processing_callback = false; } else { DPRINTF("UniReplicateGen::deltacallback(): processing_callback\n"); } } void UniReplicateGen::set(const UniConfKey &key, WvStringParm value) { DPRINTF("UniReplicateGen::set(%s, %s)\n", key.printable().cstr(), value.cstr()); replicate_if_any_have_become_ok(); Gen *first = first_ok(); if (first) first->gen->set(key, value); else DPRINTF("UniReplicateGen::set: first == NULL\n"); } void UniReplicateGen::setv(const UniConfPairList &pairs) { DPRINTF("UniReplicateGen::setv\n"); replicate_if_any_have_become_ok(); Gen *first = first_ok(); if (first) first->gen->setv(pairs); else DPRINTF("UniReplicateGen::setv: first == NULL\n"); } WvString UniReplicateGen::get(const UniConfKey &key) { for (;;) { replicate_if_any_have_become_ok(); Gen *first = first_ok(); if (first) { WvString result = first->gen->get(key); // It's possible that first has become !isok(); we must // take care of this case carefully if (!result && !first->isok()) { Gen *new_first = first_ok(); if (new_first == first) return result; first = new_first; } else return result; } else return WvString::null; } } UniConfGen::Iter *UniReplicateGen::iterator(const UniConfKey &key) { replicate_if_any_have_become_ok(); Gen *first = first_ok(); if (first) return first->gen->iterator(key); else return NULL; } UniReplicateGen::Gen *UniReplicateGen::first_ok() const { GenList::Iter j(gens); for (j.rewind(); j.next(); ) { if (j->isok()) return j.ptr(); } return NULL; } void UniReplicateGen::replicate(const UniConfKey &key) { DPRINTF("UniReplicateGen::replicate(%s)\n", key.printable().cstr()); hold_delta(); Gen *first = first_ok(); GenList::Iter j(gens); for (j.rewind(); j.next(); ) { DPRINTF("UniReplicateGen::replicate: %p\n", j.ptr()); if (!j->isok()) { DPRINTF("UniReplicateGen::replicate: !isok()\n"); continue; } UniConfGen::Iter *i = j->gen->recursiveiterator(key); if (!i) { DPRINTF("UniReplicateGen::replicate: no iterator\n"); continue; } for (i->rewind(); i->next(); ) { DPRINTF("UniReplicateGen::replicate: key=%s, value=%s\n", i->key().printable().cstr(), i->value().cstr()); if (j.ptr() == first) { DPRINTF("UniReplicateGen::replicate: deltacallback()\n"); deltacallback(first, i->key(), i->value()); } else { if (!first->gen->exists(i->key())) { DPRINTF("UniReplicateGen::replicate: !exists()\n"); first->gen->set(i->key(), i->value()); } else { DPRINTF("UniReplicateGen::replicate: exists()\n"); } } } delete i; } unhold_delta(); DPRINTF("UniReplicateGen::replicate: done\n"); } void UniReplicateGen::replicate_if_any_have_become_ok() { bool should_replicate = false; GenList::Iter j(gens); for (j.rewind(); j.next(); ) { if (!j->was_ok && j->gen->isok()) { j->was_ok = true; should_replicate = true; } } if (should_replicate) { DPRINTF("UniReplicateGen::replicate_if_any_have_become_ok: replicating\n"); replicate(); } } wvstreams-4.6.1/uniconf/uniclientconn.cc0000644000175000001440000001137611036722347017427 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Manages a connection between the UniConf client and daemon. */ #include "uniclientconn.h" #include "wvaddr.h" #include "wvtclstring.h" #include "strutils.h" /***** UniClientConn *****/ /* This table is _very_ important!!! * * With UniConf, we promise to never remove or modify the behaviour of * any of the commands listed here. If you want to modify anything, * you'd better just add a new command instead. We keep track of the * version of the UniConf protocol by the number of commands supported * by the server. * * @see UniClientConn::Commands */ const UniClientConn::CommandInfo UniClientConn::cmdinfos[ UniClientConn::NUM_COMMANDS] = { // requests { "noop", "noop: verify that the connection is active" }, { "get", "get : get the value of a key" }, { "set", "set : sets the value of a key" }, { "setv", "setv ...: set multiple key-value pairs" }, { "del", "del : deletes the key" }, { "subt", "subt : enumerates the children of a key" }, { "hchild", "hchild : returns whether a key has children" }, { "commit", "commit: commits changes to disk" }, { "refresh", "refresh: refresh contents from disk" }, { "quit", "quit: kills the session nicely" }, { "help", "help: returns this help text" }, // command completion replies { "OK", "OK : reply on command success" }, { "FAIL", "FAIL : reply on command failure" }, { "CHILD", "CHILD TRUE / FALSE: key has children or not" }, { "ONEVAL", "ONEVAL : reply to a get" }, // partial replies { "VAL", "VAL : intermediate reply value of a key" }, { "TEXT", "TEXT : intermediate reply of a text message" }, // events { "HELLO", "HELLO : sent by server on connection" }, { "NOTICE", "NOTICE : forget key and its children" }, }; UniClientConn::UniClientConn(IWvStream *_s, WvStringParm dst) : WvStreamClone(_s), log(WvString("UniConf to %s", dst.isnull() && _s->src() ? *_s->src() : WvString(dst)), WvLog::Debug5), closed(false), version(-1), payloadbuf("") { log("Opened\n"); } UniClientConn::~UniClientConn() { close(); } void UniClientConn::close() { if (!closed) { closed = true; WvStreamClone::close(); log("Closed\n"); } } WvString UniClientConn::readmsg() { WvString word; while ((word = wvtcl_getword(msgbuf, WVTCL_NASTY_NEWLINES, false)).isnull()) { // use lots of readahead to prevent unnecessary runs through select() // during heavy data transfers. char *line = getline(0, '\n', 20480); if (line) { msgbuf.putstr(line); msgbuf.put('\n'); } else { if (!WvStreamClone::isok()) { // possibly left some incomplete command behind msgbuf.zap(); } return WvString::null; } } if (!!word && 0) log("Read: %s\n", word); return word; } void UniClientConn::writemsg(WvStringParm msg) { write(msg); write("\n"); // log("Wrote: %s\n", msg); } UniClientConn::Command UniClientConn::readcmd() { WvString buf; return readcmd(buf); } UniClientConn::Command UniClientConn::readcmd(WvString &command) { WvString msg(readmsg()); if (msg.isnull()) return NONE; // extract command, leaving the remainder in payloadbuf payloadbuf.reset(msg); command = readarg(); if (command.isnull()) return NONE; for (int i = 0; i < NUM_COMMANDS; ++i) if (strcasecmp(cmdinfos[i].name, command.cstr()) == 0) return Command(i); return INVALID; } WvString UniClientConn::readarg() { return wvtcl_getword(payloadbuf); } void UniClientConn::writecmd(UniClientConn::Command cmd, WvStringParm msg) { if (msg) write(WvString("%s %s\n", cmdinfos[cmd].name, msg)); else write(WvString("%s\n", cmdinfos[cmd].name)); } void UniClientConn::writeok(WvStringParm payload) { writecmd(REPLY_OK, payload); } void UniClientConn::writefail(WvStringParm payload) { writecmd(REPLY_FAIL, payload); } void UniClientConn::writevalue(const UniConfKey &key, WvStringParm value) { if (value == WvString::null) writecmd(PART_VALUE, wvtcl_escape(key)); else writecmd(PART_VALUE, spacecat(wvtcl_escape(key), wvtcl_escape(value))); } void UniClientConn::writeonevalue(const UniConfKey &key, WvStringParm value) { writecmd(REPLY_ONEVAL, spacecat(wvtcl_escape(key), wvtcl_escape(value))); } void UniClientConn::writetext(WvStringParm text) { writecmd(PART_TEXT, wvtcl_escape(text)); } wvstreams-4.6.1/uniconf/gremlin/0000755000175000001440000000000011036722347015675 5ustar wlachuserswvstreams-4.6.1/uniconf/gremlin/unigremlin.h0000644000175000001440000000517611036722347020230 0ustar wlachusers#ifndef __UNIGREMLIN_H #define __UNIGREMLIN_H #include "wvstring.h" #include "wvhashtable.h" #include "uniconfroot.h" #include "uniconfkey.h" #define MAX_DEPTH 5 #define TYPE_STRING 0 #define TYPE_IP 1 #define TYPE_IP_NETWORK 2 #define TYPE_HOSTNAME 3 #define TYPE_BOOL 4 #define TYPE_INT 5 #define TYPE_FLOAT 6 #define NUM_TYPES 7 // Options for data. enum Data { Create = (1 << 0), // 00000001 Delete = (1 << 1), // 00000010 Modify = (1 << 2), // 00000100 Valid = (1 << 3), // 00001000 Invalid = (1 << 4), // 00010000 Correct = (1 << 5), // 00100000 Incorrect = (1 << 6) // 01000000 }; struct Victim { int i; // index int type; // type of data WvString value; // value of data Victim(int _i, int _type, WvStringParm _value) : i(_i), type(_type), value(_value) { } }; // correct data harvested off of the existing UniConf struct Harvested { int i; WvString value; Harvested(int _i, WvStringParm _value) : i(_i), value(_value) { } }; DeclareWvDict(Victim, int, i); DeclareWvDict(Harvested, int, i); class UniConfGremlin { public: // runlevels are defined in curr_runlevel() UniConfGremlin(WvString moniker, const UniConfKey key); ~UniConfGremlin(); // FIXME: use_valid_data does not work when set to true yet void start(unsigned int seed = 0, int flags = Create|Modify|Valid|Invalid|Correct|Incorrect, int _ratio_create = 60, int _ratio_valid = 90, int _ratio_correct = 70); void test(); WvString status(); private: // creates a list of the keys and expected values in the UniConf subtree void find_victims(); void change_value(bool use_valid_data = false); void add_value(); // begin randomly changing key values, using only valid data if // use_valid_data is true void start_trouble(int howmany); // returns what it thinks is the expected data for this element int inspect(WvString element); bool is_bool(char *elem); // returns "" if type was not a known string type WvString rand_str(int type); WvString type_value(int type); WvString curr_runlevel(); // commits for n iterations void spin_commit(int n); int randInt(int max, int min = 0); UniConfRoot root; UniConf cfg; VictimDict victims; HarvestedDict *harvested[NUM_TYPES]; int num_victims, num_harvested[NUM_TYPES], ratio_create, ratio_valid, ratio_correct; char flags; WvString last_change; bool modify_valid, modify_invalid, add_values, delete_values; }; #endif wvstreams-4.6.1/uniconf/gremlin/Makefile0000644000175000001440000000021311036722347017331 0ustar wlachusersinclude ${TOPDIR}/wvrules.mk XPATH=${TOPDIR}/src/wvstreams/include all: rungremlin LIBS=-lstdc++ rungremlin: $(LIBUNICONF) unigremlin.o wvstreams-4.6.1/uniconf/gremlin/unigremlin.cc0000644000175000001440000003240011036722347020354 0ustar wlachusers#include #include #include #include #include "unigremlin.h" UniConfGremlin::UniConfGremlin(WvString moniker, const UniConfKey _key) : root(moniker), victims(500), num_victims(0) { cfg = UniConf(root[_key]); for (int i = 0; i < NUM_TYPES; i++) harvested[i] = new HarvestedDict(500); } UniConfGremlin::~UniConfGremlin() { for (int i = 0; i < NUM_TYPES; i++) delete harvested[i]; } /* start(unsigned int seed) * Starts the gremlin out using the specified seed to seed the random numbers, * or if no seed is specified, uses the current time to seed them. */ void UniConfGremlin::start(unsigned int seed, int _flags, int _ratio_create, int _ratio_valid, int _ratio_correct) { ratio_create = _ratio_create; ratio_valid = _ratio_valid; ratio_correct = _ratio_correct; //harvest out bit flags if (_flags & Create) { modify_valid = _flags & Valid; modify_invalid = _flags & Invalid; } add_values = _flags & Create; delete_values = _flags & Delete; if (seed == 0) seed = time(0); srand(seed); printf("Using seed %i\n", seed); //perhaps save this to a file? // printf("Finding Victims\n"); find_victims(); // printf("Starting Trouble\n"); start_trouble(1000); } /* find_victims(UniConfKey _key) * Iterates through each element in the tree and adds a new victim to the list * victims with the element's key and a guess at what type of data should be * stored there. */ void UniConfGremlin::find_victims() { UniConf::RecursiveIter i(cfg); Victim *victim; for (i.rewind(); i.next(); ) { if (i().getme() != "") { victim = new Victim(num_victims++, inspect(i().getme()), i().fullkey(cfg.fullkey())); victims.add(victim, true); } } } /* inspect(WvString element) * Inspects the string element in an attempt to guess what type of data should * be stored there. Returns an integer representing what type the gremlin * thinks it is, and stores the value as an example of that type. */ int UniConfGremlin::inspect(WvString element) { char *elem = element.edit(); Harvested * harvest; // rough expression for an ip network char *ipNetExp = "[0-9].*\\.[0-9].*\\.[0-9].*\\.[0-9].*"; if (is_bool(elem)) { harvest = new Harvested(num_harvested[TYPE_BOOL]++, element); harvested[TYPE_BOOL]->add(harvest, true); return TYPE_BOOL; } if (isdigit(elem[0])) { regex_t preg1; regmatch_t pmatch1[1]; regcomp(&preg1, ipNetExp, REG_EXTENDED | REG_NOSUB); if (!regexec(&preg1, elem, 1, pmatch1, 0)) { if (elem[element.len() - 2] == '/' || elem[element.len() - 3] == '/') { harvest = new Harvested(num_harvested[TYPE_IP_NETWORK]++, element); harvested[TYPE_IP_NETWORK]->add(harvest, true); return TYPE_IP_NETWORK; } else { harvest = new Harvested(num_harvested[TYPE_IP]++, element); harvested[TYPE_IP]->add(harvest, true); return TYPE_IP; } } } // now we just brute force the rest of the string for (size_t i = 1; i < element.len(); i++) { if (!isdigit(elem[i])) // either string or hostvalue, return string for now { harvest = new Harvested(num_harvested[TYPE_STRING]++, element); harvested[TYPE_STRING]->add(harvest, true); return TYPE_STRING; } } // either int or float, return int for now return TYPE_INT; } /* is_bool(char *elem) * Returns true if the string stored in elem represents a boolean valuation */ bool UniConfGremlin::is_bool(char *elem) { const char *strs[] = { "true", "yes", "on", "enabled", "1", "false", "no", "off", "disabled", "0" }; for (size_t i = 0; i < sizeof(strs) / sizeof(const char*); ++i) if (strcasecmp(elem, strs[i]) == 0) return true; return false; } /* change_value(bool use_valid_data) * Changes a random value from the list of victims, the victim list includes * previously deleted victims as well, so this could potentially add previously * deleted values back in as well. Changes it with new random data. */ void UniConfGremlin::change_value(bool use_valid_data) { if (num_victims > 0) { int r = num_victims + 1; while (r >= num_victims) { r = randInt(num_victims); } if (victims[r]->value == "") printf("Fuck, why are we changing the empty value?\n"); last_change = WvString("Changed %s to be the value", victims[r]->value); WvString new_value; if (use_valid_data) { if (victims[r]->type == TYPE_INT) { int new_value = rand(); cfg.xsetint(victims[r]->value, new_value); last_change = WvString("%s %s\n", last_change, new_value); } else { WvString new_value = rand_str(victims[r]->type); cfg.xset(victims[r]->value, new_value); last_change = WvString("%s %s\n", last_change, new_value); } } else { int s = randInt(4); if (s) { WvString new_value = rand_str(victims[r]->type); int t = randInt(NUM_TYPES); cfg.xset(victims[r]->value, rand_str(t)); last_change = WvString("%s %s\n", last_change, new_value); } else { int new_value = rand(); cfg.xsetint(victims[r]->value, new_value); last_change = WvString("%s %s\n", last_change, new_value); } } cfg[victims[r]->value].commit(); } } /* add_value() * Adds a random value into the UniConf also randomly selecting the type and * contents. */ void UniConfGremlin::add_value() { int depth = randInt(MAX_DEPTH); WvString key_value = "", elem; // generate a key for (int i = 0; i < depth || !key_value; i++) { elem = ""; int length = randInt(8); for (int j = 0; j < length; j++) { // generate a valid written character (lower case right now) int num = randInt(122, 97); char c[2]; c[0] = (char)num; c[1] = '\0'; elem = WvString("%s%s", elem, c); } if (i > 0) key_value = WvString("%s/%s", key_value, elem); } key_value = WvString("/%s", key_value); last_change = WvString("Added the key %s with the new value", key_value); // generate a value int num = randInt(1); Victim *victim; if (num) // generate number { int new_value = rand(); cfg.xsetint(key_value, new_value); victim = new Victim(num_victims, TYPE_INT, key_value); last_change = WvString("%s %s\n", last_change, new_value); } else // generate string { int type = randInt(5 + TYPE_STRING, TYPE_STRING); WvString new_value = rand_str(type); cfg.xset(key_value, new_value); victim = new Victim(num_victims, TYPE_STRING, key_value); last_change = WvString("%s %s\n", last_change, new_value); } victims.add(victim, true); num_victims ++; cfg.commit(); } /* start_trouble() * Performs howmany actions, range of action controlled by initial bitflags. */ void UniConfGremlin::start_trouble(int howmany) { int r = randInt(5); for (int i = 0; i < howmany; i ++) { r = randInt(5); if (r < 1) spin_commit(500); else if (r == 1 && modify_valid) change_value(true); else if (r == 2 && modify_invalid) change_value(false); else if (r == 3 && add_values) add_value(); else if (r >= 4 && num_victims > 0 && delete_values) // randomly delete value, but always remember as a victim for fun { r = randInt(num_victims); cfg[victims[r]->value].remove(); cfg[victims[r]->value].commit(); last_change = WvString("Deleted the key %s\n", victims[r]->value); } //printf("%s", status().cstr()); } } /* spin_commit(n) * commits for n iterations, to see what effect it has */ void UniConfGremlin::spin_commit(int n) { for (int i = 0; i < n; i++) { cfg.commit(); } } /* rand_str(int type) * Returns a random string of the specified format(by type) * - not great random numbers since there's a very low probability of * getting rand() = RAND_MAX but it will happen from time to time. * had to increase the range to 1 above the max range I wanted, * just since when casting back to int it chops off the fractional part */ WvString UniConfGremlin::rand_str(int type) { if (type == TYPE_STRING || type == TYPE_HOSTNAME) { int a = randInt(50); WvString result = ""; for (int i = 0; i < a; i++) { int b = randInt(124, 97); char c[2]; c[0] = (char)b; c[1] = '\0'; result = WvString("%s%s", result, c); } return WvString("%s", result); } else if (type == TYPE_BOOL) { const char *strs[] = { "true", "yes", "on", "enabled", "1", "false", "no", "off", "disabled", "0" }; int a = randInt(10); return WvString("%s", strs[a]); } else if (type == TYPE_IP || type == TYPE_IP_NETWORK) { int a = randInt(256), b = randInt(256), c = randInt(256), d = randInt(256); if (type == TYPE_IP_NETWORK) { int e = randInt(33); return WvString("%s.%s.%s.%s/%s", a, b, c, d, e); } else return WvString("%s.%s.%s.%s", a, b, c, d); } else if (type == TYPE_INT) return rand(); else if (type == TYPE_FLOAT) return rand(); else return ""; } /* type_value(int type) * Returns a string representation of the type passed to it. */ WvString UniConfGremlin::type_value(int type) { if (type == TYPE_STRING) return "String"; else if (type == TYPE_IP) return "IP"; else if (type == TYPE_IP_NETWORK) return "IP Network"; else if (type == TYPE_HOSTNAME) return "Hostvalue"; else if (type == TYPE_BOOL) return "Boolean"; else if (type == TYPE_INT) return "Integer"; else if (type == TYPE_FLOAT) return "Float"; else return "Unknown"; } /* randInt(int max, int min) * generate a random integer between max and min */ int UniConfGremlin::randInt(int max, int min = 0) { return (int)(((double)rand() / (double)RAND_MAX) * (max - min)) + min; } /* curr_runlevel() * Returns a string describing the current runlevel. */ /*WvString UniConfGremlin::curr_runlevel() { if (runlevel == 1) return "1 - Change keys with valid data."; else if (runlevel == 2) return "2 - Change keys with invalid data."; else if (runlevel == 3) return "3 - Add new keys."; else if (runlevel == 4) return "4 - Remove keys."; else if (runlevel == 5) return "5 - Add/Remove keys, change keys with valid/invalid data."; else return WvString("Apparently I'm on runlevel %s", runlevel); }*/ /* status() * Displays the most recent action. */ WvString UniConfGremlin::status() { return WvString("Last Action was : %s", last_change); } /* test() * Code can be put here to test and tweak the functionality of the gremlin */ void UniConfGremlin::test() { printf("Testing Random Generators\n"); printf("STRING %s\n", UniConfGremlin::rand_str(TYPE_STRING).cstr()); printf("IP %s\n", UniConfGremlin::rand_str(TYPE_IP).cstr()); printf("IP_NETWORK %s\n", UniConfGremlin::rand_str(TYPE_IP_NETWORK).cstr()); printf("HOSTNAME %s\n", UniConfGremlin::rand_str(TYPE_HOSTNAME).cstr()); printf("BOOL %s\n", UniConfGremlin::rand_str(TYPE_BOOL).cstr()); printf("INT %s\n", UniConfGremlin::rand_str(TYPE_INT).cstr()); printf("FLOAT %s\n", UniConfGremlin::rand_str(TYPE_FLOAT).cstr()); printf("Testing adding things to the UniConf\n"); int count = 0; for (int i = 0; i < 5; i ++) { printf("Adding 5 random strings of type %s\n", type_value(i).cstr()); for (int j = 0; j < 5; j ++) { WvString rand = rand_str(i); printf("Adding %s\n", rand.cstr()); cfg.xset(count, rand); cfg.commit(); count ++; } } printf("Adding 5 random ints\n"); for (int i = 5; i < 10; i ++) { int randint = rand(); printf("Adding %i\n", randint); cfg.xsetint(count, randint); cfg.commit(); count ++; } printf("Testing Find Victims\n"); find_victims(); for (int i = 0; i < num_victims; i ++) { printf("%s:", victims[i]->value.cstr()); printf("%s:", type_value(victims[i]->type).cstr()); printf("%s\n", cfg[victims[i]->value].getme().cstr()); } printf("Testing Start Trouble\n"); start_trouble(1000); } wvstreams-4.6.1/uniconf/gremlin/rungremlin.cc0000644000175000001440000000102011036722347020357 0ustar wlachusers#include "unigremlin.h" #include "wvstring.h" #include #define TEST_GREMLIN 0 int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } WvString moniker = argv[1]; WvString key = argv[2]; if (!key) key = "/"; UniConfGremlin g(moniker, key); printf("Gremlin created\n"); #if TEST_GREMLIN g.test(); #else g.start(); #endif printf("%s", g.status().cstr()); return 0; } wvstreams-4.6.1/uniconf/unireadonlygen.cc0000644000175000001440000000065611036722347017601 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A read only generator wrapper. */ #include "unireadonlygen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(UniReadOnlyGen); static IUniConfGen *creator(WvStringParm s, IObject *_obj) { return new UniReadOnlyGen(wvcreate(s, _obj)); } static WvMoniker reg("readonly", creator); wvstreams-4.6.1/uniconf/unitransactiongen.cc0000644000175000001440000005373011044447363020313 0ustar wlachusers#include "unitransactiongen.h" #include "uniconftree.h" #include "unilistiter.h" #include "wvmoniker.h" static IUniConfGen *creator(WvStringParm s, IObject *_obj) { IUniConfGen *base = wvcreate(s, _obj); if (base) return new UniTransactionGen(base); else return NULL; } static WvMoniker moniker("transaction", creator); /* This enum is a field of UniConfChangeTree. It indicates the type of change represented by a node in a UniConfChangeTree. */ enum changeMode { /* This indicates that "newvalue" is valid and that its value should be written to the underlying generator at commit time. This tree *might* have children, which must be applied. "newvalue" will be a non-null pointer to a non-null WvString. */ NEWVALUE, /* This indicates that "newtree" is valid (but possibly NULL) and that the underlying generator's corresponding subtree should be made identical at commit time. This tree will *not* have children (though newtree might). */ NEWTREE, /* This indicates that "was_null_or_empty" is valid and that the key in the underlying generator should be created at commit time if it does not already exist at commit time. This tree *will* have children, which must be applied, and at least one of which will be non-BLANK. "was_null_or_empty" will be the return value of the WvString negation operation on the last known value of the corresponding key in the underlying generator; it is necessary in order to filter callbacks in certain cases. */ NEWNODE, /* This indicates that none of the fields are valid and that nothing should be done for this tree. This tree *will* have children, which must be applied, but they will all have mode of NEWTREE with newtree == NULL. */ BLANK }; class UniConfChangeTree : public UniConfTree { public: changeMode mode; // This used to be a union, but it was causing memory errors that were // extremely difficult to track down. Some of this code might serve no // purpose without this being a union, but I'd rather have it still work // and not leak than break it. -- mrwise WvString newvalue; UniConfValueTree *newtree; bool was_null_or_empty; // Constructs a tree and links it to a parent. UniConfChangeTree(UniConfChangeTree *parent, const UniConfKey &key) : UniConfTree(parent, key), newtree(0) {} // Destroys a tree and everything it owns. ~UniConfChangeTree() { if (newtree) delete newtree; } }; // Constructed by UniTransactionGen::iterator() to iterate over a section that // is to be completely replaced by a particular UniConfValueTree. class GenStyleValueTreeIter : public UniConfGen::Iter { public: GenStyleValueTreeIter(UniConfValueTree *node) : i(*node) { // printf("GenStyleValueTreeIter\n"); } ~GenStyleValueTreeIter() { // printf("~GenStyleValueTreeIter\n"); } void rewind() { i.rewind(); } bool next() { return i.next(); } UniConfKey key() const { return i->key(); } WvString value() const { return i->value(); } private: UniConfValueTree::Iter i; }; // Constructed by UniTransactionGen::iterator() to iterate over a section that // is being modified but not replaced. We iterate first over all of the values // that we're changing, except those we're deleting, and second over all // existing values not iterated over in the first stage, except those we're // deleting. class GenStyleChangeTreeIter : public UniConfGen::Iter { public: GenStyleChangeTreeIter(UniConfChangeTree *_root, const UniConfKey &_section, IUniConfGen *_base) : root(_root), section(_section), base(_base), doing_i1(true), i1(*root), i2(base->iterator(section)) { // printf("GenStyleChangeTreeIter(%s)\n", WvString(section).cstr()); } ~GenStyleChangeTreeIter() { // printf("~GenStyleChangeTreeIter(%s)\n", WvString(section).cstr()); if (i2) delete i2; } void rewind() { i1.rewind(); doing_i1 = true; } bool next() { if (doing_i1) { for (;;) { if (i1.next()) { if (i1->mode == NEWVALUE || i1->mode == NEWNODE || (i1->mode == NEWTREE && i1->newtree)) return true; } else break; } doing_i1 = false; if (i2) i2->rewind(); } if (i2) { for (;;) { if (i2->next()) { UniConfChangeTree *node = root->findchild(i2->key()); if (!node || node->mode == BLANK) return true; } else break; } } return false; } UniConfKey key() const { if (doing_i1) return i1->key(); else if (i2) return i2->key(); else return UniConfKey(); } WvString value() const { if (doing_i1) { if (i1->mode == NEWVALUE) return i1->newvalue; else if (i1->mode == NEWTREE) return i1->newtree->value(); else // i.e. i1->mode == NEWNODE { WvString value(base->get(UniConfKey(section, i1->key()))); return !value ? WvString::empty : value; } } else { return i2->value(); } } private: UniConfChangeTree *root; UniConfKey section; IUniConfGen *base; bool doing_i1; UniConfChangeTree::Iter i1; UniConfGen::Iter *i2; }; UniTransactionGen::UniTransactionGen(IUniConfGen *_base) : root(NULL), base(_base) { base->add_callback(this, wv::bind(&UniTransactionGen::gencallback, this, _1, _2)); } UniTransactionGen::~UniTransactionGen() { base->del_callback(this); WVRELEASE(base); WVDELETE(root); } WvString UniTransactionGen::get(const UniConfKey &key) { UniConfChangeTree *node = root; for (int seg = 0;; node = node->findchild(key.segment(seg++))) { if (!node) // If we couldn't find the next node, then we aren't // changing the requested key, and so the value is whatever // it currently is. return base->get(key); else if (node->mode == NEWTREE) { // Else if the next node has mode of NEWTREE, then we're changing // the requested key to whatever its value is in the stored // tree. if (node->newtree) { UniConfValueTree *subnode = node->newtree->find( key.last(key.numsegments() - seg)); if (subnode) return subnode->value(); } return WvString::null; } else if (seg == key.numsegments()) { // Else if this is the last node, then figure out what the node // would do and return the appropriate value. (The node's mode // will be either NEWVALUE, NEWNODE, or BLANK.) if (node->mode == NEWVALUE) return node->newvalue; WvString value(base->get(key.first(seg))); return (node->mode == NEWNODE && !value) ? WvString::empty : value; } } } void UniTransactionGen::set(const UniConfKey &key, WvStringParm value) { hold_delta(); root = set_change(root, key, 0, value); unhold_delta(); } void UniTransactionGen::setv(const UniConfPairList &pairs) { hold_delta(); UniConfPairList::Iter i(pairs); for (i.rewind(); i.next(); ) root = set_change(root, i->key(), 0, i->value()); unhold_delta(); } void UniTransactionGen::commit() { if (root) { // Apply our changes to the inner generator. We can't optimise // away callbacks at this point, because we may get notified of // changes caused by our changes. hold_delta(); apply_changes(root, UniConfKey()); // make sure the inner generator also commits base->commit(); // save deleting the root till now so we can hide any // redundant notifications caused by the base->commit() delete root; root = NULL; unhold_delta(); } // no need to base->commit() if we know we haven't changed anything! } bool UniTransactionGen::refresh() { if (root) { hold_delta(); cancel_changes(root, UniConfKey()); delete root; root = NULL; unhold_delta(); // no need to base->commit() here, since the inner generator never // saw any changes } // must always base->refresh(), even if we didn't change anything return base->refresh(); } UniConfGen::Iter *UniTransactionGen::iterator(const UniConfKey &key) { UniConfChangeTree *node = root; for (int seg = 0;; node = node->findchild(key.segment(seg++))) { if (!node) // If we couldn't find the next node, then we aren't changing the // children of the requested key, so they're whatever they // currently are. return base->iterator(key); else if (node->mode == NEWTREE) { // Else if the next node has mode of NEWTREE, then we're changing // the children of the requested key to whatever they are in the // stored tree. if (node->newtree) { UniConfValueTree *subnode = node->newtree->find( key.last(key.numsegments() - seg)); if (subnode) { UniConfGen::Iter *i = new GenStyleValueTreeIter(subnode); UniListIter *i2 = new UniListIter(this); i2->autofill(i); delete i; return i2; } } return new UniConfGen::NullIter(); } else if (seg == key.numsegments()) { // Else if this is the last node, then iterate over its direct // children. UniConfGen::Iter *i = new GenStyleChangeTreeIter(node, key, base); UniListIter *i2 = new UniListIter(this); i2->autofill(i); delete i; return i2; } } } void UniTransactionGen::apply_values(UniConfValueTree *newcontents, const UniConfKey §ion) { base->set(section, newcontents->value()); UniConfGen::Iter *j = base->iterator(section); if (j) { for (j->rewind(); j->next();) { if (newcontents->findchild(j->key()) == NULL) // Delete all children of the current value in the // underlying generator that do not exist in our // replacement tree. base->set(UniConfKey(section, j->key()), WvString::null); } delete j; } // Repeat for each child in the replacement tree. UniConfValueTree::Iter i(*newcontents); for (i.rewind(); i.next();) apply_values(i.ptr(), UniConfKey(section, i->key())); } void UniTransactionGen::apply_changes(UniConfChangeTree *node, const UniConfKey §ion) { if (node->mode == NEWTREE) { // If the current change is a NEWTREE change, then replace the // tree in the underlying generator with the stored one. if (node->newtree == NULL) base->set(section, WvString::null); else apply_values(node->newtree, section); // Since such changes have no children, return immediately. return; } else if (node->mode == NEWVALUE) { // Else if the current change is a NEWVALUE change, ... base->set(section, node->newvalue); } else if (node->mode == NEWNODE) { // Else if the current change is a NEWNODE change, ... if (!base->exists(section)) // ... and the current value in the underlying generator doesn't // exist, then create it. base->set(section, WvString::empty); // Note: This *is* necessary. We can't ignore this change and have // the underlying generator handle it, because it's possible that // this NEWNODE was the result of a set() which was later deleted. } // Repeat for each child in the change tree. UniConfChangeTree::Iter i(*node); for (i.rewind(); i.next();) apply_changes(i.ptr(), UniConfKey(section, i->key())); } struct my_userdata { UniConfValueTree *node; const UniConfKey &key; }; void UniTransactionGen::deletion_visitor(const UniConfValueTree *node, void *userdata) { my_userdata *data = (my_userdata *)userdata; delta(UniConfKey(data->key, node->fullkey(data->node)), WvString::null); } // Mirror image of apply_values() that issues all of the callbacks associated // with discarding a replacement value tree. void UniTransactionGen::cancel_values(UniConfValueTree *newcontents, const UniConfKey §ion) { WvString value(base->get(section)); if (!newcontents || newcontents->value() != value) delta(section, value); if (newcontents) { UniConfValueTree::Iter i(*newcontents); for (i.rewind(); i.next();) { UniConfKey subkey(section, i->key()); if (!base->exists(subkey)) { my_userdata data = { i.ptr(), subkey }; i->visit(wv::bind(&UniTransactionGen::deletion_visitor, this, _1, _2), (void*)&data, false, true); } } } UniConfGen::Iter *i = base->iterator(section); if (i) { for (i->rewind(); i->next();) cancel_values(newcontents ? newcontents->findchild(i->key()) : NULL, UniConfKey(section, i->key())); delete i; } } // Mirror image of apply_changes() that issues all of the callbacks associated // with discarding a change tree. void UniTransactionGen::cancel_changes(UniConfChangeTree *node, const UniConfKey §ion) { if (node->mode == NEWTREE) { if (!base->exists(section)) { if (node->newtree != NULL) { my_userdata data = { node->newtree, section }; node->newtree->visit( wv::bind(&UniTransactionGen::deletion_visitor, this, _1, _2), (void *)&data, false, true); } } else cancel_values(node->newtree, section); return; } WvString value; if (node->mode != BLANK) value = base->get(section); if (node->mode == NEWVALUE && !value.isnull() && value != node->newvalue) delta(section, value); UniConfChangeTree::Iter i(*node); for (i.rewind(); i.next();) cancel_changes(i.ptr(), UniConfKey(section, i->key())); if (node->mode != BLANK && value.isnull()) delta(section, WvString::null); } void UniTransactionGen::gencallback(const UniConfKey &key, WvStringParm value) { UniConfChangeTree *node = root; for (int seg = 0;; node = node->findchild(key.segment(seg++))) { if (!node) // If we couldn't find the next node, then we aren't changing // the changed key or any of its children, and so a callback // should be made. break; else if (node->mode == NEWTREE) // Else if the next node has mode of NEWTREE, then we're changing // the changed key and all of its children to whatever their // values are in the stored tree, and so the callback should be // ignored. return; else if (seg == key.numsegments()) { // Else if this is the last node, then figure out what we // should do. if (node->mode == NEWVALUE) // If we're replacing this key's value, then we should // ignore the callback. return; else if (node->mode == NEWNODE) { // Else if we want to create this key, then use its // was_null_or_empty flag to figure out if we need // to issue a callback, and update it if necessary. if (node->was_null_or_empty && !value) return; node->was_null_or_empty = !value; if (value.isnull()) { delta(key, WvString::empty); return; } break; } else // i.e. node->mode == BLANK // Else if we're doing nothing to this key, then a // callback should be made. break; } } // Make a normal callback. delta(key, value); } // Create and return a UniConfValueTree containing the value 'value' for // the key given by the segments of 'key' at and after position 'seg', with // parent 'parent' and key given by the segment of 'key' at position seg-1 // (which is the "root" key if seg == 0). Issue callbacks as necessary using // all the segments of 'key'. UniConfValueTree *UniTransactionGen::create_value(UniConfValueTree *parent, const UniConfKey &key, int seg, WvStringParm value) { UniConfValueTree *tree = 0; for (; seg != key.numsegments();) { // Create any needed intermediate nodes, each with value equal to // the empty string. parent = new UniConfValueTree(parent, key.segment(seg-1), WvString::empty); delta(key.first(seg++), WvString::empty); if (!tree) tree = parent; } // Create the last node with the specified value. parent = new UniConfValueTree(parent, key.segment(seg-1), value); delta(key, value); if (!tree) tree = parent; return tree; } void UniTransactionGen::deletion_simulator(const UniConfKey &key) { UniConfGen::Iter *i = base->iterator(key); if (i) { for (i->rewind(); i->next();) deletion_simulator(UniConfKey(key, i->key())); delete i; } delta(key, WvString::null); } // Like create_value(), but make a UniConfChangeTree containing a *change* // to value 'value'. UniConfChangeTree *UniTransactionGen::create_change(UniConfChangeTree *parent, const UniConfKey &key, int seg, WvStringParm value) { // if the key has a trailing slash, this should be a no-op: we don't // want this to have any effect if ((key.hastrailingslash()) && !value.isnull()) return parent; UniConfChangeTree *tree = 0; for (; seg != key.numsegments(); seg++) { parent = new UniConfChangeTree(parent, key.segment(seg-1)); if (value.isnull()) // We don't do anything for intermediate nodes when deleting, ... parent->mode = BLANK; else { // ... but when set()'ing a non-null value, we want them to exist. parent->mode = NEWNODE; UniConfKey nodekey(key.first(seg)); WvString curr = base->get(nodekey); parent->was_null_or_empty = !curr; if (curr.isnull()) delta(nodekey, WvString::empty); } if (!tree) tree = parent; } parent = new UniConfChangeTree(parent, key.segment(seg-1)); // Create the last node with the specified change. if (value.isnull()) { parent->mode = NEWTREE; parent->newtree = 0; if (base->exists(key)) deletion_simulator(key); } else { parent->mode = NEWVALUE; parent->newvalue = WvString(value); if (base->get(key) != value) delta(key, value); } if (!tree) tree = parent; return tree; } // Modify an existing UniConfValueTree to incorporate the set() of a // particular value for a particular key. Return a possibly altered // pointer to the root of the tree. 'seg' and 'key' are used like they // are in create_value(), and callbacks are made similarly. UniConfValueTree *UniTransactionGen::set_value(UniConfValueTree *node, const UniConfKey &key, int seg, WvStringParm value) { // printf("set_value('%s', %d)\n", WvString(key).cstr(), value.isnull()); if (value.isnull()) { // Delete the key if it exists. if (node) { UniConfValueTree *subnode = node->find( key.last(key.numsegments() - seg)); if (subnode) { hold_delta(); my_userdata data = { subnode, key }; subnode->visit(wv::bind(&UniTransactionGen::deletion_visitor, this, _1, _2), (void *)&data, false, true); // printf("DELETE SUBNODE!\n"); delete subnode; unhold_delta(); return subnode == node ? NULL : node; } else return node; } else return NULL; } else { // Switch to create_value() if we ever can't find the next node. if (!node) return create_value(NULL, key, seg, value); UniConfValueTree *subnode = node; for (; seg != key.numsegments();) { UniConfKey segment(key.segment(seg++)); UniConfValueTree *child = subnode->findchild(segment); // Switch to create_value() if we ever can't find the next node. if (!child) { create_value(subnode, key, seg, value); return node; } else subnode = child; } // The node already existed and we've found it; set it. if (value != subnode->value()) { subnode->setvalue(value); delta(key, value); } return node; } } void UniTransactionGen::deletion_simulator2(const UniConfKey &key) { UniConfGen::Iter *i = this->iterator(key); if (i) { for (i->rewind(); i->next();) deletion_simulator2(UniConfKey(key, i->key())); delete i; } delta(key, WvString::null); } // Like set_value(), but, again, for UniConfChangeTrees instead. UniConfChangeTree *UniTransactionGen::set_change(UniConfChangeTree *node, const UniConfKey &key, int seg, WvStringParm value) { // printf("set_change(key=%s,mode=%d) = '%s'\n", // WvString(key).cstr(), node ? node->mode : 999, value.cstr()); // Switch to create_change() if we ever can't find the next node, // and switch to set_value() if we ever find a NEWTREE. if (!node) return create_change(NULL, key, seg, value); else if (node->mode == NEWTREE) { node->newtree = set_value(node->newtree, key, seg, value); return node; } UniConfChangeTree *subnode = node; for (; seg != key.numsegments();) { if (subnode->mode == BLANK && !value.isnull()) { // If we're setting a non-null value and we weren't previously // doing anything to this node, then now we want to create it. subnode->mode = NEWNODE; UniConfKey nodekey(key.first(seg)); WvString curr = base->get(nodekey); subnode->was_null_or_empty = !curr; if (curr.isnull()) delta(nodekey, WvString::empty); } UniConfKey segment(key.segment(seg++)); UniConfChangeTree *next = subnode->findchild(segment); // Switch to create_change() if we ever can't find the next node, // and switch to set_value() if we ever find a NEWTREE. if (!next) { create_change(subnode, key, seg, value); return node; } else if (next->mode == NEWTREE) { next->newtree = set_value(next->newtree, key, seg, value); return node; } else subnode = next; } // The node already existed, didn't have mode of NEWTREE, and we've // found it; change it. if (value.isnull()) { if (subnode->mode != BLANK || base->exists(key)) deletion_simulator2(key); subnode->zap(); subnode->mode = NEWTREE; subnode->newtree = 0; } else if (subnode->mode == NEWVALUE) { if (subnode->newvalue != value) { subnode->newvalue = value; delta(key, value); } } else if (subnode->mode == BLANK) { if (base->get(key) != value) delta(key, value); subnode->mode = NEWVALUE; subnode->newvalue = WvString(value); } else // i.e. subnode->mode == NEWNODE { WvString currval(base->get(key)); if ((!currval != !value) && (currval != value)) delta(key, value); subnode->mode = NEWVALUE; subnode->newvalue = WvString(value); } return node; } // We'll say we're okay whenever the underlying generator is. bool UniTransactionGen::isok() { return base->isok(); } void UniTransactionGen::flush_buffers() { } wvstreams-4.6.1/uniconf/unisubtreegen.cc0000644000175000001440000000244211036722347017430 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A UniConfGen for returning only a particular subtree of a given generator. */ #include "unisubtreegen.h" #include "wvbuf.h" #include "wvtclstring.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(UniSubtreeGen); static IUniConfGen *creator(WvStringParm s, IObject *_obj) { WvConstInPlaceBuf buf(s, s.len()); WvString one(wvtcl_getword(buf)), two(wvtcl_getword(buf)); if (!one) one = ""; if (!two) two = ""; return new UniSubtreeGen(wvcreate(one), two); } static WvMoniker subtreereg("subtree", creator); UniSubtreeGen::UniSubtreeGen(IUniConfGen *gen, const UniConfKey &_subkey) : UniFilterGen(gen), subkey(_subkey) { // nothing special } bool UniSubtreeGen::keymap(const UniConfKey &unmapped_key, UniConfKey &mapped_key) { if (unmapped_key.isempty()) mapped_key = subkey; else mapped_key = UniConfKey(subkey, unmapped_key); return true; } bool UniSubtreeGen::reversekeymap(const UniConfKey &mapped_key, UniConfKey &unmapped_key) { UniConfKey _unmapped_key; bool result = subkey.suborsame(mapped_key, _unmapped_key); if (result) unmapped_key = _unmapped_key; return result; } wvstreams-4.6.1/streams/0000755000175000001440000000000011260431126014244 5ustar wlachuserswvstreams-4.6.1/streams/wvlogbuffer.cc0000644000175000001440000000520611036722347017117 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvLogBuffer is a descendant of WvLogRcv that buffers log messages for * later use. It only keeps up to max_lines log entries for every * source/debug level, s.t. debug level <= max_level */ #include "wvlogbuffer.h" #include "strutils.h" #include WvLogBuffer::Msg::Msg(WvLog::LogLevel _level, WvStringParm _source, WvString _message) : level(_level), source(_source), message(_message) { time(×tamp); } WvLogBuffer::Msg* WvLogBuffer::MsgCounter::add(WvLogBuffer::Msg* msg, int max) { list.append(msg, false); // Check if we need to purge anything if (list.count() > (size_t)max) { Msg* killme = list.first(); list.unlink_first(); return killme; } else return NULL; } WvLogBuffer::WvLogBuffer(int _max_lines, WvLog::LogLevel _max_level) : WvLogRcv(_max_level), counters(25) { max_lines = _max_lines; } WvLogBuffer::~WvLogBuffer() { end_line(); } void WvLogBuffer::_mid_line(const char *str, size_t len) { current.put(str, len); } void WvLogBuffer::handle_msg(Msg *lastmsg) { // Stick the msg in the list of all messages msgs.append(lastmsg, true); // Check if we already have any messages of this source/level WvString type(WvString("%s:%s", last_source, last_level)); MsgCounter* msgcounter = counters[type]; // If not create a new tracking list for it if (!msgcounter) { msgcounter = new MsgCounter(type); counters.add(msgcounter, true); } // Now that we are sure the type exists, add the message to it Msg* killme = msgcounter->add(lastmsg, max_lines); // Delete the extra messages if we need to if (killme) msgs.unlink(killme); } void WvLogBuffer::_end_line() { if (last_level < WvLog::NUM_LOGLEVELS) { current.put('\0'); // terminating NULL Msg *lastmsg = new Msg(last_level, last_source, trim_string((char *)current.get(current.used()))); handle_msg(lastmsg); } else current.zap(); } void WvLogBuffer::feed_receiver(WvLogRcv& receiver) { WvLogBuffer::MsgList::Iter i(msgs); i.rewind(); while (i.next()) { WvLogBuffer::Msg &msg = *i; receiver.log(msg.source, msg.level, msg.message.cstr(), msg.message.len()); } } void WvLogBuffer::dump(WvStream &s) { MsgList::Iter i(messages()); for (i.rewind(); i.next(); ) { Msg &m = *i; s.print("%s %s<%s>: %s+\n", m.timestamp, m.source, loglevels[m.level], m.message); } } wvstreams-4.6.1/streams/wvistreamlist.cc0000644000175000001440000001536011042636572017507 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIStreamList holds a list of IWvStream objects -- and its select() and * callback() functions know how to handle multiple simultaneous streams. */ #include "wvistreamlist.h" #include "wvstringlist.h" #include "wvstreamsdebugger.h" #include "wvstrutils.h" #include "wvassert.h" #include "wvstrutils.h" #ifndef _WIN32 #include "wvfork.h" #endif #ifdef HAVE_VALGRIND_MEMCHECK_H #include #else #define RUNNING_ON_VALGRIND false #endif // enable this to add some read/write trace messages (this can be VERY // verbose) #define STREAMTRACE 0 #if STREAMTRACE # define TRACE(x, y...) fprintf(stderr, x, ## y) #else #ifndef _MSC_VER # define TRACE(x, y...) #else # define TRACE #endif #endif WvIStreamList WvIStreamList::globallist; WvIStreamList::WvIStreamList(): in_select(false), dead_stream(false) { readcb = writecb = exceptcb = 0; auto_prune = true; if (this == &globallist) { globalstream = this; #ifndef _WIN32 add_wvfork_callback(WvIStreamList::onfork); #endif set_wsname("globallist"); add_debugger_commands(); } } WvIStreamList::~WvIStreamList() { close(); } bool WvIStreamList::isok() const { return WvStream::isok(); } class BoolGuard { public: BoolGuard(bool &_guard_bool): guard_bool(_guard_bool) { assert(!guard_bool); guard_bool = true; } ~BoolGuard() { guard_bool = false; } private: bool &guard_bool; }; void WvIStreamList::pre_select(SelectInfo &si) { //BoolGuard guard(in_select); bool already_sure = false; SelectRequest oldwant = si.wants; sure_thing.zap(); time_t alarmleft = alarm_remaining(); if (alarmleft == 0) already_sure = true; IWvStream *old_in_stream = WvCrashInfo::in_stream; const char *old_in_stream_id = WvCrashInfo::in_stream_id; WvCrashInfo::InStreamState old_in_stream_state = WvCrashInfo::in_stream_state; WvCrashInfo::in_stream_state = WvCrashInfo::PRE_SELECT; Iter i(*this); for (i.rewind(); i.next(); ) { IWvStream &s(*i); #if I_ENJOY_FORMATTING_STRINGS WvCrashWill will("doing pre_select for \"%s\" (%s)\n%s", i.link->id, ptr2str(&s), wvcrash_read_will()); #else WvCrashInfo::in_stream = &s; WvCrashInfo::in_stream_id = i.link->id; #endif si.wants = oldwant; s.pre_select(si); if (!s.isok()) already_sure = true; TRACE("after pre_select(%s): msec_timeout is %ld\n", i.link->id, (long)si.msec_timeout); } WvCrashInfo::in_stream = old_in_stream; WvCrashInfo::in_stream_id = old_in_stream_id; WvCrashInfo::in_stream_state = old_in_stream_state; if (alarmleft >= 0 && (alarmleft < si.msec_timeout || si.msec_timeout < 0)) si.msec_timeout = alarmleft; si.wants = oldwant; if (already_sure) si.msec_timeout = 0; } bool WvIStreamList::post_select(SelectInfo &si) { //BoolGuard guard(in_select); bool already_sure = false; SelectRequest oldwant = si.wants; time_t alarmleft = alarm_remaining(); if (alarmleft == 0) already_sure = true; IWvStream *old_in_stream = WvCrashInfo::in_stream; const char *old_in_stream_id = WvCrashInfo::in_stream_id; WvCrashInfo::InStreamState old_in_stream_state = WvCrashInfo::in_stream_state; WvCrashInfo::in_stream_state = WvCrashInfo::POST_SELECT; Iter i(*this); for (i.rewind(); i.cur() && i.next(); ) { IWvStream &s(*i); #if I_ENJOY_FORMATTING_STRINGS WvCrashWill will("doing post_select for \"%s\" (%s)\n%s", i.link->id, ptr2str(&s), wvcrash_read_will()); #else WvCrashInfo::in_stream = &s; WvCrashInfo::in_stream_id = i.link->id; #endif si.wants = oldwant; if (s.post_select(si)) { TRACE("post_select(%s) was true\n", i.link->id); sure_thing.unlink(&s); // don't add it twice! s.addRef(); sure_thing.append(&s, true, i.link->id); } else { TRACE("post_select(%s) was false\n", i.link->id); WvIStreamListBase::Iter j(sure_thing); WvLink* link = j.find(&s); wvassert(!link, "stream \"%s\" (%s) was ready in " "pre_select, but not in post_select", link->id, ptr2str(link->data)); } if (!s.isok()) { already_sure = true; if (auto_prune) i.xunlink(); } } WvCrashInfo::in_stream = old_in_stream; WvCrashInfo::in_stream_id = old_in_stream_id; WvCrashInfo::in_stream_state = old_in_stream_state; si.wants = oldwant; return already_sure || !sure_thing.isempty(); } // distribute the callback() request to all children that select 'true' void WvIStreamList::execute() { static int level = 0; const char *id; level++; WvStream::execute(); TRACE("\n%*sList@%p: (%d sure) ", level, "", this, sure_thing.count()); IWvStream *old_in_stream = WvCrashInfo::in_stream; const char *old_in_stream_id = WvCrashInfo::in_stream_id; WvCrashInfo::InStreamState old_in_stream_state = WvCrashInfo::in_stream_state; WvCrashInfo::in_stream_state = WvCrashInfo::EXECUTE; WvIStreamListBase::Iter i(sure_thing); for (i.rewind(); i.next(); ) { #if STREAMTRACE WvIStreamListBase::Iter x(*this); if (!x.find(&i())) TRACE("Yikes! %p in sure_thing, but not in main list!\n", i.cur()); #endif IWvStream &s(*i); s.addRef(); id = i.link->id; TRACE("[%p:%s]", &s, id); i.xunlink(); #if DEBUG if (!RUNNING_ON_VALGRIND) { WvString strace_node("%s: %s", s.wstype(), s.wsname()); ::write(-1, strace_node, strace_node.len()); } #endif #if I_ENJOY_FORMATTING_STRINGS WvCrashWill my_will("executing stream: %s\n%s", id ? id : "unknown stream", wvcrash_read_will()); #else WvCrashInfo::in_stream = &s; WvCrashInfo::in_stream_id = id; #endif s.callback(); s.release(); // list might have changed! i.rewind(); } WvCrashInfo::in_stream = old_in_stream; WvCrashInfo::in_stream_id = old_in_stream_id; WvCrashInfo::in_stream_state = old_in_stream_state; sure_thing.zap(); level--; TRACE("[DONE %p]\n", this); } #ifndef _WIN32 void WvIStreamList::onfork(pid_t p) { if (p == 0) { // this is a child process: don't inherit the global streamlist globallist.zap(false); } } #endif void WvIStreamList::add_debugger_commands() { WvStreamsDebugger::add_command("globallist", 0, debugger_globallist_run_cb, 0); } WvString WvIStreamList::debugger_globallist_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *) { debugger_streams_display_header(cmd, result_cb); WvIStreamList::Iter i(globallist); for (i.rewind(); i.next(); ) debugger_streams_maybe_display_one_stream(static_cast(i.ptr()), cmd, args, result_cb); return WvString::null; } wvstreams-4.6.1/streams/wvcolorlogconsole.cc0000644000175000001440000000543611036722347020354 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A version of WvColorLogConsole that colorizes the output */ #include "wvcolorlogconsole.h" #ifdef _WIN32 bool WvColorLogConsole::is_tty(int fd) { return false; } #else // !_WIN32 #include bool WvColorLogConsole::is_tty(int fd) { struct termios termios; return tcgetattr(fd, &termios) == 0; } #endif // !_WIN32 bool WvColorLogConsole::can_colorize(int fd, const char *TERM) { return is_tty(fd) && TERM != NULL && (strcmp(TERM, "linux") == 0 || strcmp(TERM, "ansi") == 0 || strcmp(TERM, "xterm") == 0 || strcmp(TERM, "rxvt") == 0); } WvColorLogConsole::WvColorLogConsole(int _fd, WvLog::LogLevel _max_level) : WvLogConsole(_fd, _max_level), colorize(WvColorLogConsole::can_colorize(_fd, getenv("TERM"))) { } WvColorLogConsole::~WvColorLogConsole() { } void WvColorLogConsole::_begin_line() { if (colorize) { const char *seq = WvColorLogConsole::color_start_seq(last_level); uwrite(seq, strlen(seq)); } WvLogConsole::_begin_line(); if (colorize) { const char *seq; seq = WvColorLogConsole::clear_to_eol_seq(last_level); uwrite(seq, strlen(seq)); seq = WvColorLogConsole::color_end_seq(last_level); uwrite(seq, strlen(seq)); } } void WvColorLogConsole::_mid_line(const char *str, size_t len) { if (colorize) { const char *seq; seq = WvColorLogConsole::color_start_seq(last_level); uwrite(seq, strlen(seq)); } WvLogConsole::_mid_line(str, len); if (colorize) { const char *seq; seq = WvColorLogConsole::clear_to_eol_seq(last_level); uwrite(seq, strlen(seq)); seq = WvColorLogConsole::color_end_seq(last_level); uwrite(seq, strlen(seq)); } } void WvColorLogConsole::_end_line() { if (colorize) { const char *seq; seq = WvColorLogConsole::color_start_seq(last_level); uwrite(seq, strlen(seq)); seq = WvColorLogConsole::clear_to_eol_seq(last_level); uwrite(seq, strlen(seq)); seq = WvColorLogConsole::color_end_seq(last_level); uwrite(seq, strlen(seq)); } WvLogConsole::_end_line(); } const char *WvColorLogConsole::color_start_seq(WvLog::LogLevel log_level) { if (int(log_level) <= int(WvLog::Error)) return "\e[41;37;1m"; else if (int(log_level) <= int(WvLog::Warning)) return "\e[43;37;1m"; else return "\e[40;37;1m"; } const char *WvColorLogConsole::clear_to_eol_seq(WvLog::LogLevel log_level) { return "\e[0K"; } const char *WvColorLogConsole::color_end_seq(WvLog::LogLevel log_level) { return "\e[0m"; } wvstreams-4.6.1/streams/wvgzipstream.cc0000644000175000001440000000044411077124114017321 0ustar wlachusers#include "wvgzipstream.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(WvGzipStream); static IWvStream *creator(WvStringParm s, IObject *_obj) { return new WvGzipStream(new WvStreamClone(wvcreate(s, _obj))); } static WvMoniker reg("gzip", creator); wvstreams-4.6.1/streams/wvstream.cc0000644000175000001440000006745511205042556016450 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Unified support for streams, that is, sequences of bytes that may or * may not be ready for read/write at any given time. * * We provide typical read and write routines, as well as a select() function * for each stream. */ #include #include #include #define __WVSTREAM_UNIT_TEST 1 #include "wvstream.h" #include "wvtimeutils.h" #include "wvcont.h" #include "wvstreamsdebugger.h" #include "wvstrutils.h" #include "wvistreamlist.h" #include "wvlinkerhack.h" #include "wvmoniker.h" #ifdef _WIN32 #define ENOBUFS WSAENOBUFS #undef errno #define errno GetLastError() #ifdef __GNUC__ #include #endif #include "streams.h" #else #include #endif #include using std::make_pair; using std::map; // enable this to add some read/write trace messages (this can be VERY // verbose) #if 0 # ifndef _MSC_VER # define TRACE(x, y...) fprintf(stderr, x, ## y); fflush(stderr); # else # define TRACE printf # endif #else # ifndef _MSC_VER # define TRACE(x, y...) # else # define TRACE # endif #endif WvStream *WvStream::globalstream = NULL; UUID_MAP_BEGIN(WvStream) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IWvStream) UUID_MAP_END static map *wsid_map; static WSID next_wsid_to_try; WV_LINK(WvStream); static IWvStream *create_null(WvStringParm, IObject *) { return new WvStream(); } static WvMoniker reg("null", create_null); IWvStream *IWvStream::create(WvStringParm moniker, IObject *obj) { IWvStream *s = wvcreate(moniker, obj); if (!s) { s = new WvStream(); s->seterr_both(EINVAL, "Unknown moniker '%s'", moniker); WVRELEASE(obj); // we're not going to use it after all } return s; } static bool is_prefix_insensitive(const char *str, const char *prefix) { size_t len = strlen(prefix); return strlen(str) >= len && strncasecmp(str, prefix, len) == 0; } static const char *strstr_insensitive(const char *haystack, const char *needle) { while (*haystack != '\0') { if (is_prefix_insensitive(haystack, needle)) return haystack; ++haystack; } return NULL; } static bool contains_insensitive(const char *haystack, const char *needle) { return strstr_insensitive(haystack, needle) != NULL; } static const char *list_format = "%6s%s%2s%s%3s%s%3s%s%6s%s%20s%s%s"; static inline const char *Yes_No(bool val) { return val? "Yes": "No"; } void WvStream::debugger_streams_display_header(WvStringParm cmd, WvStreamsDebugger::ResultCallback result_cb) { WvStringList result; result.append(list_format, "--WSID", "-", "RC", "-", "-Ok", "-", "-Cs", "-", "-AlRem", "-", "----------------Type", "-", "Name--------------------"); result_cb(cmd, result); } // Set to fit in 6 chars static WvString friendly_ms(time_t ms) { if (ms <= 0) return WvString("(%s)", ms); else if (ms < 1000) return WvString("%sms", ms); else if (ms < 60*1000) return WvString("%ss", ms/1000); else if (ms < 60*60*1000) return WvString("%sm", ms/(60*1000)); else if (ms <= 24*60*60*1000) return WvString("%sh", ms/(60*60*1000)); else return WvString("%sd", ms/(24*60*60*1000)); } void WvStream::debugger_streams_display_one_stream(WvStream *s, WvStringParm cmd, WvStreamsDebugger::ResultCallback result_cb) { WvStringList result; s->addRef(); unsigned refcount = s->release(); result.append(list_format, s->wsid(), " ", refcount, " ", Yes_No(s->isok()), " ", Yes_No(s->uses_continue_select), " ", friendly_ms(s->alarm_remaining()), " ", s->wstype(), " ", s->wsname()); result_cb(cmd, result); } void WvStream::debugger_streams_maybe_display_one_stream(WvStream *s, WvStringParm cmd, const WvStringList &args, WvStreamsDebugger::ResultCallback result_cb) { bool show = args.isempty(); WvStringList::Iter arg(args); for (arg.rewind(); arg.next(); ) { WSID wsid; bool is_num = wvstring_to_num(*arg, wsid); if (is_num) { if (s->wsid() == wsid) { show = true; break; } } else { if ((s->wsname() && contains_insensitive(s->wsname(), *arg)) || (s->wstype() && contains_insensitive(s->wstype(), *arg))) { show = true; break; } } } if (show) debugger_streams_display_one_stream(s, cmd, result_cb); } WvString WvStream::debugger_streams_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *) { debugger_streams_display_header(cmd, result_cb); if (wsid_map) { map::iterator it; for (it = wsid_map->begin(); it != wsid_map->end(); ++it) debugger_streams_maybe_display_one_stream(it->second, cmd, args, result_cb); } return WvString::null; } WvString WvStream::debugger_close_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *) { if (args.isempty()) return WvString("Usage: %s ", cmd); WSID wsid; WvString wsid_str = args.popstr(); if (!wvstring_to_num(wsid_str, wsid)) return WvString("Invalid WSID '%s'", wsid_str); IWvStream *s = WvStream::find_by_wsid(wsid); if (!s) return WvString("No such stream"); s->close(); return WvString::null; } void WvStream::add_debugger_commands() { WvStreamsDebugger::add_command("streams", 0, debugger_streams_run_cb, 0); WvStreamsDebugger::add_command("close", 0, debugger_close_run_cb, 0); } WvStream::WvStream(): read_requires_writable(NULL), write_requires_readable(NULL), uses_continue_select(false), personal_stack_size(131072), alarm_was_ticking(false), stop_read(false), stop_write(false), closed(false), readcb(wv::bind(&WvStream::legacy_callback, this)), max_outbuf_size(0), outbuf_delayed_flush(false), is_auto_flush(true), want_to_flush(true), is_flushing(false), queue_min(0), autoclose_time(0), alarm_time(wvtime_zero), last_alarm_check(wvtime_zero) { TRACE("Creating wvstream %p\n", this); static bool first = true; if (first) { first = false; WvStream::add_debugger_commands(); } // Choose a wsid; if (!wsid_map) wsid_map = new map; WSID first_wsid_tried = next_wsid_to_try; do { if (wsid_map->find(next_wsid_to_try) == wsid_map->end()) break; ++next_wsid_to_try; } while (next_wsid_to_try != first_wsid_tried); my_wsid = next_wsid_to_try++; bool inserted = wsid_map->insert(make_pair(my_wsid, this)).second; assert(inserted); #ifdef _WIN32 WSAData wsaData; int result = WSAStartup(MAKEWORD(2,0), &wsaData); assert(result == 0); #endif } // FIXME: interfaces (IWvStream) shouldn't have implementations! IWvStream::IWvStream() { } IWvStream::~IWvStream() { } WvStream::~WvStream() { TRACE("destroying %p\n", this); close(); // if this assertion fails, then uses_continue_select is true, but you // didn't call terminate_continue_select() or close() before destroying // your object. Shame on you! assert(!uses_continue_select || !call_ctx); call_ctx = 0; // finish running the suspended callback, if any assert(wsid_map); wsid_map->erase(my_wsid); if (wsid_map->empty()) { delete wsid_map; wsid_map = NULL; } // eventually, streams will auto-add themselves to the globallist. But // even before then, it'll never be useful for them to be on the // globallist *after* they get destroyed, so we might as well auto-remove // them already. It's harmless for people to try to remove them twice. WvIStreamList::globallist.unlink(this); TRACE("done destroying %p\n", this); } void WvStream::close() { TRACE("flushing in wvstream...\n"); flush(2000); // fixme: should not hardcode this stuff TRACE("(flushed)\n"); closed = true; if (!!closecb) { IWvStreamCallback cb = closecb; closecb = 0; // ensure callback is only called once cb(); } // I would like to delete call_ctx here, but then if someone calls // close() from *inside* a continuable callback, we explode. Oops! //call_ctx = 0; // destroy the context, if necessary } void WvStream::autoforward(WvStream &s) { setcallback(wv::bind(autoforward_callback, wv::ref(*this), wv::ref(s))); read_requires_writable = &s; } void WvStream::noautoforward() { setcallback(0); read_requires_writable = NULL; } void WvStream::autoforward_callback(WvStream &input, WvStream &output) { char buf[1024]; size_t len; len = input.read(buf, sizeof(buf)); output.write(buf, len); } void WvStream::_callback() { execute(); if (!!callfunc) callfunc(); } void *WvStream::_callwrap(void *) { _callback(); return NULL; } void WvStream::callback() { TRACE("(?)"); // if the alarm has gone off and we're calling callback... good! if (alarm_remaining() == 0) { alarm_time = wvtime_zero; alarm_was_ticking = true; } else alarm_was_ticking = false; assert(!uses_continue_select || personal_stack_size >= 1024); #define TEST_CONTINUES_HARSHLY 0 #if TEST_CONTINUES_HARSHLY #ifndef _WIN32 # warning "Using WvCont for *all* streams for testing!" #endif if (1) #else if (uses_continue_select && personal_stack_size >= 1024) #endif { if (!call_ctx) // no context exists yet! { call_ctx = WvCont(wv::bind(&WvStream::_callwrap, this, _1), personal_stack_size); } call_ctx(NULL); } else _callback(); // if this assertion fails, a derived class's virtual execute() function // didn't call its parent's execute() function, and we didn't make it // all the way back up to WvStream::execute(). This doesn't always // matter right now, but it could lead to obscure bugs later, so we'll // enforce it. } bool WvStream::isok() const { return !closed && WvErrorBase::isok(); } void WvStream::seterr(int _errnum) { if (!geterr()) // no pre-existing error { WvErrorBase::seterr(_errnum); close(); } } size_t WvStream::read(WvBuf &outbuf, size_t count) { // for now, just wrap the older read function size_t free = outbuf.free(); if (count > free) count = free; WvDynBuf tmp; unsigned char *buf = tmp.alloc(count); size_t len = read(buf, count); tmp.unalloc(count - len); outbuf.merge(tmp); return len; } size_t WvStream::write(WvBuf &inbuf, size_t count) { // for now, just wrap the older write function size_t avail = inbuf.used(); if (count > avail) count = avail; const unsigned char *buf = inbuf.get(count); size_t len = write(buf, count); inbuf.unget(count - len); return len; } size_t WvStream::read(void *buf, size_t count) { assert(!count || buf); size_t bufu, i; unsigned char *newbuf; bufu = inbuf.used(); if (bufu < queue_min) { newbuf = inbuf.alloc(queue_min - bufu); assert(newbuf); i = uread(newbuf, queue_min - bufu); inbuf.unalloc(queue_min - bufu - i); bufu = inbuf.used(); } if (bufu < queue_min) { maybe_autoclose(); return 0; } // if buffer is empty, do a hard read if (!bufu) bufu = uread(buf, count); else { // otherwise just read from the buffer if (bufu > count) bufu = count; memcpy(buf, inbuf.get(bufu), bufu); } TRACE("read obj 0x%08x, bytes %d/%d\n", (unsigned int)this, bufu, count); maybe_autoclose(); return bufu; } size_t WvStream::write(const void *buf, size_t count) { assert(!count || buf); if (!isok() || !buf || !count || stop_write) return 0; size_t wrote = 0; if (!outbuf_delayed_flush && !outbuf.used()) { wrote = uwrite(buf, count); count -= wrote; buf = (const unsigned char *)buf + wrote; // if (!count) return wrote; // short circuit if no buffering needed } if (max_outbuf_size != 0) { size_t canbuffer = max_outbuf_size - outbuf.used(); if (count > canbuffer) count = canbuffer; // can't write the whole amount } if (count != 0) { outbuf.put(buf, count); wrote += count; } if (should_flush()) { if (is_auto_flush) flush(0); else flush_outbuf(0); } return wrote; } void WvStream::noread() { stop_read = true; maybe_autoclose(); } void WvStream::nowrite() { stop_write = true; maybe_autoclose(); } void WvStream::maybe_autoclose() { if (stop_read && stop_write && !outbuf.used() && !inbuf.used() && !closed) close(); } bool WvStream::isreadable() { return isok() && select(0, true, false, false); } bool WvStream::iswritable() { return !stop_write && isok() && select(0, false, true, false); } char *WvStream::blocking_getline(time_t wait_msec, int separator, int readahead) { assert(separator >= 0); assert(separator <= 255); //assert(uses_continue_select || wait_msec == 0); WvTime timeout_time(0); if (wait_msec > 0) timeout_time = msecadd(wvtime(), wait_msec); maybe_autoclose(); // if we get here, we either want to wait a bit or there is data // available. while (isok()) { // fprintf(stderr, "(inbuf used = %d)\n", inbuf.used()); fflush(stderr); queuemin(0); // if there is a newline already, we have enough data. if (inbuf.strchr(separator) > 0) break; else if (!isok() || stop_read) // uh oh, stream is in trouble. break; // make select not return true until more data is available queuemin(inbuf.used() + 1); // compute remaining timeout if (wait_msec > 0) { wait_msec = msecdiff(timeout_time, wvtime()); if (wait_msec < 0) wait_msec = 0; } // FIXME: this is blocking_getline. It shouldn't // call continue_select()! bool hasdata; if (wait_msec != 0 && uses_continue_select) hasdata = continue_select(wait_msec); else hasdata = select(wait_msec, true, false); if (!isok()) break; if (hasdata) { // read a few bytes WvDynBuf tmp; unsigned char *buf = tmp.alloc(readahead); assert(buf); size_t len = uread(buf, readahead); tmp.unalloc(readahead - len); inbuf.put(tmp.get(len), len); hasdata = len > 0; // enough? } if (!isok()) break; if (!hasdata && wait_msec == 0) return NULL; // handle timeout } if (!inbuf.used()) return NULL; // return the appropriate data size_t i = 0; i = inbuf.strchr(separator); if (i > 0) { char *eol = (char *)inbuf.mutablepeek(i - 1, 1); assert(eol && *eol == separator); *eol = 0; return const_cast((const char *)inbuf.get(i)); } else { // handle "EOF without newline" condition // FIXME: it's very silly that buffers can't return editable // char* arrays. inbuf.alloc(1)[0] = 0; // null-terminate it return const_cast((const char *)inbuf.get(inbuf.used())); } } char *WvStream::continue_getline(time_t wait_msec, int separator, int readahead) { assert(false && "not implemented, come back later!"); assert(uses_continue_select); return NULL; } void WvStream::drain() { char buf[1024]; while (isreadable()) read(buf, sizeof(buf)); } bool WvStream::flush(time_t msec_timeout) { if (is_flushing) return false; TRACE("%p flush starts\n", this); is_flushing = true; want_to_flush = true; bool done = flush_internal(msec_timeout) // any other internal buffers && flush_outbuf(msec_timeout); // our own outbuf is_flushing = false; TRACE("flush stops (%d)\n", done); return done; } bool WvStream::should_flush() { return want_to_flush; } bool WvStream::flush_outbuf(time_t msec_timeout) { TRACE("%p flush_outbuf starts (isok=%d)\n", this, isok()); bool outbuf_was_used = outbuf.used(); // do-nothing shortcut for speed // FIXME: definitely makes a "measurable" difference... // but is it worth the risk? if (!outbuf_was_used && !autoclose_time && !outbuf_delayed_flush) { maybe_autoclose(); return true; } WvTime stoptime = msecadd(wvtime(), msec_timeout); // flush outbuf while (outbuf_was_used && isok()) { // fprintf(stderr, "%p: fd:%d/%d, used:%d\n", // this, getrfd(), getwfd(), outbuf.used()); size_t attempt = outbuf.optgettable(); size_t real = uwrite(outbuf.get(attempt), attempt); // WARNING: uwrite() may have messed up our outbuf! // This probably only happens if uwrite() closed the stream because // of an error, so we'll check isok(). if (isok() && real < attempt) { TRACE("flush_outbuf: unget %d-%d\n", attempt, real); assert(outbuf.ungettable() >= attempt - real); outbuf.unget(attempt - real); } // since post_select() can call us, and select() calls post_select(), // we need to be careful not to call select() if we don't need to! // post_select() will only call us with msec_timeout==0, and we don't // need to do select() in that case anyway. if (!msec_timeout) break; if (msec_timeout >= 0 && (stoptime < wvtime() || !select(msec_timeout, false, true))) break; outbuf_was_used = outbuf.used(); } // handle autoclose if (autoclose_time && isok()) { time_t now = time(NULL); TRACE("Autoclose enabled for 0x%p - now-time=%ld, buf %d bytes\n", this, now - autoclose_time, outbuf.used()); if ((flush_internal(0) && !outbuf.used()) || now > autoclose_time) { autoclose_time = 0; // avoid infinite recursion! close(); } } TRACE("flush_outbuf: after autoclose chunk\n"); if (outbuf_delayed_flush && !outbuf_was_used) want_to_flush = false; TRACE("flush_outbuf: now isok=%d\n", isok()); // if we can't flush the outbuf, at least empty it! if (outbuf_was_used && !isok()) outbuf.zap(); maybe_autoclose(); TRACE("flush_outbuf stops\n"); return !outbuf_was_used; } bool WvStream::flush_internal(time_t msec_timeout) { // once outbuf emptied, that's it for most streams return true; } int WvStream::getrfd() const { return -1; } int WvStream::getwfd() const { return -1; } void WvStream::flush_then_close(int msec_timeout) { time_t now = time(NULL); autoclose_time = now + (msec_timeout + 999) / 1000; TRACE("Autoclose SETUP for 0x%p - buf %d bytes, timeout %ld sec\n", this, outbuf.used(), autoclose_time - now); // as a fast track, we _could_ close here: but that's not a good idea, // since flush_then_close() deals with obscure situations, and we don't // want the caller to use it incorrectly. So we make things _always_ // break when the caller forgets to call select() later. flush(0); } void WvStream::pre_select(SelectInfo &si) { maybe_autoclose(); time_t alarmleft = alarm_remaining(); if (!isok() || (!si.inherit_request && alarmleft == 0)) { si.msec_timeout = 0; return; // alarm has rung } if (!si.inherit_request) { si.wants.readable |= static_cast(readcb); si.wants.writable |= static_cast(writecb); si.wants.isexception |= static_cast(exceptcb); } // handle read-ahead buffering if (si.wants.readable && inbuf.used() && inbuf.used() >= queue_min) { si.msec_timeout = 0; // already ready return; } if (alarmleft >= 0 && (alarmleft < si.msec_timeout || si.msec_timeout < 0)) si.msec_timeout = alarmleft + 10; } bool WvStream::post_select(SelectInfo &si) { if (!si.inherit_request) { si.wants.readable |= static_cast(readcb); si.wants.writable |= static_cast(writecb); si.wants.isexception |= static_cast(exceptcb); } // FIXME: need sane buffer flush support for non FD-based streams // FIXME: need read_requires_writable and write_requires_readable // support for non FD-based streams // note: flush(nonzero) might call select(), but flush(0) never does, // so this is safe. if (should_flush()) flush(0); if (!si.inherit_request && alarm_remaining() == 0) return true; // alarm ticked if ((si.wants.readable || (!si.inherit_request && readcb)) && inbuf.used() && inbuf.used() >= queue_min) return true; // already ready return false; } void WvStream::_build_selectinfo(SelectInfo &si, time_t msec_timeout, bool readable, bool writable, bool isexcept, bool forceable) { FD_ZERO(&si.read); FD_ZERO(&si.write); FD_ZERO(&si.except); if (forceable) { si.wants.readable = readcb; si.wants.writable = writecb; si.wants.isexception = exceptcb; } else { si.wants.readable = readable; si.wants.writable = writable; si.wants.isexception = isexcept; } si.max_fd = -1; si.msec_timeout = msec_timeout; si.inherit_request = ! forceable; si.global_sure = false; wvstime_sync(); pre_select(si); if (globalstream && forceable && (globalstream != this)) { WvStream *s = globalstream; globalstream = NULL; // prevent recursion s->xpre_select(si, SelectRequest(false, false, false)); globalstream = s; } } int WvStream::_do_select(SelectInfo &si) { // prepare timeout timeval tv; tv.tv_sec = si.msec_timeout / 1000; tv.tv_usec = (si.msec_timeout % 1000) * 1000; #ifdef _WIN32 // selecting on an empty set of sockets doesn't cause a delay in win32. SOCKET fakefd = socket(PF_INET, SOCK_STREAM, 0); FD_SET(fakefd, &si.except); #endif // block int sel = ::select(si.max_fd+1, &si.read, &si.write, &si.except, si.msec_timeout >= 0 ? &tv : (timeval*)NULL); // handle errors. // EAGAIN and EINTR don't matter because they're totally normal. // ENOBUFS is hopefully transient. // EBADF is kind of gross and might imply that something is wrong, // but it happens sometimes... if (sel < 0 && errno != EAGAIN && errno != EINTR && errno != EBADF && errno != ENOBUFS ) { seterr(errno); } #ifdef _WIN32 ::close(fakefd); #endif TRACE("select() returned %d\n", sel); return sel; } bool WvStream::_process_selectinfo(SelectInfo &si, bool forceable) { // We cannot move the clock backward here, because timers that // were expired in pre_select could then not be expired anymore, // and while time going backward is rather unsettling in general, // for it to be happening between pre_select and post_select is // just outright insanity. wvstime_sync_forward(); bool sure = post_select(si); if (globalstream && forceable && (globalstream != this)) { WvStream *s = globalstream; globalstream = NULL; // prevent recursion si.global_sure = s->xpost_select(si, SelectRequest(false, false, false)) || si.global_sure; globalstream = s; } return sure; } bool WvStream::_select(time_t msec_timeout, bool readable, bool writable, bool isexcept, bool forceable) { // Detect use of deleted stream assert(wsid_map && (wsid_map->find(my_wsid) != wsid_map->end())); SelectInfo si; _build_selectinfo(si, msec_timeout, readable, writable, isexcept, forceable); bool sure = false; int sel = _do_select(si); if (sel >= 0) sure = _process_selectinfo(si, forceable); if (si.global_sure && globalstream && forceable && (globalstream != this)) globalstream->callback(); return sure; } IWvStream::SelectRequest WvStream::get_select_request() { return IWvStream::SelectRequest(readcb, writecb, exceptcb); } void WvStream::force_select(bool readable, bool writable, bool isexception) { if (readable) readcb = wv::bind(&WvStream::legacy_callback, this); if (writable) writecb = wv::bind(&WvStream::legacy_callback, this); if (isexception) exceptcb = wv::bind(&WvStream::legacy_callback, this); } void WvStream::undo_force_select(bool readable, bool writable, bool isexception) { if (readable) readcb = 0; if (writable) writecb = 0; if (isexception) exceptcb = 0; } void WvStream::alarm(time_t msec_timeout) { if (msec_timeout >= 0) alarm_time = msecadd(wvstime(), msec_timeout); else alarm_time = wvtime_zero; } time_t WvStream::alarm_remaining() { if (alarm_time.tv_sec) { WvTime now = wvstime(); // Time is going backward! if (now < last_alarm_check) { #if 0 // okay, I give up. Time just plain goes backwards on some systems. // warn only if it's a "big" difference (sigh...) if (msecdiff(last_alarm_check, now) > 200) fprintf(stderr, " ************* TIME WENT BACKWARDS! " "(%ld:%ld %ld:%ld)\n", last_alarm_check.tv_sec, last_alarm_check.tv_usec, now.tv_sec, now.tv_usec); #endif alarm_time = tvdiff(alarm_time, tvdiff(last_alarm_check, now)); } last_alarm_check = now; time_t remaining = msecdiff(alarm_time, now); if (remaining < 0) remaining = 0; return remaining; } return -1; } bool WvStream::continue_select(time_t msec_timeout) { assert(uses_continue_select); // if this assertion triggers, you probably tried to do continue_select() // while inside terminate_continue_select(). assert(call_ctx); if (msec_timeout >= 0) alarm(msec_timeout); alarm(msec_timeout); WvCont::yield(); alarm(-1); // cancel the still-pending alarm, or it might go off later! // when we get here, someone has jumped back into our task. // We have to select(0) here because it's possible that the alarm was // ticking _and_ data was available. This is aggravated especially if // msec_delay was zero. Note that running select() here isn't // inefficient, because if the alarm was expired then pre_select() // returned true anyway and short-circuited the previous select(). TRACE("hello-%p\n", this); return !alarm_was_ticking || select(0, readcb, writecb, exceptcb); } void WvStream::terminate_continue_select() { close(); call_ctx = 0; // destroy the context, if necessary } const WvAddr *WvStream::src() const { return NULL; } void WvStream::setcallback(IWvStreamCallback _callfunc) { callfunc = _callfunc; call_ctx = 0; // delete any in-progress WvCont } void WvStream::legacy_callback() { execute(); if (!!callfunc) callfunc(); } IWvStreamCallback WvStream::setreadcallback(IWvStreamCallback _callback) { IWvStreamCallback tmp = readcb; readcb = _callback; return tmp; } IWvStreamCallback WvStream::setwritecallback(IWvStreamCallback _callback) { IWvStreamCallback tmp = writecb; writecb = _callback; return tmp; } IWvStreamCallback WvStream::setexceptcallback(IWvStreamCallback _callback) { IWvStreamCallback tmp = exceptcb; exceptcb = _callback; return tmp; } IWvStreamCallback WvStream::setclosecallback(IWvStreamCallback _callback) { IWvStreamCallback tmp = closecb; if (isok()) closecb = _callback; else { // already closed? notify immediately! closecb = 0; if (!!_callback) _callback(); } return tmp; } void WvStream::unread(WvBuf &unreadbuf, size_t count) { WvDynBuf tmp; tmp.merge(unreadbuf, count); tmp.merge(inbuf); inbuf.zap(); inbuf.merge(tmp); } IWvStream *WvStream::find_by_wsid(WSID wsid) { IWvStream *retval = NULL; if (wsid_map) { map::iterator it = wsid_map->find(wsid); if (it != wsid_map->end()) retval = it->second; } return retval; } wvstreams-4.6.1/streams/tests/0000755000175000001440000000000011260431126015406 5ustar wlachuserswvstreams-4.6.1/streams/tests/logtest.cc0000644000175000001440000000324011036722347017406 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Expected output: * logA<*1>: a message * logB<*2>: b message * logB<*2>: b message * logC<*3>: c message with extra newline * logC<*4>: c2 message * logA: a info message * logA<*1>: a normal message with [07][08] control chars * logA<*1>: a split * logB<*2>: message with stuff * logB: and other stuff. * logC<*3>: another split message. */ #include "wvlogrcv.h" #include int main() { WvLogConsole *rc, *rc2; free(malloc(1)); WvLog a("logA", WvLog::Debug), b("logB", WvLog::Debug2); WvLog c("logC", WvLog::Debug3), c2 = c.split(WvLog::Debug4); // default logging should disable itself while rc or rc2 exist // note: it is usually a bad idea to have more than one WvLogRx for // the same output device! rc = new WvLogConsole(dup(2)); a("a message\n"); rc2 = new WvLogConsole(dup(2)); b("b message\n"); // prints twice -- once for rc, once for rc2 WVRELEASE(rc); c("c message with extra newline\n\n"); // extra newline discarded c2("c2 message\n"); WVRELEASE(rc2); // the second line should be back at WvLog::Debug a(WvLog::Info, "a info message\n"); a("a normal message with \a\b control chars\r\n"); // should display like this: // a split // message with stuff // and other stuff a("a split "); b("message "); b("with stuff "); b(WvLog::Info, "and other stuff.\n"); // should display all on one line c("another split "); c2(WvLog::Debug3, "message."); // should auto-terminate line on exit return 0; } wvstreams-4.6.1/streams/tests/timeouttest.cc0000644000175000001440000000111011036722347020305 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTimeoutStream test. Should only fire once. */ #include "wvtimeoutstream.h" #include "wvlog.h" #include WvLog mylog("timeouttest", WvLog::Info); void timeout() { static int count = 0; count++; mylog("Fire %s\n", count); } int main() { WvTimeoutStream t(1000); t.setcallback(timeout); free(malloc(1)); for (int i = 0; i < 3 && t.isok(); i++) { if (t.select(-1)) t.callback(); } return 0; } wvstreams-4.6.1/streams/tests/prototest.cc0000644000175000001440000000312011036722347017765 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvProtoStream test. Defines a simple language consisting of the commands * and states "one", "two", "three", and "four". See if you can get to state * three! Hours of fun for the whole family! * */ #include "wvprotostream.h" #include "wvlog.h" class ProtoTest : public WvProtoStream { public: ProtoTest(WvStream *_cloned, WvLog *_debuglog); virtual void do_state(Token &t1); virtual void switch_state(int newstate); }; enum States { None = 0, One, Two, Three, Four, }; const char *toks[] = { "quit", "one", "Two", "THREE", "four", NULL }; ProtoTest::ProtoTest(WvStream *_cloned, WvLog *_debuglog) : WvProtoStream(_cloned, _debuglog) { switch_state(One); } void ProtoTest::do_state(Token &t1) { enum States tok = (States)tokanal(t1, toks, false); if (tok < 0) print("ERROR Unknown command (%s)\n", t1.data); else switch_state(tok); } void ProtoTest::switch_state(int newstate) { switch ((States)newstate) { case Three: if (state != Two) { print("ERROR Only from state two!\n"); break; } // else fall through! case One: case Two: case Four: print("GO %s (%s)\n", newstate, toks[newstate]); break; case None: close(); break; } state = newstate; } int main() { WvLog log("prototest"); ProtoTest ps(wvcon, &log); log("Starting...\n"); while (ps.isok()) { if (ps.select(100)) ps.callback(); } ps.cloned = NULL; } wvstreams-4.6.1/streams/tests/daemontest.cc0000644000175000001440000000173611036722347020100 0ustar wlachusers#include "wvdaemon.h" #include "wvlog.h" #ifdef _WIN32 #include "streams.h" #endif class MyWvDaemon : public WvDaemon { public: MyWvDaemon() : WvDaemon("MyWvDaemon", "1.0", wv::bind(&MyWvDaemon::start_cb, this), wv::bind(&MyWvDaemon::run_cb, this), wv::bind(&MyWvDaemon::stop_cb, this)), tick_interval(1), log("MyWvDaemon", WvLog::Info) { args.add_option('i', "interval", "specify tick interval", "SECONDS", tick_interval); } virtual ~MyWvDaemon() {} void start_cb() { log("start callback\n"); } void run_cb() { log("run callback\n"); while (should_run()) { sleep(tick_interval); log("tick!\n"); } } void stop_cb() { log("stop callback\n"); } private: int tick_interval; WvLog log; }; static MyWvDaemon d; int main(int argc, char *argv[]) { return d.run(argc, argv); } wvstreams-4.6.1/streams/tests/simpletest.cc0000644000175000001440000000036311036722347020121 0ustar wlachusers#include "wvstream.h" int main() { wvout->print("copying stdin to stdout...\n"); while (wvin->isok()) { char *line = wvin->blocking_getline(-1); if (line) wvout->print("%s\n", line); else break; } return 0; } wvstreams-4.6.1/streams/tests/closeflushtest.cc0000644000175000001440000000231011036722347020771 0ustar wlachusers#include "wvstreamclone.h" #include "wvfdstream.h" #include "wvlog.h" class SillyStream : public WvFDStream { public: int count; SillyStream() : WvFDStream(1) { count = 0; } virtual size_t uwrite(const void *buf, size_t size) { ++count; fprintf(stderr, "uwrite #%d (%d bytes)\n", count, size); if (count == 2) close(); // pretend we had a socket error return 0; } virtual bool post_select(SelectInfo &si) { fprintf(stderr, "post_select(%d,%d)\n", si.wants.readable, si.wants.writable); return WvFDStream::post_select(si) || true; } virtual void close() { fprintf(stderr, "closing.\n"); WvFDStream::close(); } size_t obu() { return outbuf.used(); } }; int main() { WvLog log("closeflushtest"); log("Starting.\n"); { SillyStream s; s.delay_output(true); s.write("Hello world\n"); log("Said hello -- %s\n", s.obu()); s.delay_output(false); log("Cancelled delay -- %s\n", s.obu()); s.flush_then_close(10000); log("Scheduled close -- %s\n", s.obu()); log("Select...\n"); s.select(100); log("Destroying -- %s\n", s.obu()); } log("Didn't crash.\n"); return 0; } wvstreams-4.6.1/streams/tests/streamdaemontest.cc0000644000175000001440000000500711036722347021307 0ustar wlachusers#include "wvstreamsdaemon.h" #include "wvstreamclone.h" #include "wvtcplistener.h" #include "wvlog.h" const char * NAME = "MyWvStreamsDaemon"; const char * VERSION = "1.0"; const int default_port = 2121; class MyClient : public WvStreamClone { public: MyClient(IWvStream *conn) : WvStreamClone(conn), log("MyClient", WvLog::Info) { uses_continue_select = true; print("Hello I am %s v%s\n", NAME, VERSION); log(WvLog::Notice, "Connection from: %s\n", *conn->src()); } virtual ~MyClient() { log(WvLog::Notice, "Connection to %s closed!\n", *cloned->src()); terminate_continue_select(); } virtual void execute() { // FIXME: Handle carraige returns.. WvStreamClone::execute(); WvString line = blocking_getline(-1); if (!!line) { if (strncmp(line.cstr(), "quit", 4) == 0) { print("Goodbye!\n"); flush_then_close(1000); } print("You said: %s\n", line); } } private: WvLog log; }; class MyListener : public WvTCPListener { public: MyListener(const WvIPPortAddr &addr) : WvTCPListener(addr), log("MyListener", WvLog::Info) { if (isok()) { onaccept(wv::bind(&MyListener::accept_conn, this, _1)); log("Listening for client connections on %s\n", addr); } else log(WvLog::Error, "Failed to listen for client connections on %s\n", addr); } private: void accept_conn(IWvStream *s); WvLog log; }; class MyWvStreamsDaemon : public WvStreamsDaemon { public: MyWvStreamsDaemon() : WvStreamsDaemon("MyWvStreamsDaemon", "1.0", wv::bind(&MyWvStreamsDaemon::cb, this)), port(default_port), log("MyWvStreamsDaemon", WvLog::Info) { args.add_option('p', "port", "specify alternate port number", "PORT", port); } virtual ~MyWvStreamsDaemon() {} void cb() { log("MyWvStreamsDaemon starting..\n", port); WvString bindto("0.0.0.0:%s", port); MyListener *l = new MyListener(bindto); add_stream(l, true, "echo port"); } private: int port; WvLog log; }; static MyWvStreamsDaemon d; void MyListener::accept_conn(IWvStream *s) { log("Incoming TCP connection from %s.\n", *s->src()); d.add_stream(new MyClient(s), true, "MyClient"); } int main(int argc, char *argv[]) { return d.run(argc, argv); } wvstreams-4.6.1/streams/tests/looptest.cc0000644000175000001440000000133011036722347017574 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvLoopback test. Forks and has each process to write to the other. */ #include "wvloopback.h" #include "wvlog.h" int main() { WvLoopback loop; WvLog log("loopy", WvLog::Info); char buf[1024]; size_t size; pid_t pid; pid = fork(); // each line should print twice, but no one guarantees in what order! loop.print("blah\n"); loop.print("weasels!\n"); if (pid) // parent only { while (loop.select(100)) { size = loop.read(buf, sizeof(buf)); log.write(buf, size); } } else _exit(0); // do not run destructors in the child return 0; } wvstreams-4.6.1/streams/tests/globaltest.cc0000644000175000001440000000202011036722347020060 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Tests that the return value of select() on a particular stream is * not affected by the readiness of the global list. */ #include "wvistreamlist.h" #include "wvlog.h" static WvLog mylog("globaltest"); static int count = 0; void callback1(WvStream& s) { ++count; mylog("callback called for s1 (rearming alarm)\n"); s.alarm(0); } void callback2() { mylog("callback called for s2? weird...\n"); } int main() { WvStream s1; WvStream s2; s1.setcallback(wv::bind(callback1, wv::ref(s1))); s2.setcallback(callback2); s1.alarm(0); assert(s1.isok()); assert(s2.isok()); assert(s1.select(0)); assert(!s2.select(0)); WvIStreamList::globallist.append(&s1, false, "s1"); assert(s1.isok()); assert(s2.isok()); assert(s1.select(0)); assert(!s2.select(0)); assert(WvIStreamList::globallist.select(0)); assert(count == 3); mylog("test passed!\n"); } wvstreams-4.6.1/streams/tests/modemtest.cc0000644000175000001440000000252711036722347017735 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvModem test program. Acts almost like a comm program, using WvLog to * display everything received from the modem. It should respond to AT * commands. */ #include "wvmodem.h" #include "wvistreamlist.h" #include "wvlog.h" #include "strutils.h" int main(int argc, char **argv) { WvLog log("modemtest"), modemlog("Rx"); if (argc < 2) { log("usage: modemtest \n"); return 1; } WvModem modem(argv[1], 19200); unsigned char buf[1024]; size_t len; bool last_carrier = false, carrier; WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&modem, false, "modem"); while (modem.isok() && wvcon->isok()) { carrier = modem.carrier(); if (last_carrier != carrier) { log("Modem %s\n", carrier ? "CONNECTED" : "DISCONNECTED" ); last_carrier = carrier; } if (!l.select(100)) continue; if (wvcon->select(0)) { len = wvcon->read(buf, sizeof(buf)); replace_char(buf, '\n', '\r', len); modem.write(buf, len); } else if (modem.select(0)) { len = modem.read(buf, sizeof(buf)); modemlog.write(buf, len); } } if (!modem.isok() && modem.geterr()) log(WvLog::Error, "Modem device: %s\n", modem.errstr()); return 0; } wvstreams-4.6.1/streams/tests/syslogtest.cc0000644000175000001440000000261211036722347020147 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvSyslog test. Sends information to syslog. */ #include "wvsyslog.h" int main() { WvLogRcv *rc, *rc2; free(malloc(1)); WvLog a("logA", WvLog::Debug), b("logB", WvLog::Debug2); WvLog c("logC", WvLog::Debug3), c2 = c.split(WvLog::Debug4); // default logging should disable itself while rc or rc2 exist // note: it is usually a bad idea to have more than one WvLogRx for // the same output device! rc = new WvSyslog("testy", false); a("a message\n"); rc2 = new WvSyslog("testy2", true); b("b message\n"); // prints twice -- once for rc, once for rc2 delete rc; c("c message with extra newline\n\n"); // extra newline discarded c2("c2 message\n"); delete rc2; rc = new WvSyslog("goople", false); // the second line should be back at WvLog::Debug a(WvLog::Info, "a info message\n"); a("a normal message with \a\b control chars\r\n"); // should display like this: // a split // message with stuff // and other stuff a("a split "); b("message "); b("with stuff "); b(WvLog::Info, "and other stuff.\n"); // should display all on one line c("another split "); c2(WvLog::Debug3, "message."); // should auto-terminate line on exit delete rc; return 0; } wvstreams-4.6.1/streams/tests/logbuftest.cc0000644000175000001440000000263411036722347020111 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test of the WvLogBuffer class. The expected output is shown below for each * portion of the test. * */ #include "wvlogbuffer.h" int main() { WvLogBuffer rc(4); free(malloc(1)); WvLog a("logA", WvLog::Debug), b("logB", WvLog::Debug2); WvLog c("logC", WvLog::Debug3), c2 = c.split(WvLog::Debug4); // default logging should disable itself while rc or rc2 exist // note: it is usually a bad idea to have more than one WvLogRx for // the same output device! a("a message\n"); b("b message\n"); // prints twice -- once for rc, once for rc2 c("c message with extra newline\n\n"); // extra newline discarded c2("c2 message\n"); // the second line should be back at WvLog::Debug a(WvLog::Info, "a info message\n"); a("a normal message with \a\b control chars\r\n"); // should display like this: // a split // message with stuff // and other stuff a("a split "); b("message "); b("with stuff "); b(WvLog::Info, "and other stuff.\n"); // should display all on one line c("another split "); c2(WvLog::Debug3, "message."); // should auto-terminate line on display rc.dump(*wvcon); wvcon->print("\n\n"); c2(WvLog::Debug3, " .. and it's wonky! \n"); rc.dump(*wvcon); return 0; } wvstreams-4.6.1/streams/tests/clonetest.cc0000644000175000001440000000111111036722347017720 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test of the WvStreamClone class. Clones stdin and stdout, prints whatever * it receives, and terminates when the stream closes. (Ctrl-D) * */ #include "wvstreamclone.h" int main() { WvStreamClone c(wvcon); while (wvcon->isok() && c.isok()) { char *line = NULL; if (c.select(-1)) line = wvcon->blocking_getline(-1); if (line) c.print("%s\n", line); } wvcon->print("isok: %s/%s\n", wvcon->isok(), c.isok()); c.cloned = NULL; } wvstreams-4.6.1/streams/tests/dailyeventtest.cc0000644000175000001440000000123611036722347020774 0ustar wlachusers #include "wvdailyevent.h" #include "wvconfemu.h" #include "uniinigen.h" int main(int argc, char *argv[]) { WvDailyEvent x(1, 1); //UniConfRoot cfg("ini:/tmp/foo.ini"); time_t now = time(NULL); wvcon->print("Now is %s", ctime(&now)); x.configure(0, 60*24*15, false); time_t next = x.next_event(); wvcon->print("Next event %s seconds, %s", next-now, ctime(&next)); while (1) { if (x.select(100)) { now = time(NULL); wvcon->print("Triggering at %s", ctime(&now)); x.callback(); next = x.next_event(); wvcon->print("Next event %s seconds, %s", next-now, ctime(&next)); } } return 0; } wvstreams-4.6.1/streams/tests/logfiletest.cc0000644000175000001440000000125411036722347020251 0ustar wlachusers#include "wvlogfile.h" #include static bool want_to_die = false; static void sighandler_die(int sig) { want_to_die = true; fprintf(stderr,"Exited on Signal: %d\n",sig); } int main() { signal(SIGTERM, sighandler_die); signal(SIGINT, sighandler_die); signal(SIGXFSZ, sighandler_die); WvLogFile logger("./logtest", WvLog::Debug5); WvLog log("WvLogFile Test", WvLog::Info); while(!want_to_die) { log.print("This is a logging test................................\n"); log.print("Some more testing.....................................\n"); log.print("Even more testing.....................................\n"); } return 0; } wvstreams-4.6.1/streams/tests/contseltest.cc0000644000175000001440000000144711036722347020303 0ustar wlachusers#include #include class Silly : public WvStream { public: static int counter; Silly() { alarm(0); uses_continue_select = true; //personal_stack_size = 16384; WvIStreamList::globallist.append(this, true, "silly"); } virtual void execute() { fprintf(stderr, "#%d\t going into continue select\n", counter++); WvStream::execute(); continue_select(-1); } virtual ~Silly() { terminate_continue_select(); close(); } }; int Silly::counter = 1; int main() { for (int i = 0; i < 20; i++) new Silly(); // we should only print exactly 20 messages for (int i = 0; i < 200; i++) WvIStreamList::globallist.runonce(10); } wvstreams-4.6.1/streams/tests/timetest.cc0000644000175000001440000000260211036722347017564 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTimeStream test. Should take exactly ten seconds to run, but * tests how well the time stream handles being executed in bursts. */ #include "wvtimestream.h" #include "wvlog.h" #include WvLog mylog("timetest", WvLog::Info); bool want_to_quit = false; unsigned int count = 0; void timer_callback(WvStream& s) { if (s.alarm_was_ticking) { mylog("X "); s.alarm(200); } else { if (!(count % 10)) mylog("\n"); mylog("%02s ", count); if (++count >= 100) want_to_quit = true; } } int main() { WvTimeStream t; free(malloc(1)); mylog("Artificial burstiness test - should take exactly 10 seconds\n"); t.setcallback(wv::bind(timer_callback, wv::ref(t))); t.set_timer(100); t.alarm(200); while (!want_to_quit) { if (t.select(-1)) t.callback(); /* * FIXME: It should be okay to sleep more than 100 ms here, * but it isn't. The time stream knows it is late, and will * force the select() timeout to zero to try catching up, but * since we're sleeping outside of it, there's nothing it can * do. If it could call the callback more than once per loop * iteration, it could be fixed, but I'm not sure how to do * that. */ //usleep((1 + (rand() % 500)) * 1000); } return 0; } wvstreams-4.6.1/streams/tests/pamtest.cc0000644000175000001440000000274211036722347017410 0ustar wlachusers#include "wvpam.h" #include "wvcrash.h" int main(int argc, char **argv) { wvcrash_setup(argv[0]); WvString username; WvString password; if (getuid()) { fprintf(stderr, "This test will fail since you are not root\n"); return -1; } if (argc > 0) username = argv[1]; else username = "test"; if (argc > 1) password = argv[2]; else password = "foo"; WvPam pam("Really Dumb"); if (pam.err.isok()) { fprintf(stderr, "\nShould have failed!\n\n"); return 1; } WvPam pam1("Dumb", WvString::null, username, "flummuxednotapassword"); if (pam1.err.isok()) { fprintf(stderr, "\nShould have failed!\n\n"); return 1; } fprintf(stderr, "\nPASSED username and bad password\n\n"); WvPam pam2("Dumber", WvString::null, username, password); if (!pam2.err.isok()) { fprintf(stderr, "\nShould have succeeded!\n\n"); return 1; } fprintf(stderr, "\nPASSED username and good password\n\n"); WvPam pam3("Dumbest", "localhost", username, "notarealpassword"); if (pam3.err.isok()) { fprintf(stderr, "\nShould have failed!\n\n"); return 1; } fprintf(stderr, "\nPASSED RHOST + username and bad password\n\n"); WvPam pam4("Most Dumb", "localhost", username, WvString::null); if (pam4.err.isok()) { fprintf(stderr, "\nShould have failed!\n\n"); return 1; } fprintf(stderr, "\nPASSED RHOST + username and no password\n\n"); } wvstreams-4.6.1/streams/tests/pipetest.cc0000644000175000001440000000177211036722347017572 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvPipe test. Allows you to enter bash commands, runs them, and pipes the * output back to you. */ #include "wvpipe.h" #include "wvlog.h" int main(int argc, char **argv) { const char *_av[] = { "/bin/bash", NULL }; const char **av = (argc < 2) ? _av : (const char **)(argv + 1); WvLog log(av[0]); WvPipe p(av[0], av, true, false, false); wvcon->autoforward(p); p.autoforward(*wvcon); p.write("test string\r\n"); while (p.isok() && wvcon->isok()) { if (p.select(100)) p.callback(); if (wvcon->select(100)) wvcon->callback(); } p.flush_then_close(50000); while (p.isok()) { log("Flushing...\n"); if (p.select(1000)) p.callback(); } if (p.child_exited()) log(WvLog::Notice, "Exited (return code == %s)\n", p.exit_status()); _exit(0); // don't kill the subtask return 0; } wvstreams-4.6.1/streams/wvlogfile.cc0000644000175000001440000001202711202637334016560 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A "Log Receiver" that logs messages to a file */ #include "wvlogfile.h" #include "wvtimeutils.h" #include "wvdiriter.h" #include "strutils.h" #include "wvdailyevent.h" #include "wvfork.h" #include #include #ifndef _WIN32 #include #endif #define MAX_LOGFILE_SZ 1024*1024*100 // 100 Megs #ifdef MACOS #define O_LARGEFILE 00000000 // MAC doesn't need Largefile support, so just make it a dummy value when ORd #endif static time_t gmtoffset() { time_t nowgmt = time(NULL); struct tm gmt = *gmtime(&nowgmt); struct tm local = *localtime(&nowgmt); time_t nowantilocal = mktime(&gmt); // mktime assumes gmt return nowgmt - nowantilocal; } //----------------------------------- WvLogFileBase ------------------ WvLogFileBase::WvLogFileBase(WvStringParm _filename, WvLog::LogLevel _max_level) : WvLogRcv(_max_level), WvFile(_filename, O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644) { fsync_every = fsync_count = 0; } WvLogFileBase::WvLogFileBase(WvLog::LogLevel _max_level) : WvLogRcv(_max_level) { fsync_every = fsync_count = 0; } void WvLogFileBase::_mid_line(const char *str, size_t len) { WvFile::write(str, len); } void WvLogFileBase::_end_line() { if (fsync_every) { fsync_count--; if (fsync_count <= 0 || fsync_count > fsync_every) { fsync_count = fsync_every; //WvFile::print("tick!\n"); WvFile::flush(1000); fsync(getwfd()); } } } #ifdef _WIN32 #define TIME_FORMAT "%b %d %H:%M:%S" // timezones in win32 look stupid #else #define TIME_FORMAT "%b %d %H:%M:%S %Z" #endif void WvLogFileBase::_make_prefix(time_t timenow) { struct tm* tmstamp = localtime(&timenow); char timestr[30]; strftime(×tr[0], 30, TIME_FORMAT, tmstamp); prefix = WvString("%s: %s<%s>: ", timestr, last_source, loglevels[last_level]); prelen = prefix.len(); } //----------------------------------- WvLogFile ---------------------- WvLogFile::WvLogFile(WvStringParm _filename, WvLog::LogLevel _max_level, int _keep_for, bool _force_new_line, bool _allow_append) : WvLogFileBase(_max_level), keep_for(_keep_for), filename(_filename), allow_append(_allow_append) { WvLogRcv::force_new_line = _force_new_line; // start_log(); // don't open log until the first message gets printed } void WvLogFile::_make_prefix(time_t timenow) { if (!WvFile::isok()) start_log(); // struct tm *tmstamp = localtime(&timenow); struct stat statbuf; // Get the filesize if (fstat(getfd(), &statbuf) == -1) statbuf.st_size = 0; // Make sure we are calculating last_day in the current time zone. if (last_day != ((timenow + gmtoffset())/86400) || statbuf.st_size > MAX_LOGFILE_SZ) start_log(); WvLogFileBase::_make_prefix(timenow); } static void trim_old_logs(WvStringParm filename, WvStringParm base, int keep_for) { if (!keep_for) return; WvDirIter i(getdirname(filename), false); for (i.rewind(); i.next(); ) { // if it begins with the base name if (!strncmp(i.ptr()->name, base, strlen(base))) { // and it's older than 'keep_for' days if (i.ptr()->st_mtime < wvtime().tv_sec - keep_for*86400) ::unlink(i.ptr()->fullname); } } } WvString WvLogFile::start_log() { WvFile::close(); int num = 0; struct stat statbuf; time_t timenow = wvtime().tv_sec; last_day = (timenow + gmtoffset()) / 86400; struct tm* tmstamp = localtime(&timenow); char buf[20]; WvString fullname; strftime(buf, 20, "%Y-%m-%d", tmstamp); // Get the next filename do fullname = WvString("%s.%s.%s", filename, buf, num++); while (stat(fullname, &statbuf) != -1 && (statbuf.st_size >= MAX_LOGFILE_SZ || !allow_append)); WvString curname("%s.current", filename); WvString base = getfilename(filename); WvFile::open(fullname, O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644); #ifndef _WIN32 // no symlinks in win32 // Don't delete the file, unless it's a symlink! int sym = readlink(curname, buf, 20); if (sym > 0 || errno == ENOENT) { unlink(curname); symlink(getfilename(fullname), curname); } #endif #ifndef _WIN32 // We fork here because this can be really slow when the directory has // (oh, say 32,000 files) pid_t forky = wvfork(); if (!forky) { // ForkTwiceSoTheStupidThingWorksRight if (!wvfork()) { // Child will Look for old logs and purge them trim_old_logs(filename, base, keep_for); _exit(0); } _exit(0); } // In case a signal is in the process of being delivered... pid_t rv; while ((rv = waitpid(forky, NULL, 0)) != forky) if (rv == -1 && errno != EINTR) break; #else // just do it in the foreground on Windows trim_old_logs(filename, base, keep_for); #endif return fullname; } wvstreams-4.6.1/streams/wvlockdev.cc0000644000175000001440000000523211036722347016572 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Some handy functions to create/remove /var/lock lockfiles. */ #include "wvlockdev.h" #include "wvfile.h" #include "strutils.h" #include #include #include #include #include #include WvLockDev::WvLockDev(WvString _devicename) : devicename(_devicename) { const char *p = strrchr(devicename, '/'); if (p) p++; else p = devicename; lock_count = 0; filename = WvString("/var/lock/LCK..%s", p); } WvLockDev::~WvLockDev() { if (lock_count) { lock_count = 1; unlock(); } } #if USE_LOCKDEV /* use the liblockdev.a locking routines */ #include bool WvLockDev::lock() { if (lock_count) { lock_count++; return true; } if (dev_lock(devicename)) return false; lock_count++; return true; } void WvLockDev::unlock() { if (!lock_count) return; if (!--lock_count) dev_unlock(devicename, getpid()); } #else /* !USE_LOCKDEV -- implement our own locking routines */ // note: this function uses the O_EXCL flag to open(), and thus assumes // that /var/lock is not an NFS-mounted drive (according to the open() man // page, you need to follow a special procedure to ensure successful NFS // locking) // // Actually there may be other race conditions that we should look into. bool WvLockDev::lock() { pid_t pid; if (lock_count) { lock_count++; return true; } WvFile fd(filename, O_RDWR | O_EXCL | O_CREAT, 0644); if (fd.isok()) { // We made a lock file... fd.print("%10s\n", getpid()); } else if (fd.geterr() == EEXIST) { char *inbuf; // Lock file is already there! Check for staleness... sleep(1); // preventing race condition... fd.open(filename, O_RDONLY); //fprintf(stderr, "ok: %d\n", fd.isok()); inbuf = trim_string(fd.blocking_getline(-1)); //fprintf(stderr, "blocking_getline: '%s'\n", inbuf); if (inbuf) pid = atoi(inbuf); else pid = 0; //fprintf(stderr, "pid: '%d'\n", pid); if (pid && pid != -1 && kill(pid, 0) == -1 && errno == ESRCH) { // we can create a lockfile now fd.close(); if (unlink(filename)) return false; // cannot remove lockfile fd.open(filename, O_RDWR | O_EXCL | O_CREAT, 0644); fd.print("%10s\n", getpid()); } else return false; // device already locked } else // some other unexpected error return false; lock_count++; return true; } void WvLockDev::unlock() { if (!lock_count) return; if (!--lock_count) unlink(filename); } #endif /* !USE_LOCKDEV */ wvstreams-4.6.1/streams/wvmodem.cc0000644000175000001440000001477011036722347016253 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * Copyright (C) 1999 Red Hat, Inc. * * Implementation of the WvModem class. Inherits from WvFile, but * handles various important details related to modems, like setting * the baud rate, checking carrier detect, and dropping DTR. * */ #include "wvmodem.h" #include #if HAVE_LINUX_SERIAL_H # include #endif #if ! HAVE_CFMAKERAW static inline void cfmakeraw(struct termios *termios_p) { termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); termios_p->c_oflag &= ~OPOST; termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termios_p->c_cflag &= ~(CSIZE|PARENB); termios_p->c_cflag |= CS8; } #endif struct SpeedLookup { int baud; speed_t speedt; }; static SpeedLookup speeds[] = { #ifdef B460800 {460800, B460800}, #endif #ifdef B230400 {230400, B230400}, #endif {115200, B115200}, { 57600, B57600}, { 38400, B38400}, { 19200, B19200}, { 9600, B9600}, { 4800, B4800}, { 2400, B2400}, { 1200, B1200}, { 300, B300} }; WvModemBase::WvModemBase(int _fd) : WvFile(_fd) { get_real_speed(); } WvModemBase::~WvModemBase() { // nothing needed } int WvModemBase::get_real_speed() { speed_t s; if (!isok()) return 0; tcgetattr( getrfd(), &t ); s = cfgetospeed( &t ); for (unsigned int i = 0; i < sizeof(speeds) / sizeof(*speeds); i++) { if (speeds[i].speedt == s) { baud = speeds[i].baud; break; } } return baud; } void WvModemBase::close() { // no file open, no need to close it } bool WvModemBase::carrier() { return true; } int WvModemBase::speed(int) { return baud; } void WvModemBase::hangup() { int i, oldbaud = baud; if (die_fast || !isok()) return; // politely abort any dial in progress, to avoid locking USR modems. // we should only do this if we have received any response from the modem, // so that WvModemScan can run faster. drain(); write( "\r", 1 ); // FIXME: should be iswritable, but based on the numer of msec params // tossed around I assume modems are very timing-sensitive for (i = 0; !select(200, false, true) && i < 10; i++) write( "\r", 1 ); drain(); // drop DTR for a while, if still online if (carrier()) { cfsetospeed( &t, B0 ); tcsetattr( getrfd(), TCSANOW, &t ); for (i = 0; carrier() && i < 10; i++) usleep( 100 * 1000 ); // raise DTR again, restoring the old baud rate speed(oldbaud); } if (carrier()) { // need to do +++ manual-disconnect stuff write( "+++", 3 ); usleep( 1500 * 1000 ); write( "ATH\r", 4 ); for (i = 0; carrier() && i < 5; i++) usleep( 100 * 1000 ); } } WvModem::WvModem(WvStringParm filename, int _baud, bool rtscts, bool _no_reset) : WvModemBase(), lock(filename), log("WvModem", WvLog::Debug1) { closing = false; baud = _baud; die_fast = false; no_reset = _no_reset; have_old_t = false; if (!lock.lock()) { seterr(EBUSY); return; } // note: if CLOCAL is not set on the modem, open will // block until a carrier detect. Since we have to open the modem to // generate a carrier detect, we have a problem. So we open the modem // nonblocking. It would then be safe to switch to blocking mode, // but that is no longer recommended for WvStream. open(filename, O_RDWR|O_NONBLOCK|O_NOCTTY); if (isok()) setup_modem(rtscts); } WvModem::~WvModem() { close(); } void WvModem::setup_modem(bool rtscts) { if (!isok()) return; if (tcgetattr(getrfd(), &t) || tcgetattr(getrfd(), &old_t)) { closing = true; seterr(errno); return; } have_old_t = true; drain(); #if HAVE_LINUX_SERIAL_H struct serial_struct old_sinfo, sinfo; sinfo.reserved_char[0] = 0; if (ioctl(getrfd(), TIOCGSERIAL, &old_sinfo) < 0) log("Cannot get information for serial port."); else { sinfo = old_sinfo; // Why there are two closing wait timeouts, is beyond me // but there are... apparently the second one is deprecated // but why take a chance... sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE; sinfo.closing_wait2 = ASYNC_CLOSING_WAIT_NONE; if (ioctl(getrfd(), TIOCSSERIAL, &sinfo) < 0) log("Cannot set information for serial port."); } #endif // set up the terminal characteristics. // see "man tcsetattr" for more information about these options. t.c_iflag &= ~(BRKINT | ISTRIP | IUCLC | IXON | IXANY | IXOFF | IMAXBEL); t.c_iflag |= (IGNBRK | IGNPAR); t.c_oflag &= ~(OLCUC); t.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); t.c_cflag |= (CS8 | CREAD | HUPCL | CLOCAL); if(rtscts) t.c_cflag |= CRTSCTS; t.c_lflag &= ~(ISIG | XCASE | ECHO); tcsetattr(getrfd(), TCSANOW, &t); // make sure we leave the modem in CLOCAL when we exit, so normal user // tasks can open the modem without using nonblocking. old_t.c_cflag |= CLOCAL; // Send a few returns to make sure the modem is "good and zonked". if (cfgetospeed(&t) != B0 && !no_reset) { for(int i=0; i<5; i++) { write("\r", 1); usleep(10 * 1000); } } // Set the baud rate to 0 for half a second to drop DTR... cfsetispeed(&t, B0); cfsetospeed(&t, B0); cfmakeraw(&t); tcsetattr(getrfd(), TCSANOW, &t); if (carrier()) usleep(500 * 1000); speed(baud); usleep(10 * 1000); drain(); } void WvModem::close() { if (!closed) { if (!closing) { closing = true; if (!no_reset) hangup(); else { drain(); cfsetospeed(&t, B0); // If this works?? write("\r"); } } closing = true; if (getrfd() >= 0) { tcflush(getrfd(), TCIOFLUSH); if (have_old_t) tcsetattr(getrfd(), TCSANOW, &old_t); tcflush(getrfd(), TCIOFLUSH); } WvFile::close(); closing = false; } } int WvModem::speed(int _baud) { speed_t s = B0; baud = 0; for (unsigned int i = 0; i < sizeof(speeds) / sizeof(*speeds); i++) { if (speeds[i].baud <= _baud) { s = speeds[i].speedt; break; } } cfsetispeed(&t, B0); // auto-match to output speed cfsetospeed(&t, s); tcsetattr(getrfd(), TCSANOW, &t); return get_real_speed(); } int WvModem::getstatus() { if (!isok()) return 0; int status = 0; ioctl(getrfd(), TIOCMGET, &status); return status; } bool WvModem::carrier() { return (getstatus() & TIOCM_CD) ? 1 : 0; } wvstreams-4.6.1/streams/wvtimeoutstream.cc0000644000175000001440000000060511036722347020044 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * See wvtimeoutstream.h. */ #include "wvtimeoutstream.h" WvTimeoutStream::WvTimeoutStream(time_t msec) : ok(true) { alarm(msec); } void WvTimeoutStream::execute() { WvStream::execute(); // reset the alarm if it has gone off if (alarm_was_ticking) ok = false; } wvstreams-4.6.1/streams/wvstreamclone.cc0000644000175000001440000001477711057766345017506 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStreamClone simply forwards all requests to the "cloned" stream. * * NOTE: this file is a pain to maintain, because many of these functions * are almost (but not quite) exactly like the ones in WvStream. If * WvStream changes, you need to change this too. * * See wvstreamclone.h. */ #include "wvstreamclone.h" #include "wvmoniker.h" #ifdef _MSC_VER #pragma warning(disable : 4073) #pragma init_seg(lib) #endif static IWvStream *creator(WvStringParm s, IObject *_obj) { return new WvStreamClone(wvcreate(s, _obj)); } static IWvStream *objcreator(WvStringParm s, IObject *_obj) { // no real need to wrap it #if MUTATE_ISNT_BROKEN return mutate(_obj); #else // HACK: we assume the object is safely of type IWvStream because // xplc's mutate<> function seems not to be working for some reason. return (IWvStream *)_obj; #endif } static WvMoniker clonereg("clone", creator); static WvMoniker objreg("obj", objcreator); static WvMoniker objreg2("", objcreator); WvStreamClone::WvStreamClone(IWvStream *_cloned) : cloned(NULL), my_type("WvStreamClone:(none)") { setclone(_cloned); // the sub-stream will force its own values, if it really wants. force_select(false, false, false); } WvStreamClone::~WvStreamClone() { //fprintf(stderr, "%p destroying: clone is %p\n", this, cloned); setclone(NULL); close(); } void WvStreamClone::noread() { // unlike nowrite(), it is safe to call cloned->noread() immediately. // That will pass the shutdown(SHUT_RD) on to the deepest stream right // away, but won't close anything until all the inbufs are empty. if (cloned) cloned->noread(); WvStream::noread(); } void WvStreamClone::nowrite() { // this sets stop_write. We call cloned->nowrite() in flush_internal() // when our outbuf is flushed (because until then, we *do* want to be // able to write to the clone). if (cloned && !outbuf.used()) cloned->nowrite(); WvStream::nowrite(); } void WvStreamClone::close() { // fprintf(stderr, "%p closing substream %p\n", this, cloned); if (cloned) cloned->setclosecallback(0); // prevent recursion! WvStream::close(); if (cloned) cloned->close(); } bool WvStreamClone::flush_internal(time_t msec_timeout) { if (cloned) { if (stop_write && !outbuf.used()) cloned->nowrite(); return cloned->flush(msec_timeout); } else return true; } size_t WvStreamClone::uread(void *buf, size_t size) { // we use cloned->read() here, not uread(), since we want the _clone_ // to own the input buffer, not the main stream. if (cloned) { size_t len = 0; if (cloned->isok()) len = cloned->read(buf, size); if (len == 0 && !cloned->isok()) close(); return len; } else return 0; } size_t WvStreamClone::uwrite(const void *buf, size_t size) { // we use cloned->write() here, not uwrite(), since we want the _clone_ // to own the output buffer, not the main stream. if (cloned) return cloned->write(buf, size); else return 0; } bool WvStreamClone::isok() const { if (geterr()) return false; if (!cloned) return false; return WvStream::isok(); // don't do this: cloned's closecallback will close us when needed. // return cloned->isok(); } int WvStreamClone::geterr() const { if (WvStream::geterr()) return WvStream::geterr(); if (cloned) return cloned->geterr(); return EIO; } WvString WvStreamClone::errstr() const { if (WvStream::geterr()) return WvStream::errstr(); if (cloned) return cloned->errstr(); return "No child stream!"; } void WvStreamClone::close_callback() { //fprintf(stderr, "streamclone-closecb: %d/%d/%d/%d/%d\n", // stop_read, stop_write, outbuf.used(), inbuf.used(), closed); nowrite(); noread(); // close(); //fprintf(stderr, "streamclone-closecb2: %d/%d/%d/%d/%d\n", // stop_read, stop_write, outbuf.used(), inbuf.used(), closed); } void WvStreamClone::setclone(IWvStream *newclone) { if (cloned) cloned->setclosecallback(0); WVRELEASE(cloned); cloned = newclone; closed = stop_read = stop_write = false; if (cloned) cloned->setclosecallback(wv::bind(&WvStreamClone::close_callback, this)); if (newclone != NULL) my_type = WvString("WvStreamClone:%s", newclone->wstype()); else my_type = "WvStreamClone:(none)"; } void WvStreamClone::pre_select(SelectInfo &si) { SelectRequest oldwant = si.wants; WvStream::pre_select(si); if (cloned && cloned->isok()) { if (!si.inherit_request) { si.wants.readable |= static_cast(readcb); si.wants.writable |= static_cast(writecb); si.wants.isexception |= static_cast(exceptcb); } if (outbuf.used() || autoclose_time) si.wants.writable = true; cloned->pre_select(si); si.wants = oldwant; } } bool WvStreamClone::post_select(SelectInfo &si) { SelectRequest oldwant = si.wants; // This currently always returns false, but we prolly should // still have it here in case it ever becomes useful bool result = WvStream::post_select(si); bool val, want_write; if (cloned && cloned->should_flush()) flush(0); if (cloned && cloned->isok()) { if (!si.inherit_request) { si.wants.readable |= static_cast(readcb); si.wants.writable |= static_cast(writecb); si.wants.isexception |= static_cast(exceptcb); } val = cloned->post_select(si); want_write = si.wants.writable; si.wants = oldwant; // return result if they're looking for writable and we still // have data in outbuf - the writable is for flushing, not for you! if (want_write && outbuf.used()) return result; else if (val && si.wants.readable && read_requires_writable && !read_requires_writable->select(0, false, true)) return result; else if (val && si.wants.writable && write_requires_readable && !write_requires_readable->select(0, true, false)) return result; else return val || result; } return result; } const WvAddr *WvStreamClone::src() const { if (cloned) return cloned->src(); return NULL; } void WvStreamClone::execute() { WvStream::execute(); if (cloned) cloned->callback(); } WvString WvStreamClone::getattr(WvStringParm name) const { WvString ret = WvStream::getattr(name); if (ret.isnull() && cloned) return cloned->getattr(name); return ret; } wvstreams-4.6.1/streams/wvprociter.cc0000644000175000001440000000344411077124114016766 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Process iterator. Iterates through all the processes. * */ #include "wvprociter.h" #include "wvfile.h" #include "wvfileutils.h" #include #include WvProcIter::WvProcIter() : dir_iter("/proc", false, true) { if (!dir_iter.isok()) fprintf(stderr, "WARNING: Can't open /proc: is it mounted?\n"); if (access("/proc/1/.", F_OK) != 0) fprintf(stderr, "WARNING: Can't find /proc/1: is /proc mounted?\n"); } WvProcIter::~WvProcIter() { } bool WvProcIter::isok() const { return dir_iter.isok(); } void WvProcIter::rewind() { dir_iter.rewind(); } bool WvProcIter::next() { for (;;) { if (!dir_iter.next()) return false; if (!wvstring_to_num(dir_iter->name, proc_ent.pid)) continue; proc_ent.exe = wvreadlink(WvString("%s/exe", dir_iter->fullname)); proc_ent.cmdline.zap(); WvFile cmdline_file(WvString("%s/cmdline", dir_iter->fullname), O_RDONLY); while (cmdline_file.isok()) { const char *line = cmdline_file.getline(0, '\0'); if (line == NULL) break; WvString line_str(line); line_str.unique(); proc_ent.cmdline.append(line_str); } cmdline_file.close(); break; } return true; } bool wvkillall(WvStringParm name, int sig) { bool found = false; WvProcIter i; for (i.rewind(); i.next(); ) { if (!i->cmdline.isempty() && !!*i->cmdline.first() && getfilename(*i->cmdline.first()) == name && i->pid > 0) { ::kill(i->pid, sig); found = true; } } return found; } wvstreams-4.6.1/streams/wvprotostream.cc0000644000175000001440000001143211036722347017521 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvProtoStream is a framework that makes it easy to communicate using * common command-response driven protocols. This is supposed to be flexible * enough to handle FTP, HTTP, SMTP, tunnelv, Weaver rcmd, and many others. */ #include "wvprotostream.h" #include "wvlog.h" #include "strutils.h" #include #include WvProtoStream::WvProtoStream(WvStream *_cloned, WvLog *_debuglog) : WvStreamClone(_cloned) { if (_debuglog) logp = new WvLog(_debuglog->split(WvLog::Debug4)); else logp = NULL; log_enable = true; state = 0; } WvProtoStream::~WvProtoStream() { close(); WVRELEASE(logp); } /* Just like a WvStream::uwrite(), but it copies all output to WvLog if * log_enable==true. */ size_t WvProtoStream::uwrite(const void *buf, size_t size) { if (logp && log_enable) { (*logp)("Sent: "); logp->write(buf, size); (*logp)("\n"); } return WvStreamClone::uwrite(buf, size); } WvProtoStream::Token *WvProtoStream::next_token() { static unsigned char whitespace[] = " \t\r\n"; size_t len; // find and remove up to first non-whitespace tokbuf.get(tokbuf.match(whitespace, sizeof(whitespace))); // return a token up to the first whitespace character len = tokbuf.notmatch(whitespace, sizeof(whitespace)); return len ? new Token(tokbuf.get(len), len) : NULL; } WvString WvProtoStream::next_token_str() { Token *t = next_token(); if (!t) return WvString(""); WvString s(t->data); delete t; return s; } WvString WvProtoStream::token_remaining() { tokbuf.put('\0'); return trim_string((char *)tokbuf.get(tokbuf.used())); } /* Default input tokenizer. "line" is NULL-terminated, and individual string * tokens are separated by any amount of whitespace. */ WvProtoStream::TokenList *WvProtoStream::tokenize() { TokenList *tl = new TokenList; Token *t; while ((t = next_token()) != NULL) tl->append(t, true); #if 0 if (logp && log_enable && !tl->isempty()) { (*logp)("Read: "); TokenList::Iter i(*tl); for (i.rewind(); i.next(); ) (*logp)("(%s) ", i.data); (*logp)("\n"); } #endif return tl; } /* convert a TokenList to an array of Token. * The TokenList becomes invalid after this operation! * Remember to free the array afterwards! */ size_t WvProtoStream::list_to_array(TokenList *tl, Token **array) { size_t total = tl->count(), count; assert(array); *array = new Token[total]; TokenList::Iter i(*tl); for (count = 0, i.rewind(); i.next(); count++) { Token &t = *i; (*array)[count].fill((unsigned char *)(const char *)t.data, t.length); } delete tl; return count; } /* Retrieve an input line and parse its first token. * This is the usual high-level interface to the input tokenizer. Remember * to free the array afterwards! * Ths input line is specifically allowed to be a NULL pointer. In that case, * the returned token will be NULL also. */ WvProtoStream::Token *WvProtoStream::tokline(const char *line) { if (!line) return NULL; char *newline = strdup(line); tokbuf.zap(); tokbuf.put(line, strlen(line)); if (logp && log_enable) { if (strlen(trim_string(newline)) > 0) (*logp)("Read: %s\n", trim_string(newline)); } free(newline); return next_token(); } /* returns -1 if t is not in lookup[], or else the index into lookup where * the token was found. */ int WvProtoStream::tokanal(const Token &t, const char **lookup, bool case_sensitive) { assert(lookup); const char **i; for (i = lookup; *i; i++) { if ( (!case_sensitive && !strcasecmp(t.data, *i)) || ( case_sensitive && !strcmp(t.data, *i)) ) return i - lookup; } return -1; } void WvProtoStream::do_state(Token &) { } void WvProtoStream::switch_state(int newstate) { state = newstate; } /* Default execute() function -- process a line of input, and handle it * (based on the current system state) using do_state(). */ void WvProtoStream::execute() { WvStreamClone::execute(); Token *t1 = tokline(getline()); if (t1) { do_state(*t1); delete t1; } } //////////////////////////////////// WvProtoStream::Token WvProtoStream::Token::Token() { // leave empty -- you should call fill() manually later! } WvProtoStream::Token::Token(const unsigned char *_data, size_t _length) { fill(_data, _length); } void WvProtoStream::Token::fill(const unsigned char *_data, size_t _length) { length = _length; data.setsize(length + 1); memcpy(data.edit(), _data, length); data.edit()[length] = 0; } WvProtoStream::Token::~Token() { // 'data' member is freed automatically } wvstreams-4.6.1/streams/wvsubprocqueuestream.cc0000644000175000001440000000160511036722347021101 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A more convenient way to use WvSubProcQueue. See wvsubprocqueuestream.h. */ #include "wvsubprocqueuestream.h" WvSubProcQueueStream::WvSubProcQueueStream(int _maxrunning) : WvSubProcQueue(_maxrunning), log("Subproc Queue", WvLog::Debug5) { alarm(0); } WvSubProcQueueStream::~WvSubProcQueueStream() { } void WvSubProcQueueStream::execute() { int started = WvSubProcQueue::go(); int run = running(), remain = remaining(); if (started || run || remain) log("Started %s processes (%s running, %s waiting)\n", started, run, remain - run); if (!remain) alarm(1000); // nothing is even in the queue; come back later. else if (started) alarm(0); // we're busy; go fast if possible else alarm(100); // no processes were ready *this* time; wait longer } wvstreams-4.6.1/streams/t/0000755000175000001440000000000011260431126014507 5ustar wlachuserswvstreams-4.6.1/streams/t/wvsubprocqueuestream.t.cc0000644000175000001440000000275211036722347021612 0ustar wlachusers#include "wvsubprocqueuestream.h" #include "wvistreamlist.h" #include "wvtest.h" WVTEST_MAIN("wvsubprocqueuestream") { WvIStreamList l; WvSubProcQueueStream q(2); l.append(&q, false, "subproc queue"); const char *argv1[] = { "true", NULL }; const char *argv2[] = { "sleep", "1", NULL }; q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); q.add(NULL, argv2[0], argv2); q.add(NULL, argv1[0], argv1); q.add(NULL, argv2[0], argv2); q.add(NULL, argv1[0], argv1); q.add(NULL, argv1[0], argv1); // this test just makes sure all processes do finish within a reasonable // timeout. There are 11 processes to run, and the stream uses alarm(100) // unless it actually starts a new process, and these processes are pretty // short-lived except for the sleeps, so it should really take no // more than 25 passes or so. But we'll give it more, just in case the // system is loaded down. (Hint: if the alarm() is too short or infinite, // we'll have too many passes or the test will freeze.) int i; for (i = 0; i < 55 && !q.isempty(); i++) { printf("#%d %ld: running with %d total, %d waiting.\n", i, (long)time(NULL), q.remaining(), q.running()); l.runonce(-1); } printf("Done looping with i=%d.\n", i); WVPASS(i < 50); WVPASSEQ(q.remaining(), 0); } wvstreams-4.6.1/streams/t/wvdailyevent.t.cc0000644000175000001440000000510211036722347020010 0ustar wlachusers #include #include "wvtest.h" #include "wvdailyevent.h" // Wait a number of seconds void wait(int num_seconds) { time_t start_time = time(NULL); time_t end_time = start_time + num_seconds; while(end_time > time(NULL)) { // wait! } } bool within_range(int numbertocheck, int numberneeded, int range) { if (numbertocheck - numberneeded < range / 2 || numberneeded - numbertocheck < range / 2) return true; else return false; } class WvDailyEventTest : public WvDailyEvent { public: bool ran; WvDailyEventTest(int first_hour, int num_per_day = 0, bool skip_first = false) : WvDailyEvent(first_hour, num_per_day, skip_first), ran(false) { } virtual void execute() { ran = true; } }; const int NUM_MINUTES_IN_DAY = 1440; WVTEST_MAIN("WvDailyEvent-waits-for-one-time-period Test") { // Get localtime time_t now; struct tm *tnow; now = time(NULL); tnow = localtime(&now); WvDailyEventTest devent(tnow->tm_hour, NUM_MINUTES_IN_DAY); devent.set_num_per_day(NUM_MINUTES_IN_DAY * 12); // every 5 seconds int seconds_passed = 0; while (!devent.ran) devent.runonce(); { if (now != time(NULL)) seconds_passed += time(NULL) - now; now = time(NULL); } WVPASS(within_range(seconds_passed, 5, 2)); } WVTEST_MAIN("configure()-causes-wait-for-one-time-period test") { // Get localtime time_t now; struct tm *tnow; now = time(NULL); tnow = localtime(&now); WvDailyEventTest devent(tnow->tm_hour, NUM_MINUTES_IN_DAY); devent.set_num_per_day(NUM_MINUTES_IN_DAY * 12); // every 5 seconds wait(1); printf("Reconfiguring granularity to once every 10 seconds\n"); devent.set_num_per_day(NUM_MINUTES_IN_DAY * 6); int seconds_passed = 0; while (!devent.ran) devent.runonce(); { if (now != time(NULL)) seconds_passed += time(NULL) - now; now = time(NULL); } WVPASS(within_range(seconds_passed, 10, 2)); } WVTEST_MAIN("Ridiculous values (num_per_day) test") { // Get localtime time_t now; struct tm *tnow; now = time(NULL); tnow = localtime(&now); WvDailyEventTest devent(tnow->tm_hour + 24, NUM_MINUTES_IN_DAY * 10000); devent.set_num_per_day(NUM_MINUTES_IN_DAY * 4933); int seconds_passed = 0; while (!devent.ran) devent.runonce(); { if (now != time(NULL)) seconds_passed += time(NULL) - now; now = time(NULL); } WVPASS(within_range(seconds_passed, 1, 2)); } wvstreams-4.6.1/streams/t/wvstreamclone.t.cc0000644000175000001440000000630611036722347020167 0ustar wlachusers#include "wvtest.h" #include "wvstream.h" #include "wvstreamclone.h" #include "wvloopback.h" #include "wvsocketpair.h" #include "wvmoniker.h" WVTEST_MAIN("close() non-loopiness") { WvStream *s = new WvStream(); WvStreamClone c(s); c.close(); } // noread/nowrite behaviour WVTEST_MAIN("noread/nowrite") { WvStreamClone s(new WvStream); char buf[1024]; s.nowrite(); WVPASS(s.isok()); WVFAIL(s.write(buf, 1024) != 0); s.noread(); WVPASS(!s.isok()); } WVTEST_MAIN("streamclone eof1") { WvStreamClone s(new WvLoopback); s.nowrite(); // done sending s.blocking_getline(1000); WVFAIL(s.isok()); // should be eof now } WVTEST_MAIN("streamclone eof2") { WvStreamClone s(new WvLoopback); s.write("Hello\n"); s.write("nonewline"); s.nowrite(); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "Hello"); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "nonewline"); WVFAIL(s.isok()); } WVTEST_MAIN("streamclone eof3") { WvLoopback *l = new WvLoopback; WvStreamClone s(l); s.write("barfdata", 8); // read the full 8 bytes into the stream's inbuf, but there's no newline, // so return NULL WVFAIL(s.blocking_getline(200)); s.queuemin(0); char buf[8]; WVPASSEQ(s.read(buf, 7), 7); WVPASS(s.isok()); // one block received last time; no EOF yet WVPASS(s.isreadable()); // all the data has been sent, but one byte remains in inbuf l->close(); WVPASS(s.isok()); // no EOF received by wrapper yet! WVPASS(s.isreadable()); WVPASSEQ(s.read(buf, 8), 1); // WVPASS(s.isok()); // STILL no EOF received // WVPASS(s.isreadable()); // get EOF WVPASSEQ(s.read(buf, 8), 0); WVFAIL(s.isok()); // got EOF, so should now definitely be shut down } WVTEST_MAIN("cloned inbuf after read error") { int socks[2]; WVPASS(!wvsocketpair(SOCK_STREAM, socks)); WvStreamClone s1(new WvFdStream(socks[0])), s2(new WvFdStream(socks[1])); s1.print("1\n2\n3\n4\n"); WVPASSEQ(s2.blocking_getline(1000), "1"); s1.close(); WvStreamClone ss2((s2.addRef(), &s2)); WVPASSEQ(ss2.blocking_getline(1000), "2"); s2.close(); // underlying stream goes away WVPASSEQ(ss2.blocking_getline(1000), "3"); WVPASS(ss2.isok()); // inbuf still has data! Don't detect this yet. WVPASSEQ(ss2.blocking_getline(1000), "4"); WVFAIL(ss2.blocking_getline(1000)); WVFAIL(ss2.isok()); } WVTEST_MAIN("WvStreamClone setclone behaviour") { WvStream s1; WvStream s2; WvStreamClone s((s1.addRef(), &s1)); WVPASS(s.isok()); s.noread(); WVPASS(s.isok()); s.nowrite(); WVPASS(!s.isok()); WVPASS(!s1.isok()); WVPASS(s2.isok()); s.setclone((s2.addRef(), &s2)); WVPASS(s.isok()); WVPASS(s2.isok()); s.setclone(NULL); WVPASS(!s.isok()); } WVTEST_MAIN("clone monikers") { IWvStream *e = new WvStream(); e->seterr("test"); IWvStream *s = wvcreate("", e); WVPASS(s); WVPASSEQ(s->errstr(), "test"); delete s; e = new WvStream(); e->seterr("test2"); s = wvcreate("clone:clone:", e); WVPASS(s); WVPASSEQ(s->errstr(), "test2"); delete s; } wvstreams-4.6.1/streams/t/wvprociter.t.cc0000644000175000001440000000212611077124114017467 0ustar wlachusers#include #include #include #include #include WVTEST_MAIN("wvkillall") { WvString exe("/tmp/wvprociter.%s", getpid()); unlink(exe); symlink("/bin/sleep", exe); pid_t child = fork(); if (child == 0) { execl(exe, getfilename(exe), "600", NULL); WVFAIL("execl returned"); } else if (child > 0) { bool killed_child = false; int i; WVPASS(child > 0); for (i=0; i<10; ++i) { if (wvkillall(getfilename(exe), 15)) { killed_child = true; break; } sleep(1); } if (!WVPASS(killed_child)) kill(child, 15); // make sure we don't get stuck pid_t rv; while ((rv = waitpid(child, NULL, 0)) != child) { // in case a signal is in the process of being delivered.. if (rv == -1 && errno != EINTR) break; } WVPASS(rv == child); } else WVFAIL("fork() failed"); unlink(exe); } wvstreams-4.6.1/streams/t/wvencoderstream.t.cc0000644000175000001440000006763111036722347020516 0ustar wlachusers#include "wvtest.h" #include "wvencoderstream.h" #include "wvloopback.h" #include "wvgzip.h" #include #if 1 WVTEST_MAIN("gzip") { //FIXME: this test is associated with bug #6166 static const char in_data[] = "a line of text\n"; /* deflated "a compressed line" */ static const char zin_data[] = { 0x78, 0x9c, 0x4b, 0x54, 0x48, 0xce, 0xcf, 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0x51, 0xc8, 0xc9, 0xcc, 0x4b, 0xe5, 0x02, 0x00, 0x40, 0x15, 0x06, 0x89 }; char *line; WvLoopback loopy; WvEncoderStream gzip((loopy.addRef(), &loopy)); gzip.write(in_data); line = gzip.blocking_getline(1000); WVPASSEQ(line, "a line of text"); WVFAIL(gzip.isreadable()); WvGzipEncoder *inflater = new WvGzipEncoder(WvGzipEncoder::Inflate); gzip.readchain.append(inflater, true); WVFAIL(gzip.isreadable()); gzip.write(zin_data); line = gzip.blocking_getline(1000); WVFAIL(gzip.isreadable()); WVPASSEQ(line, "a compressed line"); WvLoopback loopy2; WvEncoderStream gzip2((loopy.addRef(), &loopy)); gzip2.write(in_data); gzip2.write(zin_data); line = gzip2.blocking_getline(1000, '\n', 1); WVPASSEQ(line, "a line of text"); WvGzipEncoder *inflater2 = new WvGzipEncoder(WvGzipEncoder::Inflate); gzip2.readchain.append(inflater2, true); line = gzip2.blocking_getline(1000); WVPASSEQ(line, "a compressed line"); } #include "wvbufstream.h" #include "wvbase64.h" WVTEST_MAIN("Base64") { char input_stuff[] = "SnVsIDE0IDE3OjI0OjQ4IEVEVDogV3ZFeGNDb25uPCoxPjogQXBwbHlpbmcgcmVzcG9uc2UgZm9y\n" "IGNvbW1hbmQgKkp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVwZGF0ZUl0ZW08KjE+OiBSZWFkaW5nOiA2\n" "MSA2MSA2MSA2MSA2MSA2MSA2MSA2MSA2MSA2MSA2MTEzIDEgSnVsIDE0IDE3OjI0OjQ4IEVEVDog\n" "VXBkYXRlSXRlbTwqMT46IFJlYWQgNjg1IGJ5dGVzIG9mIGJhc2U2NEp1bCAxNCAxNzoyNDo0OCBF\n" "RFQ6IFVwZGF0ZUl0ZW08KjE+OiBXcm90ZSA2NzIgYnl0ZXMgaW50byBkZWNvZGVySnVsIDE0IDE3\n" "OjI0OjQ4IEVEVDogVXBkYXRlSXRlbTwqMT46ICh3cm90ZSBtYXkgYmUgbGVzcyB0aGFuIHJlYWQs\n" "IGR1ZSB0b25ld2xpbmUgdHJpbW1pbmcpSnVsIDE0IDE3OjI0OjQ4IEVEVDogQ2FsZW5kYXJBZGFw\n" "dG9yPCoxPjogVG9sZCB0byB1cGRhdGUgaXRlbToxMDg1MDkzNjk1Lk03MzQ1MjZQMTU0MjhSODgw\n" "NlE3Lm1haUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEV4Y2hhbmdlSXRBZGFwdG9yPCoxPjogQXR0ZW1w\n" "dGluZyB0byBjb252ZXJ0IGZyb21JU084ODU5LTEgdG8gVVRGLThKdWwgMTQgMTc6MjQ6NDggRURU\n" "OiBDYWxlbmRhckFkYXB0b3I8KjE+OiBHb3QgYW4gdXBkYXRlIGZvcjEwODUwOTM2OTUuTTczNDUy\n" "NlAxNTQyOFI4ODA2UTcubWFpSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuVXBkYXRlPCoxPjogRmlu\n" "aXNoZWQgZ2VuZXJpYyBVUERBVEUsIHJldHVybmluZyAxSnVsIDE0IDE3OjI0OjQ4IEVEVDogV3ZF\n" "eGNDb25uPCoxPjogRm91bmQgMCBuZXdsaW5lcyBhbmQgYXRlIHRoZW1KdWwgMTQgMTc6MjQ6NDgg\n" "RURUOiBXdkV4Y0Nvbm48KjE+OiA8PCAoKiBVUERBVEUgcGNvbGlqbi5DYWxlbmRhcklQRi5BcHBv\n" "aW50bWVudCAxMDg1MDkzNjk1Lk0xODQ0NjlQMTU0MjhSNTQyM1ExLm1haSlKdWwgMTQgMTc6MjQ6\n" "NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBBcHBseWluZyByZXNwb25zZSBmb3IgY29tbWFuZCAqSnVs\n" "IDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRlbTwqMT46IFJlYWRpbmc6IDYxIDYxIDYxIDYxIDYx\n" "IDYxIDYxIDYxIDYxIDYxIDYxMTMgMSBKdWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCox\n" "PjogUmVhZCA2ODUgYnl0ZXMgb2YgYmFzZTY0SnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRl\n" "bTwqMT46IFdyb3RlIDY3MiBieXRlcyBpbnRvIGRlY29kZXJKdWwgMTQgMTc6MjQ6NDggRURUOiBV\n" "cGRhdGVJdGVtPCoxPjogKHdyb3RlIG1heSBiZSBsZXNzIHRoYW4gcmVhZCwgZHVlIHRvbmV3bGlu\n" "ZSB0cmltbWluZylKdWwgMTQgMTc6MjQ6NDggRURUOiBDYWxlbmRhckFkYXB0b3I8KjE+OiBUb2xk\n" "IHRvIHVwZGF0ZSBpdGVtOjEwODUwOTM2OTUuTTE4NDQ2OVAxNTQyOFI1NDIzUTEubWFpSnVsIDE0\n" "IDE3OjI0OjQ4IEVEVDogRXhjaGFuZ2VJdEFkYXB0b3I8KjE+OiBBdHRlbXB0aW5nIHRvIGNvbnZl\n" "cnQgZnJvbUlTTzg4NTktMSB0byBVVEYtOEp1bCAxNCAxNzoyNDo0OCBFRFQ6IENhbGVuZGFyQWRh\n" "cHRvcjwqMT46IEdvdCBhbiB1cGRhdGUgZm9yMTA4NTA5MzY5NS5NMTg0NDY5UDE1NDI4UjU0MjNR\n" "MS5tYWlKdWwgMTQgMTc6MjQ6NDggRURUOiBHZW5VcGRhdGU8KjE+OiBGaW5pc2hlZCBnZW5lcmlj\n" "IFVQREFURSwgcmV0dXJuaW5nIDFKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBG\n" "b3VuZCAwIG5ld2xpbmVzIGFuZCBhdGUgdGhlbUp1bCAxNCAxNzoyNDo0OCBFRFQ6IFd2RXhjQ29u\n" "bjwqMT46IDw8ICgqIFVQREFURSBwY29saWpuLkNhbGVuZGFySVBGLkFwcG9pbnRtZW50IDIwMDQw\n" "NjI1VDAyNTAzMFotMjczNDgtMTAwLTEtMkBsb3VmYSlKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4\n" "Y0Nvbm48KjE+OiBBcHBseWluZyByZXNwb25zZSBmb3IgY29tbWFuZCAqSnVsIDE0IDE3OjI0OjQ4\n" "IEVEVDogVXBkYXRlSXRlbTwqMT46IFJlYWRpbmc6IDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYx\n" "IDYxIDYxNjEgNjEgNjEgNjEgMzMgMSBKdWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCox\n" "PjogUmVhZCA5NDkgYnl0ZXMgb2YgYmFzZTY0SnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRl\n" "bTwqMT46IFdyb3RlIDkzMiBieXRlcyBpbnRvIGRlY29kZXJKdWwgMTQgMTc6MjQ6NDggRURUOiBV\n" "cGRhdGVJdGVtPCoxPjogKHdyb3RlIG1heSBiZSBsZXNzIHRoYW4gcmVhZCwgZHVlIHRvbmV3bGlu\n" "ZSB0cmltbWluZylKdWwgMTQgMTc6MjQ6NDggRURUOiBDYWxlbmRhckFkYXB0b3I8KjE+OiBUb2xk\n" "IHRvIHVwZGF0ZSBpdGVtOjIwMDQwNjI1VDAyNTAzMFotMjczNDgtMTAwLTEtMkBsb3VmYUp1bCAx\n" "NCAxNzoyNDo0OCBFRFQ6IEV4Y2hhbmdlSXRBZGFwdG9yPCoxPjogQXR0ZW1wdGluZyB0byBjb252\n" "ZXJ0IGZyb21JU084ODU5LTEgdG8gVVRGLThKdWwgMTQgMTc6MjQ6NDggRURUOiBDYWxlbmRhckFk\n" "YXB0b3I8KjE+OiBHb3QgYW4gdXBkYXRlIGZvcjIwMDQwNjI1VDAyNTAzMFotMjczNDgtMTAwLTEt\n" "MkBsb3VmYUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEdlblVwZGF0ZTwqMT46IEZpbmlzaGVkIGdlbmVy\n" "aWMgVVBEQVRFLCByZXR1cm5pbmcgMUp1bCAxNCAxNzoyNDo0OCBFRFQ6IFd2RXhjQ29ubjwqMT46\n" "IEZvdW5kIDAgbmV3bGluZXMgYW5kIGF0ZSB0aGVtSnVsIDE0IDE3OjI0OjQ4IEVEVDogV3ZFeGND\n" "b25uPCoxPjogPDwgKCogVVBEQVRFIHBjb2xpam4uQ2FsZW5kYXJJUEYuQXBwb2ludG1lbnQgMTA4\n" "ODAzMDY2My5NNzI2MjAzUDIyODhSNjI4MFExLm1haSlKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4\n" "Y0Nvbm48KjE+OiBBcHBseWluZyByZXNwb25zZSBmb3IgY29tbWFuZCAqSnVsIDE0IDE3OjI0OjQ4\n" "IEVEVDogVXBkYXRlSXRlbTwqMT46IFJlYWRpbmc6IDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYx\n" "IDYxIDYxNjEgNjEgNjEgNjEgMjkgMSBKdWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCox\n" "PjogUmVhZCA5NDUgYnl0ZXMgb2YgYmFzZTY0SnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRl\n" "bTwqMT46IFdyb3RlIDkyOCBieXRlcyBpbnRvIGRlY29kZXJKdWwgMTQgMTc6MjQ6NDggRURUOiBV\n" "cGRhdGVJdGVtPCoxPjogKHdyb3RlIG1heSBiZSBsZXNzIHRoYW4gcmVhZCwgZHVlIHRvbmV3bGlu\n" "ZSB0cmltbWluZylKdWwgMTQgMTc6MjQ6NDggRURUOiBDYWxlbmRhckFkYXB0b3I8KjE+OiBUb2xk\n" "IHRvIHVwZGF0ZSBpdGVtOjEwODgwMzA2NjMuTTcyNjIwM1AyMjg4UjYyODBRMS5tYWlKdWwgMTQg\n" "MTc6MjQ6NDggRURUOiBHZW5VcGRhdGU8KjE+OiBGaW5pc2hlZCBnZW5lcmljIFVQREFURSwgcmV0\n" "dXJuaW5nIDFKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBGb3VuZCAwIG5ld2xp\n" "bmVzIGFuZCBhdGUgdGhlbUp1bCAxNCAxNzoyNDo0OCBFRFQ6IFd2RXhjQ29ubjwqMT46IDw8ICgq\n" "IFVQREFURSBwY29saWpuLkNhbGVuZGFySVBGLkFwcG9pbnRtZW50IDIwMDQwNjIzVDA0NTgyM1ot\n" "MzI1NzctMTAwLTEtOUBsb3VmYSlKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBB\n" "cHBseWluZyByZXNwb25zZSBmb3IgY29tbWFuZCAqSnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRl\n" "SXRlbTwqMT46IFJlYWRpbmc6IDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxNjEgNjEg\n" "NjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgNjEgMzcgMSBK\n" "dWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCoxPjogUmVhZCAxODY4IGJ5dGVzIG9mIGJh\n" "c2U2NEp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVwZGF0ZUl0ZW08KjE+OiBXcm90ZSAxODM2IGJ5dGVz\n" "IGludG8gZGVjb2Rlckp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVwZGF0ZUl0ZW08KjE+OiAod3JvdGUg\n" "bWF5IGJlIGxlc3MgdGhhbiByZWFkLCBkdWUgdG9uZXdsaW5lIHRyaW1taW5nKUp1bCAxNCAxNzoy\n" "NDo0OCBFRFQ6IENhbGVuZGFyQWRhcHRvcjwqMT46IFRvbGQgdG8gdXBkYXRlIGl0ZW06MjAwNDA2\n" "MjNUMDQ1ODIzWi0zMjU3Ny0xMDAtMS05QGxvdWZhSnVsIDE0IDE3OjI0OjQ4IEVEVDogRXhjaGFu\n" "Z2VJdEFkYXB0b3I8KjE+OiBBdHRlbXB0aW5nIHRvIGNvbnZlcnQgZnJvbUlTTzg4NTktMSB0byBV\n" "VEYtOEp1bCAxNCAxNzoyNDo0OCBFRFQ6IENhbGVuZGFyQWRhcHRvcjwqMT46IEdvdCBhbiB1cGRh\n" "dGUgZm9yMjAwNDA2MjNUMDQ1ODIzWi0zMjU3Ny0xMDAtMS05QGxvdWZhSnVsIDE0IDE3OjI0OjQ4\n" "IEVEVDogR2VuVXBkYXRlPCoxPjogRmluaXNoZWQgZ2VuZXJpYyBVUERBVEUsIHJldHVybmluZyAx\n" "SnVsIDE0IDE3OjI0OjQ4IEVEVDogV3ZFeGNDb25uPCoxPjogRm91bmQgMCBuZXdsaW5lcyBhbmQg\n" "YXRlIHRoZW1KdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiA8PCAoKiBVUERBVEUg\n" "cGNvbGlqbi5DYWxlbmRhcklQRi5BcHBvaW50bWVudCAxMDg1MDkzNjk1Lk02OTY2NDJQMTU0MjhS\n" "MjE2OVE2Lm1haSlKdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBBcHBseWluZyBy\n" "ZXNwb25zZSBmb3IgY29tbWFuZCAqSnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRlbTwqMT46\n" "IFJlYWRpbmc6IDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxIDYxMTMgMSBKdWwgMTQgMTc6\n" "MjQ6NDggRURUOiBVcGRhdGVJdGVtPCoxPjogUmVhZCA2ODUgYnl0ZXMgb2YgYmFzZTY0SnVsIDE0\n" "IDE3OjI0OjQ4IEVEVDogVXBkYXRlSXRlbTwqMT46IFdyb3RlIDY3MiBieXRlcyBpbnRvIGRlY29k\n" "ZXJKdWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCoxPjogKHdyb3RlIG1heSBiZSBsZXNz\n" "IHRoYW4gcmVhZCwgZHVlIHRvbmV3bGluZSB0cmltbWluZylKdWwgMTQgMTc6MjQ6NDggRURUOiBD\n" "YWxlbmRhckFkYXB0b3I8KjE+OiBUb2xkIHRvIHVwZGF0ZSBpdGVtOjEwODUwOTM2OTUuTTY5NjY0\n" "MlAxNTQyOFIyMTY5UTYubWFpSnVsIDE0IDE3OjI0OjQ4IEVEVDogRXhjaGFuZ2VJdEFkYXB0b3I8\n" "KjE+OiBBdHRlbXB0aW5nIHRvIGNvbnZlcnQgZnJvbUlTTzg4NTktMSB0byBVVEYtOEp1bCAxNCAx\n" "NzoyNDo0OCBFRFQ6IENhbGVuZGFyQWRhcHRvcjwqMT46IEdvdCBhbiB1cGRhdGUgZm9yMTA4NTA5\n" "MzY5NS5NNjk2NjQyUDE1NDI4UjIxNjlRNi5tYWlKdWwgMTQgMTc6MjQ6NDggRURUOiBHZW5VcGRh\n" "dGU8KjE+OiBGaW5pc2hlZCBnZW5lcmljIFVQREFURSwgcmV0dXJuaW5nIDFKdWwgMTQgMTc6MjQ6\n" "NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBGb3VuZCAwIG5ld2xpbmVzIGFuZCBhdGUgdGhlbUp1bCAx\n" "NCAxNzoyNDo0OCBFRFQ6IFd2RXhjQ29ubjwqMT46IDw8ICgqIFVQREFURSBwY29saWpuLkNhbGVu\n" "ZGFySVBGLkFwcG9pbnRtZW50IDEwNzQ4ODM2NzUuTTIyNDQ5N1AzNTg5UjMwNzRRMi5tYWkpSnVs\n" "IDE0IDE3OjI0OjQ4IEVEVDogV3ZFeGNDb25uPCoxPjogQXBwbHlpbmcgcmVzcG9uc2UgZm9yIGNv\n" "bW1hbmQgKkp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVwZGF0ZUl0ZW08KjE+OiBSZWFkaW5nOiA2MSA2\n" "MSA2MSA2MSA2MSA2MSA2MSA2MSA2MSA2MSA2MTEzIDEgSnVsIDE0IDE3OjI0OjQ4IEVEVDogVXBk\n" "YXRlSXRlbTwqMT46IFJlYWQgNjg1IGJ5dGVzIG9mIGJhc2U2NEp1bCAxNCAxNzoyNDo0OCBFRFQ6\n" "IFVwZGF0ZUl0ZW08KjE+OiBXcm90ZSA2NzIgYnl0ZXMgaW50byBkZWNvZGVySnVsIDE0IDE3OjI0\n" "OjQ4IEVEVDogVXBkYXRlSXRlbTwqMT46ICh3cm90ZSBtYXkgYmUgbGVzcyB0aGFuIHJlYWQsIGR1\n" "ZSB0b25ld2xpbmUgdHJpbW1pbmcpSnVsIDE0IDE3OjI0OjQ4IEVEVDogQ2FsZW5kYXJBZGFwdG9y\n" "PCoxPjogVG9sZCB0byB1cGRhdGUgaXRlbToxMDc0ODgzNjc1Lk0yMjQ0OTdQMzU4OVIzMDc0UTIu\n" "bWFpSnVsIDE0IDE3OjI0OjQ4IEVEVDogRXhjaGFuZ2VJdEFkYXB0b3I8KjE+OiBBdHRlbXB0aW5n\n" "IHRvIGNvbnZlcnQgZnJvbUlTTzg4NTktMSB0byBVVEYtOEp1bCAxNCAxNzoyNDo0OCBFRFQ6IENh\n" "bGVuZGFyQWRhcHRvcjwqMT46IEdvdCBhbiB1cGRhdGUgZm9yMTA3NDg4MzY3NS5NMjI0NDk3UDM1\n" "ODlSMzA3NFEyLm1haUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEdlblVwZGF0ZTwqMT46IEZpbmlzaGVk\n" "IGdlbmVyaWMgVVBEQVRFLCByZXR1cm5pbmcgMUp1bCAxNCAxNzoyNDo0OCBFRFQ6IFd2RXhjQ29u\n" "bjwqMT46IEZvdW5kIDAgbmV3bGluZXMgYW5kIGF0ZSB0aGVtSnVsIDE0IDE3OjI0OjQ4IEVEVDog\n" "V3ZFeGNDb25uPCoxPjogPDwgKCogVVBEQVRFIHBjb2xpam4uQ2FsZW5kYXJJUEYuQXBwb2ludG1l\n" "bnQgMTA4NTA5MzY5Ni5NMzQxMzc3UDE1NDI4UjY2MzZRMTIubWFpKUp1bCAxNCAxNzoyNDo0OCBF\n" "RFQ6IFd2RXhjQ29ubjwqMT46IEFwcGx5aW5nIHJlc3BvbnNlIGZvciBjb21tYW5kICpKdWwgMTQg\n" "MTc6MjQ6NDggRURUOiBVcGRhdGVJdGVtPCoxPjogUmVhZGluZzogNjEgNjEgNjEgNjEgNjEgNjEg\n" "NjEgNjEgNjEgNjEgNjE2MSAxNyAxIEp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVwZGF0ZUl0ZW08KjE+\n" "OiBSZWFkIDc1MCBieXRlcyBvZiBiYXNlNjRKdWwgMTQgMTc6MjQ6NDggRURUOiBVcGRhdGVJdGVt\n" "PCoxPjogV3JvdGUgNzM2IGJ5dGVzIGludG8gZGVjb2Rlckp1bCAxNCAxNzoyNDo0OCBFRFQ6IFVw\n" "ZGF0ZUl0ZW08KjE+OiAod3JvdGUgbWF5IGJlIGxlc3MgdGhhbiByZWFkLCBkdWUgdG9uZXdsaW5l\n" "IHRyaW1taW5nKUp1bCAxNCAxNzoyNDo0OCBFRFQ6IENhbGVuZGFyQWRhcHRvcjwqMT46IFRvbGQg\n" "dG8gdXBkYXRlIGl0ZW06MTA4NTA5MzY5Ni5NMzQxMzc3UDE1NDI4UjY2MzZRMTIubWFpSnVsIDE0\n" "IDE3OjI0OjQ4IEVEVDogRXhjaGFuZ2VJdEFkYXB0b3I8KjE+OiBBdHRlbXB0aW5nIHRvIGNvbnZl\n" "cnQgZnJvbUlTTzg4NTktMSB0byBVVEYtOEp1bCAxNCAxNzoyNDo0OCBFRFQ6IENhbGVuZGFyQWRh\n" "cHRvcjwqMT46IEdvdCBhbiB1cGRhdGUgZm9yMTA4NTA5MzY5Ni5NMzQxMzc3UDE1NDI4UjY2MzZR\n" "MTIubWFpSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuVXBkYXRlPCoxPjogRmluaXNoZWQgZ2VuZXJp\n" "YyBVUERBVEUsIHJldHVybmluZyAxSnVsIDE0IDE3OjI0OjQ4IEVEVDogV3ZFeGNDb25uPCoxPjog\n" "Rm91bmQgMCBuZXdsaW5lcyBhbmQgYXRlIHRoZW1KdWwgMTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nv\n" "bm48KjE+OiA8PCAoKiBMSVNUIHBjb2xpam4uQ2FsZW5kYXJJUEYuQXBwb2ludG1lbnQgMylKdWwg\n" "MTQgMTc6MjQ6NDggRURUOiBXdkV4Y0Nvbm48KjE+OiBBcHBseWluZyByZXNwb25zZSBmb3IgY29t\n" "bWFuZCAqSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwqMT46IDMwIGNsaWVudCBpdGVtc0p1\n" "bCAxNCAxNzoyNDo0OCBFRFQ6IEdlbkxpc3Q8KjE+OiAxMDg1MDkzNjk2Lk0zNDEzNzdQMTU0MjhS\n" "NjYzNlExMi5tYWkgaXMgaW50aGUgZXZvIHN0b3JlIGFuZCB0aGUgc2VydmVyIHN0b3JlSnVsIDE0\n" "IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwqMT46IDEwNzQ4ODM2NzUuTTIyNDQ5N1AzNTg5UjMwNzRR\n" "Mi5tYWkgaXMgaW4gdGhlZXZvIHN0b3JlIGFuZCB0aGUgc2VydmVyIHN0b3JlSnVsIDE0IDE3OjI0\n" "OjQ4IEVEVDogR2VuTGlzdDwqMT46IDEwODUwOTM2OTUuTTY5NjY0MlAxNTQyOFIyMTY5UTYubWFp\n" "IGlzIGludGhlIGV2byBzdG9yZSBhbmQgdGhlIHNlcnZlciBzdG9yZUp1bCAxNCAxNzoyNDo0OCBF\n" "RFQ6IEdlbkxpc3Q8KjE+OiAyMDA0MDYyM1QwNDU4MjNaLTMyNTc3LTEwMC0xLTlAbG91ZmEgaXMg\n" "aW50aGUgZXZvIHN0b3JlIGFuZCB0aGUgc2VydmVyIHN0b3JlSnVsIDE0IDE3OjI0OjQ4IEVEVDog\n" "R2VuTGlzdDwqMT46IDIwMDQwNjI1VDAyNTAzMFotMjczNDgtMTAwLTEtMkBsb3VmYSBpcyBpbnRo\n" "ZSBldm8gc3RvcmUgYW5kIHRoZSBzZXJ2ZXIgc3RvcmVKdWwgMTQgMTc6MjQ6NDggRURUOiBHZW5M\n" "aXN0PCoxPjogMTA4NTA5MzY5NS5NMTg0NDY5UDE1NDI4UjU0MjNRMS5tYWkgaXMgaW50aGUgZXZv\n" "IHN0b3JlIGFuZCB0aGUgc2VydmVyIHN0b3JlSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwq\n" "MT46IDEwODUwOTM2OTUuTTczNDUyNlAxNTQyOFI4ODA2UTcubWFpIGlzIGludGhlIGV2byBzdG9y\n" "ZSBhbmQgdGhlIHNlcnZlciBzdG9yZUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEdlbkxpc3Q8KjE+OiAy\n" "MDA0MDYyM1QwNDAxMTRaLTMyNTc3LTEwMC0xLTBAbG91ZmEgaXMgaW50aGUgZXZvIHN0b3JlIGFu\n" "ZCB0aGUgc2VydmVyIHN0b3JlSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwqMT46IDEwODcz\n" "NDA3NDAuTTY4NjIyN1A5NjQ5Ujg3MDJRMC50b3JtZW50IGlzIGludGhlIGV2byBzdG9yZSBhbmQg\n" "dGhlIHNlcnZlciBzdG9yZUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEdlbkxpc3Q8KjE+OiAyMDA0MDYy\n" "NVQwNDU3NDNaLTI5Mzc1LTEwMC0xLTBAbG91ZmEgaXMgaW50aGUgZXZvIHN0b3JlIGFuZCB0aGUg\n" "c2VydmVyIHN0b3JlSnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwqMT46IDEwODUwOTM2OTUu\n" "TTc4NzY3NFAxNTQyOFIzODMxUTgubWFpIGlzIGludGhlIGV2byBzdG9yZSBhbmQgdGhlIHNlcnZl\n" "ciBzdG9yZUp1bCAxNCAxNzoyNDo0OCBFRFQ6IEdlbkxpc3Q8KjE+OiAxMDg0NDc2NzYwLk02MzMy\n" "NTRQODkzUjEwODRRMS5tYWkgaXMgaW4gdGhlZXZvIHN0b3JlIGFuZCB0aGUgc2VydmVyIHN0b3Jl\n" "SnVsIDE0IDE3OjI0OjQ4IEVEVDogR2VuTGlzdDwqMT46IDIwMDQwNjIzVDA0MDEyNVotMzI1Nzct\n" "MTAwLTEtMUBsb3VmYSBpcyBpbnRoZSBldm8gc3RvcmUgYW5kIHRoZSBzZXJ2ZXIgc3RvcmVKdWwg\n" "MTQgMTc6MjQ6NDggRURUOiBHZW5MaXN0PCoxPjogMjAwNDA2MjNUMDQ1NDQxWi0zMjU3Ny0xMDAt\n" "MS03QGxvdWZhIGlzIGludGhlIGV2byBzdG9yZSBhbmQgdGhlIHNlcnZlciBzdG9yZQ==\n"; char output_stuff [] = "Jul 14 17:24:48 EDT: WvExcConn<*1>: Applying response for co" "mmand *Jul 14 17:24:48 EDT: UpdateItem<*1>: Reading: 61 61 6" "1 61 61 61 61 61 61 61 6113 1 Jul 14 17:24:48 EDT: UpdateIte" "m<*1>: Read 685 bytes of base64Jul 14 17:24:48 EDT: UpdateIt" "em<*1>: Wrote 672 bytes into decoderJul 14 17:24:48 EDT: Upd" "ateItem<*1>: (wrote may be less than read, due tonewline tri" "mming)Jul 14 17:24:48 EDT: CalendarAdaptor<*1>: Told to upda" "te item:1085093695.M734526P15428R8806Q7.maiJul 14 17:24:48 E" "DT: ExchangeItAdaptor<*1>: Attempting to convert fromISO8859" "-1 to UTF-8Jul 14 17:24:48 EDT: CalendarAdaptor<*1>: Got an " "update for1085093695.M734526P15428R8806Q7.maiJul 14 17:24:48" " EDT: GenUpdate<*1>: Finished generic UPDATE, returning 1Jul" " 14 17:24:48 EDT: WvExcConn<*1>: Found 0 newlines and ate th" "emJul 14 17:24:48 EDT: WvExcConn<*1>: << (* UPDATE pcolijn.C" "alendarIPF.Appointment 1085093695.M184469P15428R5423Q1.mai)J" "ul 14 17:24:48 EDT: WvExcConn<*1>: Applying response for com" "mand *Jul 14 17:24:48 EDT: UpdateItem<*1>: Reading: 61 61 61" " 61 61 61 61 61 61 61 6113 1 Jul 14 17:24:48 EDT: UpdateItem" "<*1>: Read 685 bytes of base64Jul 14 17:24:48 EDT: UpdateIte" "m<*1>: Wrote 672 bytes into decoderJul 14 17:24:48 EDT: Upda" "teItem<*1>: (wrote may be less than read, due tonewline trim" "ming)Jul 14 17:24:48 EDT: CalendarAdaptor<*1>: Told to updat" "e item:1085093695.M184469P15428R5423Q1.maiJul 14 17:24:48 ED" "T: ExchangeItAdaptor<*1>: Attempting to convert fromISO8859-" "1 to UTF-8Jul 14 17:24:48 EDT: CalendarAdaptor<*1>: Got an u" "pdate for1085093695.M184469P15428R5423Q1.maiJul 14 17:24:48 " "EDT: GenUpdate<*1>: Finished generic UPDATE, returning 1Jul " "14 17:24:48 EDT: WvExcConn<*1>: Found 0 newlines and ate the" "mJul 14 17:24:48 EDT: WvExcConn<*1>: << (* UPDATE pcolijn.Ca" "lendarIPF.Appointment 20040625T025030Z-27348-100-1-2@loufa)J" "ul 14 17:24:48 EDT: WvExcConn<*1>: Applying response for com" "mand *Jul 14 17:24:48 EDT: UpdateItem<*1>: Reading: 61 61 61" " 61 61 61 61 61 61 61 6161 61 61 61 33 1 Jul 14 17:24:48 EDT" ": UpdateItem<*1>: Read 949 bytes of base64Jul 14 17:24:48 ED" "T: UpdateItem<*1>: Wrote 932 bytes into decoderJul 14 17:24:" "48 EDT: UpdateItem<*1>: (wrote may be less than read, due to" "newline trimming)Jul 14 17:24:48 EDT: CalendarAdaptor<*1>: T" "old to update item:20040625T025030Z-27348-100-1-2@loufaJul 1" "4 17:24:48 EDT: ExchangeItAdaptor<*1>: Attempting to convert" " fromISO8859-1 to UTF-8Jul 14 17:24:48 EDT: CalendarAdaptor<" "*1>: Got an update for20040625T025030Z-27348-100-1-2@loufaJu" "l 14 17:24:48 EDT: GenUpdate<*1>: Finished generic UPDATE, r" "eturning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found 0 newlin" "es and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: << (* UPD" "ATE pcolijn.CalendarIPF.Appointment 1088030663.M726203P2288R" "6280Q1.mai)Jul 14 17:24:48 EDT: WvExcConn<*1>: Applying resp" "onse for command *Jul 14 17:24:48 EDT: UpdateItem<*1>: Readi" "ng: 61 61 61 61 61 61 61 61 61 61 6161 61 61 61 29 1 Jul 14 " "17:24:48 EDT: UpdateItem<*1>: Read 945 bytes of base64Jul 14" " 17:24:48 EDT: UpdateItem<*1>: Wrote 928 bytes into decoderJ" "ul 14 17:24:48 EDT: UpdateItem<*1>: (wrote may be less than " "read, due tonewline trimming)Jul 14 17:24:48 EDT: CalendarAd" "aptor<*1>: Told to update item:1088030663.M726203P2288R6280Q" "1.maiJul 14 17:24:48 EDT: GenUpdate<*1>: Finished generic UP" "DATE, returning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found 0" " newlines and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: <<" " (* UPDATE pcolijn.CalendarIPF.Appointment 20040623T045823Z-" "32577-100-1-9@loufa)Jul 14 17:24:48 EDT: WvExcConn<*1>: Appl" "ying response for command *Jul 14 17:24:48 EDT: UpdateItem<*" "1>: Reading: 61 61 61 61 61 61 61 61 61 61 6161 61 61 61 61 " "61 61 61 61 61 61 61 61 61 61 61 61 61 61 37 1 Jul 14 17:24:" "48 EDT: UpdateItem<*1>: Read 1868 bytes of base64Jul 14 17:2" "4:48 EDT: UpdateItem<*1>: Wrote 1836 bytes into decoderJul 1" "4 17:24:48 EDT: UpdateItem<*1>: (wrote may be less than read" ", due tonewline trimming)Jul 14 17:24:48 EDT: CalendarAdapto" "r<*1>: Told to update item:20040623T045823Z-32577-100-1-9@lo" "ufaJul 14 17:24:48 EDT: ExchangeItAdaptor<*1>: Attempting to" " convert fromISO8859-1 to UTF-8Jul 14 17:24:48 EDT: Calendar" "Adaptor<*1>: Got an update for20040623T045823Z-32577-100-1-9" "@loufaJul 14 17:24:48 EDT: GenUpdate<*1>: Finished generic U" "PDATE, returning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found " "0 newlines and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: <" "< (* UPDATE pcolijn.CalendarIPF.Appointment 1085093695.M6966" "42P15428R2169Q6.mai)Jul 14 17:24:48 EDT: WvExcConn<*1>: Appl" "ying response for command *Jul 14 17:24:48 EDT: UpdateItem<*" "1>: Reading: 61 61 61 61 61 61 61 61 61 61 6113 1 Jul 14 17:" "24:48 EDT: UpdateItem<*1>: Read 685 bytes of base64Jul 14 17" ":24:48 EDT: UpdateItem<*1>: Wrote 672 bytes into decoderJul " "14 17:24:48 EDT: UpdateItem<*1>: (wrote may be less than rea" "d, due tonewline trimming)Jul 14 17:24:48 EDT: CalendarAdapt" "or<*1>: Told to update item:1085093695.M696642P15428R2169Q6." "maiJul 14 17:24:48 EDT: ExchangeItAdaptor<*1>: Attempting to" " convert fromISO8859-1 to UTF-8Jul 14 17:24:48 EDT: Calendar" "Adaptor<*1>: Got an update for1085093695.M696642P15428R2169Q" "6.maiJul 14 17:24:48 EDT: GenUpdate<*1>: Finished generic UP" "DATE, returning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found 0" " newlines and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: <<" " (* UPDATE pcolijn.CalendarIPF.Appointment 1074883675.M22449" "7P3589R3074Q2.mai)Jul 14 17:24:48 EDT: WvExcConn<*1>: Applyi" "ng response for command *Jul 14 17:24:48 EDT: UpdateItem<*1>" ": Reading: 61 61 61 61 61 61 61 61 61 61 6113 1 Jul 14 17:24" ":48 EDT: UpdateItem<*1>: Read 685 bytes of base64Jul 14 17:2" "4:48 EDT: UpdateItem<*1>: Wrote 672 bytes into decoderJul 14" " 17:24:48 EDT: UpdateItem<*1>: (wrote may be less than read," " due tonewline trimming)Jul 14 17:24:48 EDT: CalendarAdaptor" "<*1>: Told to update item:1074883675.M224497P3589R3074Q2.mai" "Jul 14 17:24:48 EDT: ExchangeItAdaptor<*1>: Attempting to co" "nvert fromISO8859-1 to UTF-8Jul 14 17:24:48 EDT: CalendarAda" "ptor<*1>: Got an update for1074883675.M224497P3589R3074Q2.ma" "iJul 14 17:24:48 EDT: GenUpdate<*1>: Finished generic UPDATE" ", returning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found 0 new" "lines and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: << (* " "UPDATE pcolijn.CalendarIPF.Appointment 1085093696.M341377P15" "428R6636Q12.mai)Jul 14 17:24:48 EDT: WvExcConn<*1>: Applying" " response for command *Jul 14 17:24:48 EDT: UpdateItem<*1>: " "Reading: 61 61 61 61 61 61 61 61 61 61 6161 17 1 Jul 14 17:2" "4:48 EDT: UpdateItem<*1>: Read 750 bytes of base64Jul 14 17:" "24:48 EDT: UpdateItem<*1>: Wrote 736 bytes into decoderJul 1" "4 17:24:48 EDT: UpdateItem<*1>: (wrote may be less than read" ", due tonewline trimming)Jul 14 17:24:48 EDT: CalendarAdapto" "r<*1>: Told to update item:1085093696.M341377P15428R6636Q12." "maiJul 14 17:24:48 EDT: ExchangeItAdaptor<*1>: Attempting to" " convert fromISO8859-1 to UTF-8Jul 14 17:24:48 EDT: Calendar" "Adaptor<*1>: Got an update for1085093696.M341377P15428R6636Q" "12.maiJul 14 17:24:48 EDT: GenUpdate<*1>: Finished generic U" "PDATE, returning 1Jul 14 17:24:48 EDT: WvExcConn<*1>: Found " "0 newlines and ate themJul 14 17:24:48 EDT: WvExcConn<*1>: <" "< (* LIST pcolijn.CalendarIPF.Appointment 3)Jul 14 17:24:48 " "EDT: WvExcConn<*1>: Applying response for command *Jul 14 17" ":24:48 EDT: GenList<*1>: 30 client itemsJul 14 17:24:48 EDT:" " GenList<*1>: 1085093696.M341377P15428R6636Q12.mai is inthe " "evo store and the server storeJul 14 17:24:48 EDT: GenList<*" "1>: 1074883675.M224497P3589R3074Q2.mai is in theevo store an" "d the server storeJul 14 17:24:48 EDT: GenList<*1>: 10850936" "95.M696642P15428R2169Q6.mai is inthe evo store and the serve" "r storeJul 14 17:24:48 EDT: GenList<*1>: 20040623T045823Z-32" "577-100-1-9@loufa is inthe evo store and the server storeJul" " 14 17:24:48 EDT: GenList<*1>: 20040625T025030Z-27348-100-1-" "2@loufa is inthe evo store and the server storeJul 14 17:24:" "48 EDT: GenList<*1>: 1085093695.M184469P15428R5423Q1.mai is " "inthe evo store and the server storeJul 14 17:24:48 EDT: Gen" "List<*1>: 1085093695.M734526P15428R8806Q7.mai is inthe evo s" "tore and the server storeJul 14 17:24:48 EDT: GenList<*1>: 2" "0040623T040114Z-32577-100-1-0@loufa is inthe evo store and t" "he server storeJul 14 17:24:48 EDT: GenList<*1>: 1087340740." "M686227P9649R8702Q0.torment is inthe evo store and the serve" "r storeJul 14 17:24:48 EDT: GenList<*1>: 20040625T045743Z-29" "375-100-1-0@loufa is inthe evo store and the server storeJul" " 14 17:24:48 EDT: GenList<*1>: 1085093695.M787674P15428R3831" "Q8.mai is inthe evo store and the server storeJul 14 17:24:4" "8 EDT: GenList<*1>: 1084476760.M633254P893R1084Q1.mai is in " "theevo store and the server storeJul 14 17:24:48 EDT: GenLis" "t<*1>: 20040623T040125Z-32577-100-1-1@loufa is inthe evo sto" "re and the server storeJul 14 17:24:48 EDT: GenList<*1>: 200" "40623T045441Z-32577-100-1-7@loufa is inthe evo store and the" " server store"; WvBufStream input_stream; input_stream.write(input_stuff); WvBufStream *buf_stream = new WvBufStream(); WvEncoderStream b64_stream(buf_stream); b64_stream.writechain.append(new WvBase64Decoder, true); b64_stream.auto_flush(false); time_t timeout = 1000; while (true) { WvString s(input_stream.blocking_getline(timeout)); timeout = 10; // only allow a _long_ delay once if (!s) break; b64_stream.write(s); } WvDynBuf outbuf; b64_stream.read(outbuf, 8714); WvString output = outbuf.getstr(); // fprintf(stderr,"We got out: %s\n", output.cstr()); WVPASS(!strcmp(output, output_stuff)); } WVTEST_MAIN("encoderstream eof1") { WvEncoderStream s(new WvLoopback); s.nowrite(); // done sending s.blocking_getline(1000); WVFAIL(s.isok()); // should be eof now } WVTEST_MAIN("encoderstream eof2") { WvEncoderStream s(new WvLoopback); s.write("Hello\n"); s.write("nonewline"); s.nowrite(); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "Hello"); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "nonewline"); WVFAIL(s.isok()); } class ECountStream : public WvStreamClone { public: ECountStream(IWvStream *s) : WvStreamClone(s) { } virtual size_t uread(void *buf, size_t len) { size_t count = WvStreamClone::uread(buf, len); fprintf(stderr, "uread(%d) == %d\n", (int)len, (int)count); return count; } virtual size_t uwrite(const void *buf, size_t len) { size_t count = WvStreamClone::uwrite(buf, len); fprintf(stderr, "uwrite(%d) == %d\n", (int)len, (int)count); return count; } }; class LetterPlusEncoder : public WvEncoder { int incr; public: LetterPlusEncoder(int _incr) { incr = _incr; } protected: virtual bool _encode(WvBuf &in, WvBuf &out, bool flush) { if (!flush) return true; // don't flush unless we have to size_t count = in.used(); unsigned char *c = const_cast(in.get(count)); for (size_t i = 0; i < count; i++) if (isalpha(c[i])) c[i] += incr; out.put(c, count); return true; } }; #if 0 # define new_enc() (new LetterPlusEncoder(1)) # define new_dec() (new LetterPlusEncoder(-1)) #else # define new_enc() (new WvGzipEncoder(WvGzipEncoder::Deflate)) # define new_dec() (new WvGzipEncoder(WvGzipEncoder::Inflate)) #endif // not expected to work if READAHEAD is greater than 1, // because WvEncoderStream::inbuf can't be re-encoded if it's nonempty. // Eventually, we'll take the extra buffering out of plain WvStream; that // should help a bit. In the meantime, always use a readahead of 1 if you // expect to add encoders later. #define READAHEAD (1) static void closecb(int *i) { (*i)++; } WVTEST_MAIN("encoderstream eof3") { int closed = 0; { WvLoopback *l = new WvLoopback; WvEncoderStream s(l); s.writechain.append(new_enc(), true); s.readchain.append(new_dec(), true); s.setclosecallback(wv::bind(&closecb, &closed)); s.write("Hello\n"); s.write("nonewline"); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "Hello"); WVPASS(s.isok()); l->nowrite(); WVPASSEQ(s.blocking_getline(1000), "nonewline"); l->close(); s.runonce(100); WVFAIL(s.isok()); WVPASSEQ(closed, 1); } WVPASSEQ(closed, 1); } WVTEST_MAIN("encoderstream eof4") { WvStream *x = new WvStream; WvEncoderStream s(x); WVPASS(s.isok()); x->close(); WVFAIL(s.isok()); } WVTEST_MAIN("add filters midstream") { WvEncoderStream s(new ECountStream(new WvLoopback)); // if we don't do this, the flush() commands below should be unnecessary. s.delay_output(true); // this allows big kernel read() calls even though we only read one // byte at a time from the *decoded* input stream. Enabling this // tests continue_encode() in WvEncoderChain; otherwise, continue_encode() // wouldn't matter. s.min_readsize = 1024; s.print("First line\n"); WVPASS("1"); s.print("Second line\n"); s.flush(0); WVPASS("2"); s.writechain.prepend(new_enc(), true); s.print("Third line\n"); WVPASS("3a"); s.print("Third line2\n"); s.flush(0); WVPASS("3b"); s.writechain.prepend(new_enc(), true); s.print("Fourth line\n"); WVPASS("4a"); s.print("Fourth line2\n"); s.flush(0); WVPASS("4b"); WVPASSEQ(s.geterr(), 0); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "First line"); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "Second line"); WVPASS("r2"); WVPASSEQ(s.geterr(), 0); s.readchain.append(new_dec(), true); WVPASS("e3"); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "Third line"); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "Third line2"); WVPASSEQ(s.geterr(), 0); WVPASS("r3"); s.readchain.append(new_dec(), true); WVPASS("e4"); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "Fourth line"); WVPASSEQ(s.geterr(), 0); WVPASS("r4a"); s.runonce(1000); WVPASSEQ(s.blocking_getline(1000, '\n', READAHEAD), "Fourth line2"); WVPASSEQ(s.geterr(), 0); WVPASS("r4b"); s.nowrite(); s.noread(); WvDynBuf remainder; s.read(remainder, 1024); WVPASSEQ(remainder.used(), 0); wvcon->print("Remainder: '%s'\n", remainder.getstr()); WVPASSEQ(s.geterr(), 0); wvcon->print("Error code: '%s'\n", s.errstr()); } #endif wvstreams-4.6.1/streams/t/wvgzipstream.t.cc0000644000175000001440000000167711036722347020046 0ustar wlachusers#include "wvtest.h" #include "wvgzipstream.h" #include "wvloopback.h" #ifdef _WIN32 #define ZLIB_DOESNT_HAVE_VALGRIND_ERRORS 1 // win32 has no valgrind! #endif // hmm... this test itself passes now, but the gzip encoder seems to have // valgrind errors. Probably minor, but we shouldn't upset the unit tests. #if ZLIB_DOESNT_HAVE_VALGRIND_ERRORS WVTEST_MAIN("autoflush") { WvGzipStream gzip(new WvLoopback); char buf[1024]; size_t len; // since autoflush is enabled, gzip encoder should always be flushed // right away. gzip.write("x"); for (int i = 0; i < 10; i++) { WVPASS(gzip.select(1000)); len = gzip.read(buf, sizeof(buf)); if (len) break; } WVPASSEQ(len, 1); // when auto_flush is disabled, expect at least a short delay. gzip.auto_flush(false); gzip.write("y"); WVFAIL(gzip.read(buf, sizeof(buf))); gzip.select(1000); WVPASS(gzip.read(buf, sizeof(buf))); } #endif wvstreams-4.6.1/streams/t/wvstream.t.cc0000644000175000001440000003304111077124114017133 0ustar wlachusers#include "wvtest.h" #define __WVSTREAM_UNIT_TEST 1 #include "wvstream.h" #include "wvistreamlist.h" #include "wvcont.h" #include "wvtimeutils.h" class ReadableStream : public WvStream { public: bool yes_readable; ReadableStream() { yes_readable = false; } virtual void pre_select(SelectInfo &si) { WvStream::pre_select(si); if (yes_readable && si.wants.readable) si.msec_timeout = 0; } virtual bool post_select(SelectInfo &si) { bool ret = WvStream::post_select(si); if (yes_readable && si.wants.readable) return true; return ret; } }; class CountStream : public WvStream { public: size_t rcount, wcount; bool yes_writable, block_writes; CountStream() { printf("countstream initializing.\n"); rcount = wcount = 0; yes_writable = block_writes = false; int num = geterr(); printf("countstream error: %d (%s)\n", num, errstr().cstr()); printf("countstream new error: %d\n", geterr()); } virtual ~CountStream() { close(); } virtual size_t uread(void *buf, size_t count) { size_t ret = WvStream::uread(buf, count); rcount += ret; return ret; } virtual size_t uwrite(const void *buf, size_t count) { fprintf(stderr, "I'm uwrite! (%d)\n", count); if (block_writes) return 0; size_t ret = WvStream::uwrite(buf, count); assert(ret == count); wcount += ret; return ret; } virtual bool post_select(SelectInfo &si) { printf("countstream post_select\n"); int ret = WvStream::post_select(si); if (yes_writable && (si.wants.writable || (outbuf_used() && want_to_flush))) return true; else return ret; } }; WVTEST_MAIN("buffered read/write") { WvStream s; char buf[1024]; // buffered reads and writes WVPASS(!s.isreadable()); WVPASS(!s.iswritable()); WVFAIL(s.read(buf, 1024) != 0); WVPASSEQ(s.write(buf, 1024), 1024); WVPASS(!s.iswritable()); WVPASS(!s.isreadable()); WVPASS(s.isok()); // close() shouldn't have to wait to flush buffers, because plain // WvStream has no way to actually flush them. WvTime t1 = wvtime(); s.close(); WvTime t2 = wvtime(); WVPASS(msecdiff(t2, t1) >= 0); WVPASS(msecdiff(t2, t1) < 1000); // after close() WVPASS(!s.isok()); } // error tests WVTEST_MAIN("errors") { WvStream a, b; WVPASS(a.isok()); WVPASS(!a.geterr()); a.seterr(EBUSY); WVPASS(!a.isok()); WVPASSEQ(a.geterr(), EBUSY); WVPASSEQ(a.errstr(), strerror(EBUSY)); b.seterr("I'm glue!"); WVPASS(!b.isok()); WVPASSEQ(b.geterr(), -1); WVPASSEQ(b.errstr(), "I'm glue!"); } // noread/nowrite behaviour WVTEST_MAIN("noread/nowrite") { WvStream s; char buf[1024]; s.nowrite(); WVPASS(s.isok()); WVFAIL(s.write(buf, 1024) != 0); s.noread(); WVPASS(!s.isok()); } // getline tests WVTEST_MAIN("getline") { WvStream s; char buf[1024]; WVPASS(!s.isreadable()); s.inbuf_putstr("a\n b \r\nline"); WVPASS(s.isreadable()); s.noread(); WVPASS(s.isreadable()); WVPASSEQ(s.read(buf, 2), 2); char *line = s.getline(); WVPASS(line); WVPASS(line && !strcmp(line, " b \r")); line = s.getline(); WVPASS(line); WVPASS(line && !strcmp(line, "line")); WVPASS(!s.getline()); WvTime t1 = wvtime(); WVPASS(!s.blocking_getline(500)); WvTime t2 = wvtime(); WVPASS(msecdiff(t2, t1) >= 0); WVPASS(msecdiff(t2, t1) < 400); // noread(). shouldn't actually wait! WvStream t; t.inbuf_putstr("tremfodls\nd\ndopple"); line = t.getline(0, '\n', 20); WVPASS(line && !strcmp(line, "tremfodls")); t.close(); line = t.getline(0, '\n', 20); WVPASS(line && !strcmp(line, "d")); line = t.getline(0, '\n', 20); WVPASS(line && !strcmp(line, "dopple")); // FIXME: avoid aborting the entire test here on a freezeup! #ifndef WIN32 ::alarm(5); // crash after 5 seconds WVPASS(!s.blocking_getline(-1)); ::alarm(0); #endif } // more noread/nowrite behaviour WVTEST_MAIN("more noread/nowrite") { WvStream s; s.inbuf_putstr("hello"); s.write("yellow"); WVPASS(s.isok()); s.nowrite(); WVPASS(s.isok()); s.noread(); WVPASS(s.isok()); WVPASS(s.getline()); WVFAIL(s.blocking_getline(-1)); WVPASS(!s.isok()); } static void val_cb(int *x) { (*x)++; } static void val_icb(int &closeval) { ++closeval; } // callback tests WVTEST_MAIN("callbacks") { int val = 0, closeval = 0; WvStream s; s.setcallback(wv::bind(val_cb, &val)); s.setclosecallback(wv::bind(&val_icb, wv::ref(closeval))); WVPASS(!val); WVPASS(!closeval); s.runonce(0); WVPASS(!val); s.inbuf_putstr("gah"); s.runonce(0); WVPASSEQ(val, 1); // callback works? s.runonce(0); WVPASSEQ(val, 2); // level triggered? s.getline(); WVPASSEQ(val, 2); // but not by getline WVPASS(!closeval); s.inbuf_putstr("blah!"); s.nowrite(); s.noread(); s.runonce(0); WVPASSEQ(val, 3); WVPASS(s.getline()); s.runonce(0); WVPASSEQ(val, 3); WVPASSEQ(closeval, 1); s.runonce(0); WVPASSEQ(closeval, 1); s.close(); WVPASSEQ(closeval, 1); } static void ccb_isok(WvStream &s) { WVPASS(!s.isok()); } WVTEST_MAIN("closecallback-isok") { WvStream s; s.setclosecallback(wv::bind(ccb_isok, wv::ref(s))); s.close(); } // autoforward and various buffer-related tests WVTEST_MAIN("autoforward and buffers") { WvStream a; CountStream b; int val = 0; fprintf(stderr, "a error: '%s'\n", a.errstr().cstr()); fprintf(stderr, "b error: '%s'\n", b.errstr().cstr()); a.autoforward(b); b.setcallback(wv::bind(val_cb, &val)); WVPASS(a.isok()); WVPASS(b.isok()); a.inbuf_putstr("astr"); WVPASSEQ(a.inbuf_used(), 4); a.runonce(0); WVPASS(!a.inbuf_used()); b.runonce(0); WVPASSEQ(val, 0); WVPASSEQ(b.wcount, 4); a.noautoforward(); a.inbuf_putstr("astr2"); a.runonce(0); WVPASSEQ(a.inbuf_used(), 5); WVPASSEQ(b.wcount, 4); // delay_output tests a.autoforward(b); b.delay_output(true); a.runonce(0); WVPASS(!a.inbuf_used()); WVPASSEQ(b.wcount, 4); WVPASSEQ(b.outbuf_used(), 5); b.runonce(0); WVFAIL(!b.outbuf_used()); b.yes_writable = true; b.runonce(0); WVFAIL(!b.outbuf_used()); b.flush(0); WVPASS(!b.outbuf_used()); WVPASSEQ(b.wcount, 4+5); // autoforward() has lower precedence than drain() WVPASS(!a.inbuf_used()); a.inbuf_putstr("googaa"); a.drain(); WVPASSEQ(b.wcount, 4+5); WVPASS(!a.inbuf_used()); // queuemin() works a.inbuf_putstr("phleg"); a.queuemin(2); WVPASS(a.isreadable()); a.queuemin(6); WVFAIL(a.isreadable()); a.drain(); WVFAIL(a.getline()); WVFAIL(a.isreadable()); WVFAIL(!a.inbuf_used()); a.inbuf_putstr("x"); WVPASS(a.isreadable()); WVPASSEQ(a.inbuf_used(), 6); a.drain(); WVPASS(!a.inbuf_used()); } // flush_then_close() WVTEST_MAIN("flush_then_close") { CountStream s; s.block_writes = true; s.write("abcdefg"); WVPASSEQ(s.outbuf_used(), 7); s.flush(0); WVPASSEQ(s.outbuf_used(), 7); s.runonce(0); WVPASSEQ(s.outbuf_used(), 7); s.flush_then_close(20000); WVPASSEQ(s.outbuf_used(), 7); s.runonce(0); WVPASSEQ(s.outbuf_used(), 7); WVPASS(s.isok()); s.yes_writable = true; s.block_writes = false; s.runonce(0); s.runonce(0); WVPASSEQ(s.outbuf_used(), 0); WVFAIL(s.isok()); } // force_select and the globallist WVTEST_MAIN("force_select and globallist") { int val = 0; CountStream s, x; s.yes_writable = x.yes_writable = true; WVFAIL(s.select(0)); WVPASS(s.select(0, false, true)); s.inbuf_putstr("hello"); WVPASS(s.select(0)); WVFAIL(s.select(0, false, false)); s.undo_force_select(true, false, false); WVFAIL(s.select(0)); s.force_select(false, true, false); WVPASS(s.select(0)); s.yes_writable = false; WVFAIL(s.select(0)); x.setcallback(wv::bind(val_cb, &val)); WvIStreamList::globallist.append(&x, false, "countstream"); WVFAIL(s.select(0)); WVPASS(!val); x.inbuf_putstr("yikes"); x.force_select(false, true, false); WVPASS(!s.select(0)); WVPASS(val == 1); WVPASS(!s.select(0)); WVPASS(val == 2); WVPASS(!s.select(0, false, true)); s.yes_writable = true; WVPASS(s.select(0, false, true)); WVPASS(val == 2); s.runonce(); WVPASS(val == 3); WvIStreamList::globallist.unlink(&x); } static int acbi; static void acb() { acbi++; } WVTEST_MAIN("close_and_alarm") { { acbi = 0; WvStream a; a.setcallback(wv::bind(acb)); a.runonce(0); WVPASSEQ(acbi, 0); a.alarm(0); a.runonce(0); WVPASSEQ(acbi, 1); a.runonce(0); WVPASSEQ(acbi, 1); a.alarm(0); a.close(); a.runonce(0); WVPASSEQ(acbi, 2); a.runonce(0); WVPASSEQ(acbi, 2); } { acbi = 0; WvIStreamList l; WvStream a; a.setcallback(wv::bind(acb)); l.append(&a, false, "basic stream"); l.runonce(0); WVPASSEQ(acbi, 0); a.alarm(0); l.runonce(0); WVPASSEQ(acbi, 1); l.runonce(0); WVPASSEQ(acbi, 1); a.alarm(0); a.close(); l.runonce(0); WVPASSEQ(acbi, 2); l.runonce(0); WVPASSEQ(acbi, 2); } } static void cont_cb(WvStream &s, int *x) { int next = 1, sgn = 1; while (s.isok()) { *x = sgn * next; next *= 2; sgn = s.continue_select(0) ? 1 : -1; } } WVTEST_MAIN("continue_select") { WvStream a; int aval = 0; a.uses_continue_select = true; a.setcallback(wv::bind(cont_cb, wv::ref(a), &aval)); a.runonce(0); WVPASS(aval == 0); a.inbuf_putstr("gak"); a.runonce(0); WVPASS(aval == 1); a.runonce(0); WVPASS(aval == 2); a.drain(); WVPASS(aval == 2); a.alarm(-1); a.runonce(0); WVPASS(aval == 2); a.alarm(0); a.runonce(0); WVPASS(aval == -4); a.terminate_continue_select(); } static void cont_once(WvStream &s, int *i) { (*i)++; s.continue_select(10); (*i)++; *i = -*i; } WVTEST_MAIN("continue_select and alarm()") { int i = 1; ReadableStream s; s.uses_continue_select = true; s.setcallback(wv::bind(cont_once, wv::ref(s), &i)); s.yes_readable = true; WVPASSEQ(i, 1); s.runonce(100); WVPASSEQ(i, 2); s.runonce(100); WVPASSEQ(i, -3); s.yes_readable = false; s.runonce(100); WVPASSEQ(i, -3); s.alarm(0); s.runonce(100); WVPASSEQ(i, -2); s.alarm(-1); // disabling the alarm should disable continue_select timeout s.runonce(100); WVPASSEQ(i, -2); s.terminate_continue_select(); } static void seterr_cb(WvStream &s) { s.seterr("my seterr_cb error"); } WVTEST_MAIN("seterr() inside a continuable callback") { WvStream s; s.setcallback(wv::bind(seterr_cb, wv::ref(s))); WVPASS(s.isok()); s.runonce(0); WVPASS(s.isok()); s.alarm(0); s.runonce(5); WVFAIL(s.isok()); WVPASS(s.geterr() == -1); s.terminate_continue_select(); } static void *wvcont_cb(WvStream &s, void *userdata) { int next = 1, sgn = 1; int *val = (int *)userdata; while (s.isok()) { *val = sgn * next; next *= 2; sgn = WvCont::yield() ? 1 : -1; printf("...returned from yield()\n"); } *val = 4242; return NULL; } static void call_wvcont_cb(WvCont *cb, void *userdata) { (*cb)(userdata); } WVTEST_MAIN("continue_select compatibility with WvCont") { WvStream s; int sval = 0; s.uses_continue_select = true; { WvCont cont1(wv::bind(&wvcont_cb, wv::ref(s), _1)); WvCont cont2(cont1), cont3(cont2); s.setcallback(wv::bind(&call_wvcont_cb, &cont3, &sval)); s.inbuf_putstr("gak"); WVPASS(sval == 0); s.runonce(0); WVPASS(sval == 1); s.runonce(0); WVPASS(sval == 2); s.close(); WVPASS(!s.isok()); s.runonce(0); s.setcallback(0); } // the WvCont should have now been destroyed! WVPASS(sval == 4242); } static void alarmcall(WvStream &s, int *userdata) { WVPASS(s.alarm_was_ticking); val_cb(userdata); } // alarm() WVTEST_MAIN("alarm") { int val = 0; WvStream s; s.setcallback(wv::bind(alarmcall, wv::ref(s), &val)); s.runonce(0); WVPASSEQ(val, 0); s.alarm(0); s.runonce(0); WVPASSEQ(val, 1); s.runonce(5); WVPASSEQ(val, 1); s.alarm(-5); WVPASS(s.alarm_remaining() == -1); s.runonce(0); WVPASSEQ(val, 1); s.alarm(100); time_t remain = s.alarm_remaining(); WVPASS(remain > 0); WVPASS(remain <= 100); s.runonce(0); WVPASSEQ(val, 1); s.runonce(10000); WVPASSEQ(val, 2); WVPASSEQ(s.geterr(), 0); printf("alarm remaining: %d\n", (int)s.alarm_remaining()); s.runonce(50); WVPASSEQ(val, 2); printf("alarm remaining: %d\n", (int)s.alarm_remaining()); WvIStreamList l; l.append(&s, false, "alarmer"); s.alarm(1); l.runonce(10); l.runonce(10); l.runonce(10); WVPASSEQ(val, 3); } static int rn = 0; static void rcb2(WvStream &s) { rn++; WVPASS(rn == 2); s.setcallback(0); } static void rcb(WvStream &s) { rn++; WVPASS(rn == 1); s.setcallback(wv::bind(rcb2, wv::ref(s))); WVPASS(rn == 1); //s.continue_select(0); //WVPASS(rn == 1); } WVTEST_MAIN("self-redirection") { WvStream s; s.uses_continue_select = true; s.setcallback(wv::bind(rcb, wv::ref(s))); s.inbuf_putstr("x"); s.runonce(0); s.runonce(0); s.runonce(0); s.runonce(0); WVPASS(rn == 2); s.terminate_continue_select(); } wvstreams-4.6.1/streams/t/wvfile.t.cc0000644000175000001440000000237111036722347016570 0ustar wlachusers#include "wvtest.h" #include "wvfile.h" #include "wvfileutils.h" WVTEST_MAIN("basics") { WvString filename = wvtmpfilename("wvfile-test"); { WvFile f(filename, O_WRONLY | O_CREAT); WVPASS(f.isok()); if (!f.isok()) printf("file error code: '%s'\n", f.errstr().cstr()); WVFAIL(f.isreadable()); WVPASS(f.iswritable()); f.print("line1\n"); f.print("line2"); } { WvFile f(filename, O_RDONLY); WVPASS(f.isok()); WVPASS(f.isreadable()); WVFAIL(f.iswritable()); char buf[1024]; size_t len = f.read(buf, sizeof(buf)-1); WVPASSEQ(len, 11); buf[11] = 0; WVPASSEQ(buf, "line1\nline2"); } { WvFile f(filename, O_RDONLY); WVPASS(f.isok()); WVPASSEQ(f.getline(), "line1"); WVPASSEQ(f.getline(), "line2"); WVPASSEQ(f.getline(), NULL); } unlink(filename); } WVTEST_MAIN("no crlf mangling") { WvString filename = wvtmpfilename("wvfile-test"); WvString s("a\rb\nc\r\nd\n\r"); { FILE *f = fopen(filename, "wb"); if (f) { fwrite(s, strlen(s), 1, f); fclose(f); } } { WvFile f(filename, O_RDONLY); char buf[1024]; size_t len = f.read(buf, sizeof(buf)-1); buf[len] = 0; WVPASSEQ(strlen(buf), strlen(s)); WVPASSEQ(buf, s); } // unlink(filename); } wvstreams-4.6.1/streams/t/wvstreamsdaemon.t.cc0000644000175000001440000001164511077715733020525 0ustar wlachusers#include #include #include #include #include #include #include #include #include #include #include // This needs to be global (and not part of a WvStreamsDaemonTester class) // because the WvStreamsDaemon startup callback below needs to know the name // of the socket to start on. static WvString sock_name; static WvString pidfile; void init() { sock_name = WvString("/tmp/WvStreamsDaemon_test_sock-%s", getpid()); pidfile = WvString("/tmp/WvStreamsDaemon_test_sock-%s.pid", getpid()); } //Callback for the accepted client conection at the server static void client_cb(WvStream &stream) { // Echo everything back const char *line = stream.getline(); if (line) stream.print("Client said: %s\n", line); } static void accept_cb(IWvStream *_conn) { WvUnixConn *conn = (WvUnixConn*)_conn; conn->setcallback(wv::bind(client_cb, wv::ref(*conn))); WvIStreamList::globallist.append(conn, true, "WvUnixConn"); } //Callback function for the daemon static void startup(WvStreamsDaemon *daemon) { signal(SIGPIPE, SIG_IGN); WvUnixListener *listener = new WvUnixListener(sock_name, 0700); listener->onaccept(wv::bind(accept_cb, _1)); daemon->add_die_stream(listener, true, "Listener"); } // Returns a new WvUnixConn connected to name. Returns NULL if it could not // connect. If expect_connect is false, will retry until it cannot connect // (up to num_retries times). WvUnixConn *connect_to_daemon(WvString name, int num_retries, bool expect_connect) { WvUnixConn *conn = NULL; for (int i = 0; i < num_retries ; i++) { WVFAILEQ(WvString("Trying to connect %s \n", i).cstr(), ""); conn = new WvUnixConn(name); bool is_connected = conn->isok(); if (is_connected && expect_connect) { WVPASS("Connected!\n"); break; } WVRELEASE(conn); conn = NULL; if (!is_connected && !expect_connect) { WVPASS("Connection unavailable."); break; } wvdelay(100); } return conn; } void wait_for_child(pid_t child) { int status = 0; int count = 0; int max_tries = 10; pid_t rv; do rv = waitpid(child, &status, 0); while (rv == -1 && errno == EINTR && ++count < max_tries); // Print out any error we received, to aid debugging WVPASSEQ(errno, errno); WVFAILEQ(count, max_tries); WVPASSEQ(rv, child); WVPASS(WIFEXITED(status)); WVPASSEQ(WEXITSTATUS(status), 0); } WVTEST_MAIN("Checking Daemon created") { init(); //Forking the server (daemon) and client processes pid_t child = wvfork(); if (child == 0) { // This is the server process WvStreamsDaemon *daemon = NULL; wvout->print("Running code for server\n"); daemon = new WvStreamsDaemon("Sample Daemon", "0.1", wv::bind(startup, wv::ref(daemon))); daemon->pid_file = pidfile; int fake_argc = 2; char *fake_argv[] = { (char*)"WvStreamsDaemon_nonexistant", (char*)"-d", NULL }; _exit(daemon->run(fake_argc, fake_argv)); } else { // This is the client process wvout->print("Running code for client\n"); WvUnixConn *client = connect_to_daemon(sock_name, 60, true); if (WVPASS(client != NULL)) { client->print("hello\n"); const char *line = client->blocking_getline(10000); wvout->print("Server said: %s\n", line); if (WVPASS(line != NULL)) WVPASSEQ(WvString(line), WvString("Client said: hello")); WVRELEASE(client); client = NULL; } pid_t pid_daemon = -1; WvFile has_pid(pidfile, O_RDONLY); if(WVPASS(has_pid.isok())) { char *line = has_pid.getline(0); if (WVPASS(line)) pid_daemon = atoi(line); } printf("Process id for daemon is %d\n", pid_daemon); if (WVPASS(pid_daemon > 0)) { kill(pid_daemon, SIGTERM); // The daemon won't be available for us to wait on, since it's // done a ForkTwiceSoTheStupidThingWorksRight, and its parent (our // child) has exited anyway. Still, let's attempt to ensure // it gets the signal before continuing. pid_t rv; do rv = waitpid(pid_daemon, NULL, 0); while (rv == -1 && errno == EINTR); WVPASSEQ(errno, ECHILD); WVPASSEQ(rv, -1); } // Clean up our child wait_for_child(child); // connect_to_daemon returns NULL if it couldn't connect (i.e. if the // stream is not isok()); this is what we expect. WvUnixConn *check_conn = connect_to_daemon(sock_name, 60, false); WVFAIL(check_conn); WVRELEASE(check_conn); } } wvstreams-4.6.1/streams/t/wvloopback.t.cc0000644000175000001440000000343311036722347017443 0ustar wlachusers/* * Grossly incomplete test for WvLoopback. */ #include "wvtest.h" #include "wvloopback.h" #ifndef _WIN32 // no fork() in win32 #include WVTEST_MAIN("loopback") { WvLoopback loop; WVPASS(loop.isok()); pid_t pid = fork(); assert(pid >= 0); if (pid == 0) // child: WvTest stuff in here won't work right! { loop.noread(); loop.write("message from child\n"); _exit(0); } // otherwise, we're the parent WVPASS(loop.isok()); loop.nowrite(); WVPASS(loop.isok()); loop.select(1000, true, false); WVPASS(loop.isok()); const char *line = loop.blocking_getline(10000); WVPASS(line); printf("line is '%s'\n", line); pid_t rv; // In case a signal is in the process of being delivered... while ((rv = waitpid(pid, NULL, 0)) != pid) if (rv == -1 && errno != EINTR) break; WVPASSEQ(rv, pid); loop.nowrite(); } #endif WVTEST_MAIN("loopback non-blocking") { { WvLoopback loop; const int nblocks = (1<<8); char buf[1024]; memset(buf, 0, sizeof(buf)); WVPASS(loop.isok()); printf("Writing %d blocks:\n", nblocks); for (int i = 0; i < nblocks; i++) { printf("%d ", i); loop.write(buf, 1024); } printf("\n"); WVPASS(loop.isok()); printf("Closing loop without draining first...\n"); } WVPASS("loop closed okay"); } WVTEST_MAIN("loopback eof1") { WvLoopback s; s.nowrite(); // done sending s.blocking_getline(1000); WVFAIL(s.isok()); // should be eof now } WVTEST_MAIN("loopback eof2") { WvLoopback s; s.write("Hello\n"); s.write("nonewline"); s.nowrite(); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "Hello"); WVPASS(s.isok()); WVPASSEQ(s.blocking_getline(1000), "nonewline"); WVFAIL(s.isok()); } wvstreams-4.6.1/streams/t/wvistreamlist.t.cc0000644000175000001440000000315111077124114020177 0ustar wlachusers#include "wvistreamlist.h" #include "wvtest.h" #include "wvloopback.h" #include "wvtimeutils.h" #ifdef _WIN32 #include "streams.h" #endif static void cb(int *x) { (*x)++; } WVTEST_MAIN("spinning list") { int scount = 0, lcount = 0; WvStream s; s.setcallback(wv::bind(cb, &scount)); WvIStreamList l; l.setcallback(wv::bind(cb, &lcount)); l.append(&s, false, "stream"); l.alarm(0); l.runonce(0); WVPASSEQ(scount, 0); WVPASSEQ(lcount, 1); scount = lcount = 0; s.alarm(0); l.runonce(0); WVPASSEQ(scount, 1); WVPASSEQ(lcount, 1); scount = lcount = 0; s.alarm(0); l.alarm(0); l.runonce(0); WVPASSEQ(scount, 1); WVPASSEQ(lcount, 1); scount = lcount = 0; l.runonce(0); WVPASSEQ(scount, 0); WVPASSEQ(lcount, 0); } WVTEST_MAIN("spinning list 2") { int scount = 0, lcount = 0; WvLoopback s; s.setcallback(wv::bind(cb, &scount)); WvIStreamList l; l.setcallback(wv::bind(cb, &lcount)); l.append(&s, false, "stream"); s.runonce(0); WVPASSEQ(scount, 0); WVPASSEQ(lcount, 0); l.alarm(0); l.runonce(0); WVPASSEQ(scount, 0); WVPASSEQ(lcount, 1); scount = lcount = 0; s.write("x"); l.runonce(5000); s.drain(); WVPASSEQ(scount, 1); WVPASSEQ(lcount, 1); scount = lcount = 0; s.write("x"); l.alarm(0); wvdelay(100); l.runonce(5000); s.drain(); WVPASSEQ(scount, 1); WVPASSEQ(lcount, 1); scount = lcount = 0; l.runonce(0); WVPASSEQ(scount, 0); WVPASSEQ(lcount, 0); } wvstreams-4.6.1/streams/t/wvlockfile.t.cc0000644000175000001440000000037211036722436017437 0ustar wlachusers#include "wvfileutils.h" #include "wvlockfile.h" #include "wvtest.h" WVTEST_MAIN("lockfile blank") { WvString lockname("/tmp/stupidlock.%s.tmp", getpid()); ftouch(lockname); WvLockFile lockfile(lockname); WVPASS(lockfile.lock()); } wvstreams-4.6.1/streams/t/wvatomicfile.t.cc0000644000175000001440000000435211202637334017762 0ustar wlachusers/* FIXME: horribly incomplete */ #include "wvtest.h" #include "wvatomicfile.h" #ifdef MACOS #include #endif WVTEST_MAIN("atomic file test") { struct stat st; WvString filename("/tmp/testfile.%s", getpid()); unlink(filename); WVPASS(lstat(filename, &st) == -1); WvAtomicFile g(filename, O_WRONLY|O_CREAT|O_TRUNC, 0660); WVPASS(g.iswritable()); WVPASS(g.isok()); WVPASS(lstat(filename, &st) == -1); g.print("Hello there"); WVPASS(lstat(filename, &st) == -1); g.close(); WVPASS(lstat(filename, &st) == 0); WvFile f(filename, O_RDONLY); WVPASS(f.isok()); WVPASS(f.getline(-1) == WvString("Hello there")); unlink(filename); } WVTEST_MAIN("atomic file chmod") { WvString filename("/tmp/testfile.%s", getpid()); struct stat st; mode_t old_umask = umask(022); unlink(filename); WvAtomicFile g(filename, O_WRONLY|O_CREAT|O_TRUNC, 0660); WVPASS(g.isok()); WVPASS(fstat(g.getfd(), &st) == 0 && (st.st_mode & 0777) == 0640); WVPASS(g.chmod(0666)); WVPASS(fstat(g.getfd(), &st) == 0 && (st.st_mode & 0777) == 0666); g.close(); WVFAIL(g.chmod(0600)); WVPASS(lstat(filename, &st) == 0 && (st.st_mode & 0777) == 0666); umask(old_umask); unlink(filename); } WVTEST_MAIN("atomic errors") { WvString filename("/this/directory/had/better/not/exist/filename.txt"); WvAtomicFile f(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); WVFAIL(f.isok()); WVPASSEQ(f.geterr(), ENOENT); printf("error string: '%s'\n", f.errstr().cstr()); } #if 0 // This only works as root... WVTEST_MAIN("atomic file chown") { WvString filename("/tmp/testfile.%s", getpid()); struct stat st; WvAtomicFile g(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); WVPASS(g.isok()); WVPASS(fstat(g.getfd(), &st) == 0 && st.st_uid == getuid() && st.st_gid == getgid()); WVPASS(g.chown(getuid()+1, getgid()+1)); WVPASS(fstat(g.getfd(), &st) == 0 && st.st_uid == getuid()+1 && st.st_gid == getgid()+1); g.close(); WVFAIL(g.chmod(0600)); WVPASS(lstat(filename, &st) == 0 && st.st_uid == getuid()+1 && st.st_gid == getgid()+1); unlink(filename); } #endif wvstreams-4.6.1/streams/t/fileutils.t.cc0000644000175000001440000000667011077124114017273 0ustar wlachusers/* FIXME: horribly incomplete */ #include #include #include #include "wvtest.h" #include "wvfile.h" #include "wvfileutils.h" #ifndef _WIN32 // file permissions are pointless in win32 WVTEST_MAIN("wvchmod test") { mode_t oldmode = 0600; mode_t newmode = 0744; mode_t diroldmode = 0700; mode_t dirnewmode = 0744; WvString basedir("/tmp/wvchmod-test-%s", getpid()); WVPASS(wvmkdir(basedir, 0775) != -1); WvString testfile("%s/file", basedir); WvFile f(testfile, O_CREAT | O_RDWR, oldmode); WVPASS(f.isok()); f.close(); // check that the file's initial perms are correct struct stat st; WVPASS(stat(testfile, &st) != -1); WVPASSEQ((st.st_mode & 0777), oldmode); // ensure that we can create the symlink WvString testlink("%s/link", basedir); WVPASS(symlink(testfile, testlink) != -1); // test that chmodding a symlink does not touch the file WVPASS(wvchmod(testlink, newmode) == -1); WVPASS(stat(testfile, &st) != -1); WVPASSEQ((st.st_mode & 0777), oldmode); unlink(testlink); // test that chmodding the file works WVPASS(wvchmod(testfile, newmode) != -1); WVPASS(stat(testfile, &st) != -1); WVPASSEQ((st.st_mode & 0777), newmode); // add a test dir and make sure perms are good WvString testdir("%s/dir", basedir); WVPASS(wvmkdir(testdir, diroldmode) != -1); WVPASS(stat(testdir, &st) != -1); WVPASSEQ((st.st_mode & 0777), diroldmode); WvString testdlink("%s/dlink", basedir); WVPASS(symlink(testdir, testdlink) != -1); // test that chmodding a symlink does not touch the dir WVPASS(wvchmod(testdlink, dirnewmode) == -1); WVPASS(stat(testdir, &st) != -1); WVPASSEQ((st.st_mode & 0777), diroldmode); unlink(testdlink); // test that chmodding the dir works WVPASS(wvchmod(testdir, dirnewmode) != -1); WVPASS(stat(testdir, &st) != -1); WVPASSEQ((st.st_mode & 0777), dirnewmode); unlink(testfile); rmdir(testdir); rmdir(basedir); } #endif // !_WIN32 #ifndef _WIN32 // no symbolic links in win32 WVTEST_MAIN("wvreadlink") { WvString symlink_name("/tmp/wvreadlink.%s", getpid()); unlink(symlink_name); WVPASS(wvreadlink(symlink_name).isnull()); const char *old_paths[] = { "foo", "/usr/bin/cat", "wioaeboiabetiobawioebtgoaiwbegiouabvgibasdjbgaulsdbguavweovgaiuvgasuidvgiouavegiawoevgao;usvgo;uvaweo;gvawoevgaiowveeeeeeeeeeeeeeeeeeeeeeeeee;vgsdkkkkkkkkkkkkkkkkkkkkkkkjaasbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'ooooooooooaskklsdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddwaaaaaaaaaaabgopppppbooooooawgbopppppeeeboopasdopfbopasopdbfasbopdfoasopdbfasbdpfasdbfpoabsdopfbaopsbdfpasbdopfbapsobdfpoasbdopfbaspodbfpasodbfopasbopdfasdfabsdbopfasdfoasdfbopasopdfabsopdfabopsdfabopsdfaopsdfasdfpboooooooooasdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddpasdfasdpopsbdfpbasopdbfpaosdbfopasbdfopabsdfobasopdbfapsodbfpasbdfpaosbdfopabsdpfobasopdbfapsobfoasbdpfasbdpfbasopdbfpasbdfpoasbdfpabsdopfbasopdbfpaosdbfpaosbdfpbaspdbfopasbdfpasbdfopasbdfpabsdpfbaspdfbaspodbfopasdbfpoasbdfpasbdpfbaspdbfaspodbfpoasbdpfobapsdbfaopsdfbasdpofbaspdfpqwepfobapwoebfapwebfapwbefp", NULL }; const char **old_path; for (old_path = &old_paths[0]; *old_path; ++old_path) { symlink(*old_path, symlink_name); WVPASSEQ(wvreadlink(symlink_name), *old_path); unlink(symlink_name); } } #endif // !_WIN32 wvstreams-4.6.1/streams/t/wvlogbuffer.t.cc0000644000175000001440000000172211036722347017623 0ustar wlachusers#include "wvtest.h" #include "wvlogbuffer.h" #include "wvlog.h" void loganddelete() { WvLog loggy ("temporary log"); loggy.uwrite("msg", 3); } // loggy gets deleted when this returns WVTEST_MAIN("test for accessing free'd memory in wvlogbuffer") { // Create wvlogbuffer to recieve messages WvLogBuffer *logbuf = new WvLogBuffer(15, WvLog::Debug3); loganddelete(); // Allocate a big string to overwrite the deleted WvLog with junk WvString a("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); logbuf->end_line(); WVPASS(1); // If you get this far, you win! } wvstreams-4.6.1/streams/t/wvfdstream.t.cc0000644000175000001440000001760411036722347017463 0ustar wlachusers#include #ifdef _WIN32 #include #else #include #endif #include #include "wvfdstream.h" #include "wvfile.h" #include "wvfileutils.h" #include "wvistreamlist.h" #include "wvlog.h" #include "wvsocketpair.h" #include "wvstreamclone.h" #include "wvtest.h" #include "wvfileutils.h" //FIXME: absolutely simple simple test right now, built from closeflushtest // BEGIN closeflushtest.cc definition class SillyStream : public WvFDStream { public: int count; SillyStream() : WvFDStream(dup(1)) { count = 0; } virtual size_t uwrite(const void *buf, size_t size) { ++count; // fprintf(stderr, "uwrite #%d (%d bytes)\n", count, size); if (count == 2) close(); // pretend we had a socket error return 0; } virtual bool post_select(SelectInfo &si) { // fprintf(stderr, "post_select(%d,%d)\n", // si.wants.readable, si.wants.writable); return WvFDStream::post_select(si) || true; } virtual void close() { // fprintf(stderr, "closing.\n"); WvFDStream::close(); } size_t obu() { return outbuf.used(); } }; // END closeflushtest.cc definition WVTEST_MAIN("closeflushtest.cc") { { SillyStream s; s.delay_output(true); s.write("Hello world\n"); WVPASS(s.obu() == 12); s.delay_output(false); WVPASS(s.obu() == 12); s.flush_then_close(10000); WVPASS(s.obu() == 12); s.select(100); WVPASS(s.obu() == 0); } } WVTEST_MAIN("open and close with null FDs") { WvFDStream fdstream; WVPASS(fdstream.getrfd() == -1); WVPASS(fdstream.getwfd() == -1); WVPASS(fdstream.getfd() == -1); WVFAIL(fdstream.isok()); WVFAIL(fdstream.select(1, true, false)); WVFAIL(fdstream.select(1, false, true)); WVFAIL(fdstream.select(1, true, true)); WVFAIL(fdstream.iswritable()); WVFAIL(fdstream.isreadable()); } WVTEST_MAIN("stdout clone") { { WvFDStream s(dup(1)); WVPASS(s.isok()); WVPASSEQ(s.geterr(), 0); s.print("This is stdout!\n"); WVPASS(s.isok()); WVPASSEQ(s.geterr(), 0); s.close(); WVFAIL(s.isok()); WVPASSEQ(s.geterr(), 0); } { int fd = dup(1); WvFDStream s(fd); WVPASS(s.isok()); WVPASSEQ(s.geterr(), 0); s.print("Boink!\n"); WVPASS(s.isok()); WVPASSEQ(s.geterr(), 0); close(fd); s.print("this will write to an invalid fd\n"); WVFAIL(s.isok()); WVPASSEQ(s.geterr(), EBADF); } } WVTEST_MAIN("open, read, write and close between two WvFDStreams") { ::unlink("wvfdstream.t.tmp"); // create temporary and empty file for testing printf("Trying to open wvfdstream.t.tmp to write\n"); int file1 = open("wvfdstream.t.tmp", O_CREAT | O_TRUNC | O_WRONLY, 0666); if (!WVPASS(file1 >= 0)) printf("Are you sure we can write to wvfdstream.t.tmp?\n"); printf("Trying to open wvfdstream.t.tmp to read\n"); int file2 = open("wvfdstream.t.tmp", O_CREAT | O_TRUNC | O_RDONLY, 0666); if (!WVPASS(file2 >= 0)) printf("Are you sure we can read from wvfdstream.t.tmp?\n"); WvFDStream writestream(-1, file1); WvFDStream readstream(file2, -1); // writestream is not-readable and writeable WVPASS(writestream.iswritable()); WVFAIL(writestream.isreadable()); // readstream is readable and not-writeable WVPASS(readstream.isreadable()); WVFAIL(readstream.iswritable()); // Writing to file WVPASSEQ(writestream.write("Bonjour, je m'appelle writestream\n"), 34); WVPASSEQ(writestream.write("Bonjour! Je m'appelle writestream"), 33); WVPASS(writestream.iswritable()); WVPASS(readstream.isreadable()); char *buf = new char[256]; memset(buf, 0, 256); // Reading from file WVPASS(writestream.select(0, false, true)); WVPASS(1); WvString line(readstream.blocking_getline(-1)); WVPASSEQ(line, "Bonjour, je m'appelle writestream"); WVPASS(readstream.isreadable()); WVPASSEQ(readstream.read(buf, 256), 33); // read() is not supposed to insert the null terminator at the end of // the char string, so do it manually buf[33] = '\0'; WVPASSEQ(buf, "Bonjour! Je m'appelle writestream"); deletev buf; close(file1); close(file2); } WVTEST_MAIN("outbuf_limit") { int fd = open("wvfdstream.t.tmp", O_WRONLY); printf("Trying to open wvfdstream.t.tmp to write\n"); if (!WVPASS(fd > 2)) { printf("(fd==%d) Are you sure we can write to wvfdstream.t.tmp?\n", fd); } WvFDStream fdstream1(dup(0), fd); fdstream1.outbuf_limit(10); fdstream1.delay_output(true); // call flush explicitly // empty buffer WVPASS(fdstream1.isok()); WVPASS(fdstream1.iswritable()); // one character in buffer fdstream1.write("d"); WVPASS(fdstream1.isok()); WVPASS(fdstream1.iswritable()); // string is too long - write only (10 - 1) chars WVPASS(fdstream1.write("Hello terminal!\n") == 9); WVPASS(fdstream1.isok()); // you might expect fdstream to return false here, but it doesn't; the // stream *is* writable (if you were to allow it to flush), but you // don't, so writes will fail even if it's writable. You have to be // prepared for writes to fail even if a stream is writable anyway, WVPASS(fdstream1.iswritable()); // full buffer - write() returns 0 (i.e. it fails); WVPASS(fdstream1.isok()); WVPASS(fdstream1.write("Hello terminal, again!\n") == 0); WVPASS(fdstream1.iswritable()); } static void myclosecb(int *i) { (*i)++; } WVTEST_MAIN("closecallback") { WvFdStream s(dup(0), dup(1)); int i = 0; s.setclosecallback(wv::bind(&myclosecb, &i)); WVPASS(s.isok()); s.nowrite(); WVPASS(s.isok()); WVPASSEQ(i, 0); s.noread(); s.runonce(0); WVFAIL(s.isok()); WVPASSEQ(i, 1); } WVTEST_MAIN("inbuf after read error") { int socks[2]; WVPASS(!wvsocketpair(SOCK_STREAM, socks)); WvFdStream s1(socks[0]), s2(socks[1]); s1.print("1\n2\n3\n4\n"); WVPASSEQ(s2.blocking_getline(1000, '\n', 1024), "1"); s1.close(); WVPASSEQ(s2.blocking_getline(1000, '\n', 1024), "2"); WVPASSEQ(s2.blocking_getline(1000, '\n', 1024), "3"); WVPASS(s2.isok()); WVPASSEQ(s2.blocking_getline(1000, '\n', 1024), "4"); WVFAIL(s2.blocking_getline(1000, '\n', 1024)); WVFAIL(s2.isok()); } class FooFD : public WvFDStream { public: FooFD(int fd) : WvFDStream(fd) { WVPASS(isreadable()); called = false; setcallback(wv::bind(&FooFD::fooback, this)); WvIStreamList::globallist.append(this, false, "FooFD"); } ~FooFD() { WvIStreamList::globallist.unlink(this); } void fooback() { called = true; } bool called; }; WVTEST_MAIN("Test undo_force_select() on a WvFDStream") { // create our test file WvString testfile = wvtmpfilename("wvfdstream-testfile-"); WvFile x(testfile, O_CREAT|O_RDWR, 0666); x.print("moo\n"); x.print("mow\n"); x.print("maw\n"); x.close(); int fd = open(testfile, O_RDONLY); WVPASS(fd != -1); WvFDStream f(fd); WVPASS(f.isok()); // should have some data for reading WVPASS(f.select(0)); // we don't want to select on anything anymore f.undo_force_select(true, true, true); WVFAIL(f.select(0)); // we want to continue selecting f.force_select(true, true, true); WVPASS(f.select(0)); FooFD foof(fd); WVPASS(!foof.called); // check that our callback is called WvIStreamList::globallist.runonce(); WVPASS(foof.isok()); WVPASS(foof.select(0)); WVPASS(WvIStreamList::globallist.select(0)); WVPASS(foof.called); foof.called = false; WVPASS(!foof.called); // undo_force_select() and make sure we're not called foof.undo_force_select(true, true, true); // can't use runonce() here because it should be false if (WvIStreamList::globallist.select(0)) WvIStreamList::globallist.callback(); WVPASS(!foof.called); unlink(testfile); } wvstreams-4.6.1/streams/t/wvmagicloopback.t.cc0000644000175000001440000000237211036722347020445 0ustar wlachusers#include #include "wvtest.h" #include "wvmagicloopback.h" #include "wvfork.h" #include WVTEST_MAIN("WvMagicLoopback Sanity") { signal(SIGPIPE, SIG_IGN); WvMagicLoopback ml(1024); pid_t pid = fork(); WVFAIL(pid < 0 && "fork() failed"); if (pid == 0) { int i; for (i=0; i<1024; ++i) { while (!ml.iswritable()); ml.write(&i, sizeof(i)); } _exit(0); } else { int i, maybe_i; for (i=0; i<1024; ++i) { while (!ml.isreadable()); ml.read(&maybe_i, sizeof(maybe_i)); if (i != maybe_i) { WVPASS(i == maybe_i); break; } } } pid_t rv; while ((rv = waitpid(pid, NULL, 0)) != pid) { // In case a signal is in the process of being delivered... if (rv == -1 && errno != EINTR) break; } WVPASS(rv == pid); } WVTEST_MAIN("WvMagicLoopback Non-Blocking Writes") { WvMagicLoopback ml(1024); WVPASS(ml.isok()); for (int i=0; i<(1<<10); ++i) { char buf[1024] = "WvMagicLoopback Non-Blocking Writes"; ml.write(buf, sizeof(buf)); } WVPASS(ml.isok()); } wvstreams-4.6.1/streams/t/wvpipe.t.cc0000644000175000001440000000144711036722347016611 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvPipe test. Allows you to enter bash commands, runs them, and pipes the * output back to you. */ #include #include #include #include #include WVTEST_MAIN ("WvPipe with environment") { WvDynBuf foo; WvStringList envs; envs.append("FOOBAR=foobar"); const char *av[] = { "/bin/bash", NULL }; WvPipe p(av[0], av, true, true, false, 0, 1, 2, &envs); // wvcon->autoforward(p); // p.autoforward(*wvcon); p.write("echo $FOOBAR\n"); if (p.select(100)) { p.read(foo, 1024); WvString isfoo(foo.getstr()); WVPASS(isfoo == "foobar\n"); } } wvstreams-4.6.1/streams/t/wvloopback2.t.cc0000644000175000001440000000115011036722347017517 0ustar wlachusers#include "wvtest.h" #include "wvloopback2.h" #include "wvstreamclone.h" WVTEST_MAIN("loopback2") { IWvStream *_s1, *_s2; wvloopback2(_s1, _s2); WvStreamClone s1(_s1), s2(_s2); WVPASS(s1.isok()); WVPASS(s2.isok()); s1.print("s1 output\ns1 line2\n"); s2.print("s2 output\ns2 line2"); WVPASSEQ(s1.blocking_getline(1000), "s2 output"); WVPASSEQ(s2.blocking_getline(1000), "s1 output"); WVPASSEQ(s2.getline(), "s1 line2"); WVFAIL(s1.getline()); // no newline found s2.nowrite(); // EOF finishes that last line WVPASSEQ(s1.blocking_getline(1000), "s2 line2"); } wvstreams-4.6.1/streams/t/pwvstream.t.cc0000644000175000001440000000135311036722347017323 0ustar wlachusers#include "wvtest.h" #include "pwvstream.h" #include "wvstreamclone.h" WVTEST_MAIN("pclones") { PWvStream s("loop:"); { PWvStream c(s.addRef()), c2(s.addRef()); c->print("hi!\n"); WVPASSEQ(c2->getline(-1), "hi!"); WVPASSEQ(c2->getline(0), ""); } PWvStream c3(s.addRef()); c3->print("boink\ngack"); c3->nowrite(); WVPASSEQ(c3->getline(-1), "boink"); WVPASSEQ(c3->getline(-1), "gack"); WVPASSEQ(c3->getline(-1), ""); } WVTEST_MAIN("pcopy") { char buf[4] = "xxx"; PWvStream s("loop:"); { PWvStream a1(s), a2, a3; a2 = a3; a2 = s; a2 = a2; a2 = a1; s = a1; } s->write("boo", 3); size_t len = s->read(buf, 3); WVPASSEQ(len, 3); WVPASSEQ(buf, "boo"); } wvstreams-4.6.1/streams/t/wvlog.t.cc0000644000175000001440000001341711036722347016435 0ustar wlachusers/* FIXME: horribly incomplete */ #include "wvtest.h" #include "wvlog.h" #include "wvlogbuffer.h" #include "wvlogfile.h" #include "wvfileutils.h" WVTEST_MAIN("extremely basic test") { // this test just basically helps see if there's an fd or memory leak // caused by creating/using a wvlog... WvLog log("logtest", WvLog::Info); log("Hello!\n"); WVPASS(log.isok()); } WVTEST_MAIN("line-breaking logic") { WvLogBuffer logbuffer(10); WvLog log1("log", WvLog::Info); WvLog log2(log1.split(WvLog::Debug)); WvLog log3("other log", WvLog::Info); log1("first part"); log2("second part"); log1("third part"); log3("fourth part"); log2("Message: "); log1(WvLog::Debug, "this is the message\n"); WvLogBuffer::MsgList::Iter i(logbuffer.messages()); i.rewind(); WVPASS(i.next()); WVPASSEQ(i->level, WvLog::Info); WVPASSEQ(i->source, "log"); WVPASSEQ(i->message, "first part"); WVPASS(i.next()); WVPASSEQ(i->level, WvLog::Debug); WVPASSEQ(i->source, "log"); WVPASSEQ(i->message, "second part"); WVPASS(i.next()); WVPASSEQ(i->level, WvLog::Info); WVPASSEQ(i->source, "log"); WVPASSEQ(i->message, "third part"); WVPASS(i.next()); WVPASSEQ(i->level, WvLog::Info); WVPASSEQ(i->source, "other log"); WVPASSEQ(i->message, "fourth part"); WVPASS(i.next()); WVPASSEQ(i->level, WvLog::Debug); WVPASSEQ(i->source, "log"); WVPASSEQ(i->message, "Message: this is the message"); WVFAIL(i.next()); } WVTEST_MAIN("timestamps") { WvString logfilename = wvtmpfilename("wvlog-timestamps"); WvLogFileBase logfile(logfilename, WvLog::Debug); WvLog log(__FUNCTION__, WvLog::Debug); time_t first_time = time(NULL); log("First message\n"); while (time(NULL) - first_time < 2) sleep(1); log("Second message\n"); logfile.close(); WvFile file(logfilename, O_RDONLY); WVPASS(file.isok()); // 0123456789012345678901 // Nov 10 10:13:15 GMT-4: WvString first_timestamp = file.getline(); if (first_timestamp.len() >= 21) first_timestamp.edit()[21] = '\0'; wvout->print("first timestamp: %s\n", first_timestamp); WvString second_timestamp = file.getline(); if (second_timestamp.len() >= 21) second_timestamp.edit()[21] = '\0'; wvout->print("second timestamp: %s\n", second_timestamp); WVFAILEQ(first_timestamp, second_timestamp); file.close(); WVPASS(unlink(logfilename) == 0); } WVTEST_MAIN("keep single log lines together") { WvString logfilename = wvtmpfilename("wvlog-together"); fprintf(stderr, "log file is: '%s'\n", logfilename.cstr()); { // WvFile f(logfilename, O_WRONLY|O_CREAT); int fd = open(logfilename, O_WRONLY|O_CREAT, 0777); if (fd < 0) perror("open"); if (close(fd) != 0) perror("close"); } if (unlink(logfilename) != 0) perror("unlink"); WvLogFileBase logfile(logfilename, WvLog::Debug); WvLog log(__FUNCTION__, WvLog::Debug); time_t first_time = time(NULL); log("First message: "); while (time(NULL) - first_time < 2) sleep(1); log("Second message\n"); logfile.close(); WvFile file(logfilename, O_RDONLY); WVPASS(file.isok()); WvString line1 = file.getline(); WvString line2 = file.getline(); wvout->print("line 1: %s\n", line1); // we want both messages on a single log line WVPASS(!line2); WVPASS(strstr(line1.cstr(), "First")); WVPASS(strstr(line1.cstr(), "Second")); file.close(); WVPASS(unlink(logfilename) == 0); } class WvNoisyLogRcv : public WvLogConsole { WvString noise; WvLog sublog; public: WvNoisyLogRcv(WvStringParm _noise, int fd, WvLog::LogLevel max_level) : WvLogConsole(fd, max_level), noise(_noise), sublog("WvNoisyLogRcv", max_level) { } void log(WvStringParm source, int _loglevel, const char *_buf, size_t len) { sublog("%s\n", noise); return WvLogConsole::log(source, _loglevel, _buf, len); } }; // Test that if a log receiver generates a log message itself while logging, // that we log a warning about it and don't recurse endlessly. WVTEST_MAIN("Recursion avoidance") { WvString noise("Recursive noise"); WvNoisyLogRcv noisy(noise, dup(1), WvLog::Debug5); #ifdef WIN32 mkdir("/tmp"); #endif WvString logfilename("/tmp/wvlog-recursive-test.%s", getpid()); WvLogFileBase logfile(logfilename, WvLog::Debug5); if (!WVPASS(logfile.isok())) { wverr->print("open %s: %s\n", logfilename, logfile.errstr()); return; } WvLog log("Regular log", WvLog::Error); WvString logmsg("The pebble that starts an avalanche..."); log(logmsg); logfile.close(); WvFile file(logfilename, O_RDONLY); if (!WVPASS(file.isok())) { wverr->print("open %s: %s\n", logfilename, file.errstr()); return; } // Test that we received all the log messages we were due WVPASS(strstr(file.getline(), "Too many extra log messages " "written while writing to the log. Suppressing " "additional messages.")); for (int i = 0; i < 6; ++i) WVPASS(strstr(file.getline(), noise.cstr())); WVPASS(strstr(file.getline(), logmsg.cstr())); // Cleanup file.close(); WVPASSEQ(unlink(logfilename), 0); } #if 0 WVTEST_MAIN("wvlog performance") { WvString logfilename = wvtmpfilename("wvlog-timestamps"); WvLogFileBase logfile(logfilename, WvLog::Debug); WvLog log(__FUNCTION__, WvLog::Debug); time_t start; start = time(NULL); while (time(NULL) == start) usleep(1000); start = time(NULL); int count = 0; while (time(NULL) - start < 10) log("Message %s\n", count++); wvout->print("Total %s log messages\n", count); WVPASS(unlink(logfilename) == 0); } #endif wvstreams-4.6.1/streams/t/wvlogfile.t.cc0000644000175000001440000000061311036722347017267 0ustar wlachusers#include "wvtest.h" #include "wvlogfile.h" #include "wvfileutils.h" WVTEST_MAIN("wvlogfile") { WvString name(wvtmpfilename("wvtest-log")); WvLogFile f(name); WvString fullname(f.start_log()); WVFAILEQ(fullname, name); WvLog log("hello", WvLog::Info); WVPASS(true); WVPASS(access(fullname, R_OK) == 0); log.print("log test\n"); WVPASS(true); } wvstreams-4.6.1/streams/wvatomicfile.cc0000644000175000001440000000435511202637334017260 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * Wrapper class for WvFile for automic file creation. Any files that * are guaranteed to be automic will completely write over any existing * file on close. */ #include "wvatomicfile.h" #include "wvfileutils.h" #include "wvstrutils.h" #ifdef MACOS #include #endif WvAtomicFile::WvAtomicFile(WvStringParm filename, int flags, mode_t create_mode) : tmp_file(WvString::null) { open(filename, flags, create_mode); } WvAtomicFile::~WvAtomicFile() { close(); } /* Mimics behaviour of wvfile except that it uses a tmp file and stores the real name */ bool WvAtomicFile::open(WvStringParm filename, int flags, mode_t create_mode) { close(); atomic_file = filename; // Ensure that if the file exists it is a regular file struct stat st; if (lstat(atomic_file, &st) == 0 && !S_ISREG(st.st_mode)) return false; WvString new_tmp_file("%s/WvXXXXXX", getdirname(filename)); // Get the current umask and guarantee that mkstemp() creates // a file with maximal restrictions mode_t old_umask = ::umask(077); int tmp_fd = ::mkstemp(new_tmp_file.edit()); if (tmp_fd < 0) seterr(errno); ::umask(old_umask); if (tmp_fd < 0) return false; // Set the permissions as specified using the original umask // We will only possibly be adding permissions here... if (::fchmod(tmp_fd, create_mode & ~old_umask) != 0) seterr(errno); if (!WvFile::open(tmp_fd)) { ::close(tmp_fd); return false; } tmp_file = new_tmp_file; return true; } void WvAtomicFile::close() { WvFdStream::close(); if (tmp_file) { if (::rename(tmp_file, atomic_file) != 0) ::unlink(tmp_file); tmp_file = WvString::null; } } bool WvAtomicFile::chmod(mode_t mode) { if (getfd() == -1) return false; if (fchmod(getfd(), mode) != 0) { seterr(errno); return false; } return true; } bool WvAtomicFile::chown(uid_t owner, gid_t group) { if (getfd() == -1) return false; if (fchown(getfd(), owner, group) != 0) { seterr(errno); return false; } return true; } wvstreams-4.6.1/streams/wvsocketpair.cc0000644000175000001440000000124311036722347017305 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of wvsocketpair(), a portable way to call socketpair(). */ #include "wvsocketpair.h" #include #ifndef _WIN32 # include #else # include #endif #ifdef _WIN32 int socketpair(int family, int type, int protocol, int *sb); #endif int wvsocketpair(int type, int socks[2]) { // NOTE: a fake socketpair() call is provided by wvstreams for win32. // The main advantage of wvsocketpair is it avoids the weird mess of // includes, ifdefs, and prototypes above. return socketpair(PF_UNIX, type, 0, socks); } wvstreams-4.6.1/streams/wvbufstream.cc0000644000175000001440000000203711077373534017140 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvBufStream stores data written by write(), and returns it in read(). * * See wvbufstream.h. */ #include "wvbufstream.h" WvBufStream::WvBufStream() { dead = eof = false; } WvBufStream::~WvBufStream() { close(); } void WvBufStream::close() { dead = true; WvStream::close(); } // if uread() is called, someone has already exhausted inbuf... so now it's // time to close our stream so they know they're at EOF. size_t WvBufStream::uread(void *buf, size_t size) { if (eof) close(); return 0; } size_t WvBufStream::uwrite(const void *buf, size_t size) { inbuf.put(buf, size); return size; } bool WvBufStream::isok() const { return !dead; } void WvBufStream::pre_select(SelectInfo &si) { WvStream::pre_select(si); if (si.wants.writable || eof) si.msec_timeout = 0; } bool WvBufStream::post_select(SelectInfo &si) { return WvStream::post_select(si) || si.wants.writable || eof; } wvstreams-4.6.1/streams/wvmagicloopback.cc0000644000175000001440000000170411036722347017736 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. */ #include "wvmagicloopback.h" WvMagicLoopback::WvMagicLoopback(size_t size) : circle(size), loop() { } void WvMagicLoopback::pre_select(SelectInfo &si) { loop.drain(); loop.pre_select(si); if ((si.wants.readable && circle.used() > 0) || (si.wants.writable && circle.left() > 0)) si.msec_timeout = 0; } bool WvMagicLoopback::post_select(SelectInfo &si) { bool ret = WvStream::post_select(si); if ((si.wants.readable && circle.used() > 0) || (si.wants.writable && circle.left() > 0)) ret = true; return ret; } size_t WvMagicLoopback::uread(void *buf, size_t len) { return circle.get(buf, len); } size_t WvMagicLoopback::uwrite(const void *buf, size_t len) { len = circle.put(buf, len); if (len > 0) loop.uwrite("", 1); // Make select wake up return len; } wvstreams-4.6.1/streams/wvstreamsdaemon.cc0000644000175000001440000000502311036722347020003 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * High-level abstraction for creating daemon processes that do * nothing but listen on a list of WvStreams and add connections * to the global list. */ #include "wvstreamsdaemon.h" #ifndef _WIN32 #include #endif void WvStreamsDaemon::init(WvDaemonCallback cb) { do_full_close = false; setcallback(cb); #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif } void WvStreamsDaemon::do_start() { WvDaemon::do_start(); callback(); } void WvStreamsDaemon::do_run() { if (streams.isempty()) { log(WvLog::Error, "No streams; exiting\n"); die(); } while (should_run()) { WvDaemon::do_run(); WvIStreamList::globallist.runonce(); } } void WvStreamsDaemon::do_stop() { WvIStreamList::Iter stream(streams); for (stream.rewind(); stream.next(); ) WvIStreamList::globallist.unlink(stream.ptr()); streams.zap(); if (do_full_close || want_to_die()) WvIStreamList::globallist.zap(); WvDaemon::do_stop(); } void WvStreamsDaemon::add_stream(IWvStream *istream, bool autofree, const char *id) { streams.append(istream, false, id); // FIXME: we should pass in "id" here, but things are not happy in // const-correctness-land. WvIStreamList::globallist.append(istream, autofree, id); } void WvStreamsDaemon::add_restart_stream(IWvStream *istream, bool autofree, const char *id) { add_stream(istream, autofree, id); istream->setclosecallback(wv::bind(&WvStreamsDaemon::restart_close_cb, this, istream, id)); } void WvStreamsDaemon::add_die_stream(IWvStream *istream, bool autofree, const char *id) { add_stream(istream, autofree, id); istream->setclosecallback(wv::bind(&WvStreamsDaemon::die_close_cb, this, istream, id)); } void WvStreamsDaemon::restart_close_cb(IWvStream *s, const char *id) { if (should_run()) { WvString err = s->geterr() ? s->errstr() : "no error"; log(WvLog::Error, "%s is closed (%s); restarting\n", id ? id : "Stream", err); restart(); } } void WvStreamsDaemon::die_close_cb(IWvStream *s, const char *id) { if (should_run()) { WvString err = s->geterr() ? s->errstr() : "no error"; log(WvLog::Error, "%s is closed (%s); dying\n", id ? id : "Stream", err); die(); } } void WvStreamsDaemon::setcallback(WvDaemonCallback cb) { callback = cb; } wvstreams-4.6.1/streams/wvloopback2.cc0000644000175000001440000000136111036722347017016 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of a two-way version of WvLoopback. See wvloopback2.h. */ #include "wvloopback2.h" #include "wvsocketpair.h" void wvloopback2(IWvStream *&s1, IWvStream *&s2) { int socks[2]; if (wvsocketpair(SOCK_STREAM, socks)) { int errnum = errno; s1 = new WvStream; s2 = new WvStream; s1->seterr(errnum); s2->seterr(errnum); return; } WvFdStream *f1 = new WvFdStream(socks[0], socks[0]); WvFdStream *f2 = new WvFdStream(socks[1], socks[1]); f1->set_close_on_exec(true); f2->set_close_on_exec(true); f1->set_nonblock(true); f2->set_nonblock(true); s1 = f1; s2 = f2; } wvstreams-4.6.1/streams/wvfile.cc0000644000175000001440000000642611036722347016070 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * A simple class to access filesystem files using WvStreams. */ #include "wvfile.h" #include "wvmoniker.h" WvFile::WvFile() { readable = writable = false; } #ifndef _WIN32 // meaningless to do this on win32 /* * The Win32 runtime library doesn't provide fcntl so we can't * set readable and writable reliably. Use the other constructor. */ WvFile::WvFile(int rwfd) : WvFDStream(rwfd) { if (rwfd > -1) { /* We have to do it this way since O_RDONLY is defined as 0 in linux. */ mode_t xmode = fcntl(rwfd, F_GETFL); xmode = xmode & (O_RDONLY | O_WRONLY | O_RDWR); readable = (xmode == O_RDONLY) || (xmode == O_RDWR); writable = (xmode == O_WRONLY) || (xmode == O_RDWR); } else readable = writable = false; } #endif WvFile::WvFile(WvStringParm filename, int mode, int create_mode) { #ifdef _WIN32 mode |= O_BINARY; // WvStreams users aren't expecting crlf mangling #endif open(filename, mode, create_mode); } static IWvStream *increator(WvStringParm s, IObject*) { return new WvFile(s, O_RDONLY, 0666); } static IWvStream *outcreator(WvStringParm s, IObject*) { return new WvFile(s, O_WRONLY|O_CREAT|O_TRUNC, 0666); } static IWvStream *creator(WvStringParm s, IObject*) { return new WvFile(s, O_RDWR|O_CREAT, 0666); } static WvMoniker reg0("infile", increator); static WvMoniker reg1("outfile", outcreator); static WvMoniker reg3("file", creator); bool WvFile::open(WvStringParm filename, int mode, int create_mode) { noerr(); /* We have to do it this way since O_RDONLY is defined as 0 in linux. */ int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR)); readable = (xmode == O_RDONLY) || (xmode == O_RDWR); writable = (xmode == O_WRONLY) || (xmode == O_RDWR); // don't do the default force_select of read if we're not readable! if (!readable) undo_force_select(true, false, false); close(); #ifndef _WIN32 int rwfd = ::open(filename, mode | O_NONBLOCK, create_mode); #else int rwfd = ::_open(filename, mode | O_NONBLOCK, create_mode); #endif if (rwfd < 0) { seterr(errno); return false; } setfd(rwfd); fcntl(rwfd, F_SETFD, 1); closed = stop_read = stop_write = false; return true; } #ifndef _WIN32 // since win32 doesn't support fcntl bool WvFile::open(int _rwfd) { noerr(); if (_rwfd < 0) return false; noerr(); close(); int mode = fcntl(_rwfd, F_GETFL); int xmode = (mode & (O_RDONLY | O_WRONLY | O_RDWR)); readable = (xmode == O_RDONLY) || (xmode == O_RDWR); writable = (xmode == O_WRONLY) || (xmode == O_RDWR); if (!readable) undo_force_select(true, false, false); setfd(_rwfd); fcntl(_rwfd, F_SETFL, mode | O_NONBLOCK); fcntl(_rwfd, F_SETFD, 1); closed = stop_read = stop_write = false; return true; } #endif // files not open for read are never readable; files not open for write // are never writable. void WvFile::pre_select(SelectInfo &si) { if (!readable) si.wants.readable = false; if (!writable) si.wants.writable = false; WvFDStream::pre_select(si); } bool WvFile::post_select(SelectInfo &si) { return WvFDStream::post_select(si); } wvstreams-4.6.1/streams/wvconstream.cc0000644000175000001440000000452611036722347017143 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Declarations for wvcon, wvin, wvout, and wverr global streams. */ #include "wvfdstream.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(WvConStream); // just like WvFDStream, but doesn't close the fd class _WvConStream : public WvFDStream { public: bool isopen; _WvConStream(int _rfd, int _wfd, WvStringParm name = WvString::null); virtual ~_WvConStream(); virtual void close(); virtual bool isok() const; }; _WvConStream::_WvConStream(int _rfd, int _wfd, WvStringParm name) : WvFDStream(_rfd, _wfd) { isopen = true; if (!name.isnull()) set_wsname(name); } _WvConStream::~_WvConStream() { close(); } void _WvConStream::close() { isopen = false; setfd(-1); // prevent WvFdStream from closing our fds WvFDStream::close(); } bool _WvConStream::isok() const { return isopen; } // console streams #ifdef _WIN32 #include "streams.h" SocketFromFDMaker _zero(_dup(0), fd2socket_fwd, false); SocketFromFDMaker _one(1, socket2fd_fwd, true); SocketFromFDMaker _two(2, socket2fd_fwd, true); static _WvConStream _wvcon(_zero.GetSocket(), _one.GetSocket(), "wvcon"); static _WvConStream _wvin(_zero.GetSocket(), -1, "wvin"); static _WvConStream _wvout(-1, _one.GetSocket(), "wvout"); static _WvConStream _wverr(-1, _two.GetSocket(), "wverr"); #else // _WIN32 static _WvConStream _wvcon(0, 1, "wvcon"); static _WvConStream _wvin(0, -1, "wvin"); static _WvConStream _wvout(-1, 1, "wvout"); static _WvConStream _wverr(-1, 2, "wverr"); #endif // !_WIN32 WvStream *wvcon = &_wvcon; WvStream *wvin = &_wvin; WvStream *wvout = &_wvout; WvStream *wverr = &_wverr; static IWvStream *create_stdin(WvStringParm s, IObject*) { wvin->addRef(); return wvin; } static IWvStream *create_stdout(WvStringParm s, IObject*) { wvout->addRef(); return wvout; } static IWvStream *create_stderr(WvStringParm s, IObject*) { wverr->addRef(); return wverr; } static IWvStream *create_stdio(WvStringParm s, IObject*) { wvcon->addRef(); return wvcon; } static WvMoniker reg0("stdin", create_stdin); static WvMoniker reg1("stdout", create_stdout); static WvMoniker reg2("stderr", create_stderr); static WvMoniker reg3("stdio", create_stdio); wvstreams-4.6.1/streams/wvtimestream.cc0000644000175000001440000000406611036722347017321 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * See wvtimestream.h. */ #include "wvtimestream.h" WvTimeStream::WvTimeStream(): last(wvtime_zero), next(wvtime_zero), ms_per_tick(0) { } void WvTimeStream::set_timer(time_t msec) { WvTime now = wvstime(); ms_per_tick = msec > 0 ? msec : 0; next = msecadd(now, ms_per_tick); last = now; } bool WvTimeStream::isok() const { return true; } void WvTimeStream::pre_select(SelectInfo &si) { WvTime now; time_t diff; WvStream::pre_select(si); //fprintf(stderr, "%p: timestream pre_select mspt=%ld msto=%ld\n", // this, ms_per_tick, si.msec_timeout); if (ms_per_tick) { now = wvstime(); /* Are we going back in time? If so, adjust the due time. */ if (now < last) next = tvdiff(next, tvdiff(last, now)); last = now; if (next <= now) { si.msec_timeout = 0; return; } diff = msecdiff(next, now); diff = diff < 0 ? 0 : diff; if (diff < si.msec_timeout || si.msec_timeout < 0) si.msec_timeout = diff; } } bool WvTimeStream::post_select(SelectInfo &si) { WvTime now = wvstime(); return WvStream::post_select(si) || (ms_per_tick && next <= now); } void WvTimeStream::execute() { WvStream::execute(); /* Schedule our next timer event, unless alarm_is_ticking, which * would mean that we're here because someone used alarm() rather * than because our timer expired. */ if (!alarm_was_ticking) { WvTime now = wvstime(); next = msecadd(next, ms_per_tick); if (msecdiff(next, now) > ms_per_tick * 100 || msecdiff(now, next) > ms_per_tick * 100) { // reset if we fall forward or behind WAY too excessively // This is usually due to a change in system time last = now; next = msecadd(last, ms_per_tick); } else if (msecdiff(next, now) > ms_per_tick * 10) // compensate if we fall behind too excessively next = msecadd(now, ms_per_tick); } } wvstreams-4.6.1/streams/wvcrashlog.cc0000644000175000001440000000105411036722347016743 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A "Log Receiver" that puts the messages in the wvcrash_ring_buffer */ #include "wvcrashlog.h" #include "wvcrash.h" WvCrashLog::WvCrashLog(WvLog::LogLevel _max_level) : WvLogRcv(_max_level) { } void WvCrashLog::_mid_line(const char *str, size_t len) { wvcrash_ring_buffer_put(str, len); } void WvCrashLog::_make_prefix(time_t timenow) { prefix = WvString("%s<%s>: ", last_source, loglevels[last_level]); prelen = prefix.len(); } wvstreams-4.6.1/streams/wvdailyevent.cc0000644000175000001440000000742411036722347017314 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * A simple class that can trigger an event on a timed basis. * a) if given an hour, triggers once per day, on that hour. * b) if given a number of times per day, triggers that many times per * day, evenly, starting at the hour given in (a). (Needed to get a * Microbackup going every 15 minutes.) * * Presently has a one-hour granularity in the first case, but that can be * extended one day when someone cares. * */ #include "wvdailyevent.h" #include "wvstream.h" #include "wvtimeutils.h" #include #ifndef _WIN32 #include #include #endif #define NUM_MINS_IN_DAY (24*60) #define NUM_SECS_IN_DAY (60*NUM_MINS_IN_DAY) WvDailyEvent::WvDailyEvent(int _first_hour, int _num_per_day, bool _skip_first) : prev(time(NULL)) { need_reset = false; prev = wvstime().tv_sec; configure(_first_hour, _num_per_day, _skip_first); } // Compute the next time this stream should select() void WvDailyEvent::pre_select(SelectInfo &si) { WvStream::pre_select(si); if (num_per_day) { time_t now = wvstime().tv_sec; time_t next = next_event(); assert(prev); assert(next); assert(prev > 100000); assert(next > 100000); //printf("%d %d %d\n", now, next, msecdiff(now, next)); if (now < next) si.msec_timeout = msecdiff(now, next); else if (!need_reset) { need_reset = true; prev = next; } } if (need_reset) si.msec_timeout = 0; //printf("%p msd=%d\n", this, ret, si.msec_timeout); } // Test to see if the timer has gone off bool WvDailyEvent::post_select(SelectInfo& si) { bool timer_rang = false; WvTime next(next_event(), 0); if (next < wvtime()) { timer_rang = true; prev = next; } return WvStream::post_select(si) || need_reset || timer_rang; } void WvDailyEvent::set_num_per_day(int _num_per_day) { num_per_day = _num_per_day; if (num_per_day < 0) num_per_day = 1; if (num_per_day > NUM_SECS_IN_DAY) num_per_day = NUM_SECS_IN_DAY; time_t max = num_per_day ? NUM_SECS_IN_DAY/num_per_day : 6*60*60; if (max > 6*60*60) max = 6*60*60; // unless that's a very long time, 6 hrs // don't start until at least one period has gone by prev = wvstime().tv_sec; not_until = prev + max; } void WvDailyEvent::configure(int _first_hour, int _num_per_day, bool _skip_first) { first_hour = _first_hour; skip_first = _skip_first; // Don't let WvDailyEvents occur more than once a minute. -- use an alarm // instead if (_num_per_day > NUM_MINS_IN_DAY) _num_per_day = NUM_MINS_IN_DAY; set_num_per_day(_num_per_day); } // the daily event occurs each day at first_hour on the hour, or at // some multiple of the interval *after* that hour. time_t WvDailyEvent::next_event() const { if (!num_per_day) // disabled return 0; assert(prev); time_t interval = NUM_SECS_IN_DAY/num_per_day; time_t start = prev + interval; // find the time to start counting from (up to 24 hours in the past) struct tm *tm = localtime(&start); if (tm->tm_hour < first_hour) { start = prev - NUM_SECS_IN_DAY + 1; // this time yesterday tm = localtime(&start); } tm->tm_hour = first_hour; // always start at the given hour tm->tm_min = tm->tm_sec = 0; // right on the hour start = mktime(tm); // convert back into a time_t // find the next event after prev that's a multiple of 'interval' // since 'start' time_t next = prev + interval; if ((next - start)%interval != 0) next = start + (next - start)/interval * interval; assert(next); assert(next > 100000); while (skip_first && next < not_until) next += interval; return next; } wvstreams-4.6.1/streams/wvlockfile.cc0000644000175000001440000000264011036722436016732 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A simple lockfile class using WvStreams. */ #include "wvlockfile.h" #include "strutils.h" #include WvLockFile::WvLockFile(WvStringParm _lockname) : lockname(_lockname) { // nothing special } bool WvLockFile::isok() { pid_t pid = readpid(); return !pid || pid == getpid(); } bool WvLockFile::lock() { if (!isok()) return false; WvFile lock(lockname, O_WRONLY|O_CREAT|O_EXCL); if (!lock.isok()) return false; lock.print("%s\n", getpid()); return true; } bool WvLockFile::unlock() { if (!isok()) return false; unlink(lockname); return readpid() == 0; } pid_t WvLockFile::readpid() { char *line; pid_t pid = 0; WvString lockdir(getdirname(lockname)); if (access(lockdir, W_OK) < 0 || (!access(lockname, F_OK) && access(lockname, R_OK) < 0)) return -1; // won't be able to create a lock else { WvFile lock(lockname, O_RDONLY); line = lock.blocking_getline(-1); if (line) { pid = atoi(line); if (pid != -1 && kill(pid, 0) < 0 && errno == ESRCH) // no such process { // previous lock owner is dead; clean it up. ::unlink(lockname); return 0; } } else { // blank lock file; clean it up. ::unlink(lockname); return 0; } } return pid; } wvstreams-4.6.1/streams/wvsyslog.cc0000644000175000001440000000315211036722347016462 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvSyslog is a descendant of WvLogRcv that sends messages to the syslogd * daemon. */ #include "wvsyslog.h" #include "strutils.h" #include #include WvSyslog::WvSyslog(WvStringParm _prefix, bool _include_appname, WvLog::LogLevel _first_debug, WvLog::LogLevel _max_level) : WvLogRcv(_max_level), syslog_prefix(_prefix) { first_debug = _first_debug; include_appname = _include_appname; openlog(syslog_prefix, 0, LOG_DAEMON); } WvSyslog::~WvSyslog() { end_line(); closelog(); } void WvSyslog::_begin_line() { if (include_appname) current.put(prefix, prelen); } void WvSyslog::_mid_line(const char *str, size_t len) { current.put(str, len); } void WvSyslog::_end_line() { int lev, count; struct LevMap { int wvlog_lvl; int syslog_lvl; }; static LevMap levmap[] = { {WvLog::Critical, LOG_CRIT}, {WvLog::Error, LOG_ERR}, {WvLog::Warning, LOG_WARNING}, {WvLog::Notice, LOG_NOTICE}, {WvLog::Info, LOG_INFO}, {WvLog::Debug, LOG_DEBUG}, {WvLog::Debug2, -1}, {-1, -1} }; if (current.used()) { lev = -1; for (count = 0; levmap[count].wvlog_lvl >= 0; count++) { if (last_level >= levmap[count].wvlog_lvl) lev = levmap[count].syslog_lvl; } if (last_level < first_debug && lev == LOG_DEBUG) lev = LOG_INFO; if (lev >= 0) { current.put("", 1); // null-terminate syslog(lev, "%s", current.get(current.used())); } else current.zap(); // not important enough to print this message } } wvstreams-4.6.1/streams/wvencoderstream.cc0000644000175000001440000001365111036722347020002 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvEncoderStream chains a series of encoders on the input and * output ports of the underlying stream to effect on-the-fly data * transformations. */ #include "wvencoderstream.h" WvEncoderStream::WvEncoderStream(WvStream *_cloned) : WvStreamClone(_cloned) { is_closing = false; min_readsize = 0; } WvEncoderStream::~WvEncoderStream() { close(); } void WvEncoderStream::close() { // fprintf(stderr, "Encoderstream close!\n"); // we want to finish the encoders even if !isok() since we // might just have encountered an EOF condition, and we want // to ensure that the remaining data is processed, but this // might cause recursion if the encoders set a new error condition if (is_closing) return; is_closing = true; // finish encoders finish_read(); finish_write(); // flush write chain and close the stream WvStreamClone::close(); } bool WvEncoderStream::isok() const { //fprintf(stderr, "encoderstream isok: %d %p %d %d\n", // WvStream::isok(), cloned, cloned->isok(), cloned->geterr()); // handle encoder error conditions if (!WvStream::isok()) return false; // handle substream error conditions // we don't check substream isok() because that is handled // during read operations to distinguish EOF from errors if (!cloned || cloned->geterr() != 0) return false; return true; } bool WvEncoderStream::flush_internal(time_t msec_timeout) { flush_write(); return WvStreamClone::flush_internal(msec_timeout); } bool WvEncoderStream::flush_read() { bool success = readchain.flush(readinbuf, readoutbuf); checkreadisok(); inbuf.merge(readoutbuf); return success; } bool WvEncoderStream::flush_write() { bool success = push(true /*flush*/, false /*finish*/); return success; } bool WvEncoderStream::finish_read() { bool success = readchain.flush(readinbuf, readoutbuf); if (!readchain.finish(readoutbuf)) success = false; checkreadisok(); inbuf.merge(readoutbuf); // noread(); return success; } bool WvEncoderStream::finish_write() { return push(true /*flush*/, true /*finish*/); } void WvEncoderStream::pull(size_t size) { // fprintf(stderr, "encoder pull %d\n", size); // pull a chunk of unencoded input bool finish = false; if (cloned) { if (size != 0) cloned->read(readinbuf, size); if (!cloned->isok()) finish = true; // underlying stream hit EOF or error } // deal with any encoders that have been added recently WvDynBuf tmpbuf; tmpbuf.merge(readoutbuf); readchain.continue_encode(tmpbuf, readoutbuf); // apenwarr 2004/11/06: always flush on read, because otherwise there's // no clear way to decide when we need to flush. Anyway, most "decoders" // (the kind of thing you'd put in the readchain) don't care whether you // flush or not. readchain.encode(readinbuf, readoutbuf, true); //readchain.encode(readinbuf, readoutbuf, finish /*flush*/); if (finish) { readchain.finish(readoutbuf); // if (readoutbuf.used() == 0 && inbuf.used() == 0) // noread(); close(); // otherwise defer EOF until the buffered data has been read } else if (!readoutbuf.used() && !inbuf.used() && readchain.isfinished()) { // only get EOF when the chain is finished and we have no // more data //noread(); close(); } checkreadisok(); } bool WvEncoderStream::push(bool flush, bool finish) { WvDynBuf writeoutbuf; // encode the output if (flush) writeinbuf.merge(outbuf); bool success = writechain.encode(writeinbuf, writeoutbuf, flush); if (finish) if (!writechain.finish(writeoutbuf)) success = false; checkwriteisok(); #if 0 // push encoded output to cloned stream size_t size = writeoutbuf.used(); if (size != 0) { const unsigned char *writeout = writeoutbuf.get(size); size_t len = WvStreamClone::uwrite(writeout, size); writeoutbuf.unget(size - len); } #endif if (cloned) cloned->write(writeoutbuf, writeoutbuf.used()); return success; } size_t WvEncoderStream::uread(void *buf, size_t size) { // fprintf(stderr, "encstream::uread(%d)\n", size); if (size && readoutbuf.used() == 0) pull(min_readsize > size ? min_readsize : size); size_t avail = readoutbuf.used(); if (size > avail) size = avail; readoutbuf.move(buf, size); return size; } size_t WvEncoderStream::uwrite(const void *buf, size_t size) { writeinbuf.put(buf, size); push(false /*flush*/, false /*finish*/); return size; } void WvEncoderStream::pre_select(SelectInfo &si) { WvStreamClone::pre_select(si); if (si.wants.readable && readoutbuf.used() != 0) si.msec_timeout = 0; } bool WvEncoderStream::post_select(SelectInfo &si) { bool sure = false; // if we have buffered input data and we want to check for // readability, then cause a callback to occur that will // hopefully ask us for more data via uread() if (si.wants.readable && readoutbuf.used() != 0) { pull(0); // try an encode if (readoutbuf.used() != 0) sure = true; } // try to push pending encoded output to cloned stream // outbuf_delayed_flush condition already handled by uwrite() push(false /*flush*/, false /*finish*/); // consult the underlying stream sure |= WvStreamClone::post_select(si); return sure; } void WvEncoderStream::checkreadisok() { if (!readchain.isok()) { seterr(WvString("read chain: %s", readchain.geterror())); noread(); } } void WvEncoderStream::checkwriteisok() { if (!writechain.isok()) seterr(WvString("write chain: %s", writechain.geterror())); } wvstreams-4.6.1/streams/fileutils.cc0000644000175000001440000001612411077124114016561 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Various useful file utilities. * */ #include "fileutils.h" #include "wvfile.h" #include "wvdiriter.h" #include #include #ifndef _WIN32 #include #endif #ifndef _MSC_VER #include #include #endif int wvmkdir(WvStringParm _dir, int create_mode) { #ifdef _WIN32 return mkdir(_dir); #else return mkdir(_dir, create_mode); #endif } int mkdirp(WvStringParm _dir, int create_mode) { if (!access(_dir, X_OK)) return 0; // You're trying to make a nothing directory eh? assert(!!_dir); WvString dir(_dir); char *p = dir.edit(); while ((p = strchr(++p, '/'))) { *p = '\0'; if (access(dir, X_OK) && wvmkdir(dir, create_mode)) return -1; *p = '/'; } // You're probably creating the directory to write to it? Maybe this should // look for R_OK&X_OK instead of X_OK&W_OK... return (access(dir, X_OK&W_OK) && wvmkdir(dir, create_mode)) ? -1 : 0; } void rm_rf(WvStringParm dir) { WvDirIter i(dir, false, false); // non-recursive, don't skip_mounts for (i.rewind(); i.next(); ) { if (i.isdir()) rm_rf(i->fullname); else ::unlink(i->fullname); } ::rmdir(dir); ::unlink(dir); } bool fcopy(WvStringParm src, WvStringParm dst) { struct stat buf; if (stat(src, &buf)) return false; WvFile in(src, O_RDONLY); unlink(dst); int oldmode = umask(0); WvFile out(dst, O_CREAT|O_WRONLY, buf.st_mode & 007777); umask(oldmode); in.autoforward(out); while (in.isok() && out.isok()) { /* This used to be a select(0), but really, if select() returns * false, it'll keep doing it until the end of time. If you're * going into an infinite loop, better save the CPU a bit, since * you can still find out about it with strace... */ if (in.select(-1, true, false)) in.callback(); } if (!out.isok()) return false; struct utimbuf utim; utim.actime = utim.modtime = buf.st_mtime; if (utime(dst, &utim)) return false; return true; } bool fcopy(WvStringParm srcdir, WvStringParm dstdir, WvStringParm relname) { return fcopy(WvString("%s/%s", srcdir, relname), WvString("%s/%s", dstdir, relname)); } bool ftouch(WvStringParm file, time_t mtime) { if (!WvFile(file, O_WRONLY|O_CREAT).isok()) return false; struct utimbuf *buf = NULL; if (mtime != 0) { buf = (struct utimbuf *)malloc(sizeof(struct utimbuf)); buf->actime = time(NULL); buf->modtime = mtime; } if (utime(file, buf) == 0) { free(buf); return true; } free(buf); return false; } // Reads the contents of a symlink. Returns WvString::null on error. WvString wvreadlink(WvStringParm path) { #ifdef _WIN32 return WvString::null; // no such thing as a symlink on Windows #else WvString result; int size = 64; for (;;) { result.setsize(size); int readlink_result = readlink(path, result.edit(), size); if (readlink_result == -1) return WvString::null; if (readlink_result < size) { result.edit()[readlink_result] = '\0'; break; } size = 2*size; // increase buffer size } return result; #endif } bool samedate(WvStringParm file1, WvStringParm file2) { struct stat buf; struct stat buf2; if (stat(file1, &buf) || stat(file2, &buf2)) return false; if (buf.st_mtime == buf2.st_mtime || buf.st_ctime == buf2.st_ctime) return true; return false; } bool samedate(WvStringParm dir1, WvStringParm dir2, WvStringParm relname) { return samedate(WvString("%s/%s", dir1, relname), WvString("%s/%s", dir2, relname)); } #ifndef _WIN32 // runs fnmatch against everything in patterns. We also interpret // CVS-style '!' patterns, which makes us very fancy. bool wvfnmatch(WvStringList& patterns, WvStringParm name, int flags) { WvStringList::Iter i(patterns); bool match = false; for (i.rewind(); i.next(); ) { // if we hit JUST a '!', reset any matches found so far. if (*i == "!") { match = false; continue; } // if we hit something that starts with '!', we unmatch anything // found so far. if (i->cstr()[0] == '!') { if (!match) continue; // nothing to unmatch, so why try? if (fnmatch(*i+1, name, flags) == 0) // matches match = false; // unmatch it. } else { // just a straightforward matching case. if (fnmatch(*i, name, flags) == 0) // matches match = true; } } return match; } #endif #ifndef _WIN32 // file permissions are too screwy in win32 int wvchmod(const char *path, mode_t mode) { struct stat st; if (lstat(path, &st) == -1) { return -1; } int filedes = open(path, O_RDONLY); if (filedes == -1) { // if we're not running as root, this file/dir may have 0 // perms and open() fails, so let's try again // // NOTE: This is not as secure as the proper way, since // it's conceivable that someone swaps out the dir/file // for a symlink between our check and the chmod() call // struct stat sst; if (getuid() != 0) if (stat(path, &sst) != -1) if (st.st_ino == sst.st_ino) return chmod(path, mode); return -1; } struct stat fst; if (fstat(filedes, &fst) == -1) { close(filedes); return -1; } if (st.st_ino != fst.st_ino) { close(filedes); return -1; } #ifndef _WIN32 // we're definitely chmod'ing the open file here, which is good, // because the filename itself might have been moved around between // our stat'ing and chmod'ing it. int retval = fchmod(filedes, mode); #else // this is guaranteed to be the same file as filedes, because in // Windows, open files can't be changed on the filesystem (unlike in // Unix). int retval = chmod(path, mode); #endif close(filedes); return retval; } #endif // !_WIN32 FILE *wvtmpfile() { #ifndef _WIN32 // tmpfile() is really the best choice, when it works return tmpfile(); #else // in win32, tmpfile() creates files in c:\... // and that directory isn't always writable! Idiots. char *name = _tempnam("c:\\temp", "wvtmp"); FILE *f = fopen(name, "wb+"); free(name); return f; #endif } WvString wvtmpfilename(WvStringParm prefix) { #ifndef _WIN32 // tmpfile() is really the best choice, when it works WvString tmpname("/tmp/%sXXXXXX", prefix); int fd; if ((fd = mkstemp(tmpname.edit())) == (-1)) return WvString(); close(fd); #else WvString tmpname(_tempnam("c:\\temp", prefix.cstr())); int fd; fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, 0777); if (fd < 0) return WvString::null; // weird _close(fd); #endif return tmpname; } mode_t get_umask() { mode_t rv = umask(0); umask(rv); return rv; } wvstreams-4.6.1/streams/wvlog.cc0000644000175000001440000002154011036722347015724 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Functions needed to implement general WvLog class. * * See wvlog.h for more information. */ #include "wvlogrcv.h" #include "wvstringlist.h" #include "strutils.h" #include "wvfork.h" #include #ifdef _WIN32 #define snprintf _snprintf #endif WvLogRcvBaseList *WvLog::receivers; int WvLog::num_receivers = 0, WvLog::num_logs = 0; WvLogRcvBase *WvLog::default_receiver = NULL; const char *WvLogRcv::loglevels[WvLog::NUM_LOGLEVELS] = { "Crit", "Err", "Warn", "Notice", "Info", "*1", "*2", "*3", "*4", "*5", }; /////////////////////////////////////// WvLog WvLog::WvLog(WvStringParm _app, LogLevel _loglevel, WvLogFilter* _filter) : app(_app), loglevel(_loglevel), filter(_filter) { // printf("log: %s create\n", app.cstr()); num_logs++; set_wsname(app); } WvLog::WvLog(const WvLog &l) : app(l.app), loglevel(l.loglevel), filter(l.filter) { // printf("log: %s create\n", app.cstr()); num_logs++; set_wsname(app); } WvLog::~WvLog() { num_logs--; if (!num_logs && default_receiver) { num_receivers++; // deleting default does not really reduce delete default_receiver; default_receiver = NULL; } // printf("log: %s delete\n", app.cstr()); // printf("num_logs is now %d\n", num_logs); } bool WvLog::isok() const { return true; } void WvLog::pre_select(SelectInfo &si) { // a wvlog is always writable... if (si.wants.writable) si.msec_timeout = 0; else WvStream::pre_select(si); } bool WvLog::post_select(SelectInfo &si) { // a wvlog is always writable... if (si.wants.writable) return true; else return WvStream::post_select(si); } size_t WvLog::uwrite(const void *_buf, size_t len) { // Writing the log message to a stream might cause it to emit its own log // messages, causing recursion. Don't let it get out of hand. static const int recursion_max = 8; static int recursion_count = 0; static WvString recursion_msg("Too many extra log messages written while " "writing to the log. Suppressing additional messages.\n"); ++recursion_count; if (!num_receivers) { if (!default_receiver) { // nobody's listening -- create a receiver on the console int xfd = dup(2); default_receiver = new WvLogConsole(xfd); num_receivers--; // default does not qualify! } if (recursion_count < recursion_max) default_receiver->log(app, loglevel, (const char *)_buf, len); else if (recursion_count == recursion_max) default_receiver->log(app, WvLog::Warning, recursion_msg.cstr(), recursion_msg.len()); --recursion_count; return len; } else if (default_receiver) { // no longer empty list -- delete our default to stderr num_receivers++; // deleting default does not really reduce delete default_receiver; default_receiver = NULL; } assert(receivers); WvLogRcvBaseList::Iter i(*receivers); for (i.rewind(); i.next(); ) { WvLogRcvBase &rc = *i; if (recursion_count < recursion_max) rc.log(app, loglevel, (const char *)_buf, len); else if (recursion_count == recursion_max) rc.log(app, WvLog::Warning, recursion_msg.cstr(), recursion_msg.len()); } --recursion_count; return len; } ///////////////////////////////////// WvLogRcvBase WvLogRcvBase::WvLogRcvBase() { static_init(); WvLogRcvBase::force_new_line = false; if (!WvLog::receivers) WvLog::receivers = new WvLogRcvBaseList; WvLog::receivers->append(this, false); WvLog::num_receivers++; } WvLogRcvBase::~WvLogRcvBase() { assert(WvLog::receivers); WvLog::receivers->unlink(this); if (WvLog::receivers->isempty()) { delete WvLog::receivers; WvLog::receivers = NULL; } WvLog::num_receivers--; } const char *WvLogRcvBase::appname(WvStringParm log) const { if (log) return log; else return "unknown"; } void WvLogRcvBase::static_init() { static bool init = false; if (!init) { #ifndef _WIN32 add_wvfork_callback(WvLogRcvBase::cleanup_on_fork); #endif init = true; } } void WvLogRcvBase::cleanup_on_fork(pid_t p) { if (p) return; // parent: do nothing if (WvLog::receivers) WvLog::receivers->zap(); delete WvLog::default_receiver; WvLog::default_receiver = NULL; WvLog::num_receivers = 0; } //////////////////////////////////// WvLogRcv WvLogRcv::WvLogRcv(WvLog::LogLevel _max_level) : custom_levels(5) { last_source = WvString(); last_level = WvLog::NUM_LOGLEVELS; last_time = 0; max_level = _max_level; at_newline = true; } WvLogRcv::~WvLogRcv() { } void WvLogRcv::_make_prefix(time_t now) { prefix = WvString("%s<%s>: ", last_source, loglevels[last_level]); prelen = prefix.len(); } void WvLogRcv::_begin_line() { mid_line(prefix, prelen); } void WvLogRcv::_end_line() { // do nothing } // like isprint(), but always treats chars >128 as printable, because they // always are (even if they're meaningless) static bool my_isprint(char _c) { unsigned char c = _c; if (isprint(c) || c >= 128) return true; else return false; } void WvLogRcv::log(WvStringParm source, int _loglevel, const char *_buf, size_t len) { WvLog::LogLevel loglevel = (WvLog::LogLevel)_loglevel; char hex[5]; WvLog::LogLevel threshold = max_level; WvString srcname(source); strlwr(srcname.edit()); Src_LvlDict::Iter i(custom_levels); i.rewind(); // Check if the debug level for the source has been overridden while (i.next()) { if (strstr(srcname, i->src)) { threshold = i->lvl; break; } } if (loglevel > threshold) return; // only need to start a new line with new headers if they headers have // changed. if the source and level are the same as before, just continue // the previous log entry. time_t now = wvtime().tv_sec; if (source != last_source || loglevel != last_level || WvLogRcvBase::force_new_line) { end_line(); last_source = source; last_level = loglevel; last_time = now; _make_prefix(now); } else if (last_time == 0 || now != last_time) { // ensure that even with the same source and level, logs will // properly get the right time associated with them. however, // don't split up log messages that should appear in a single // log line. last_time = now; if (at_newline) _make_prefix(now); } const char *buf = (const char *)_buf, *bufend = buf + len, *cptr; // loop through the buffer, printing each character or its [hex] equivalent // if it is unprintable. Also eat newlines unless they are appropriate. while (buf < bufend) { if (buf[0] == '\n' || buf[0] == '\r') { end_line(); buf++; continue; } begin_line(); if (buf[0] == '\t') { mid_line(" ", 1); buf++; continue; } else if (!my_isprint(buf[0])) { snprintf(hex, 5, "[%02x]", buf[0]); mid_line(hex, 4); buf++; continue; } // like strchr, but size-limited instead of null-terminated for (cptr = buf; cptr < bufend; cptr++) { if (*cptr == '\n' || !my_isprint(*cptr)) break; } if (cptr >= bufend) // end of buffer { mid_line(buf, bufend - buf); buf = bufend; } else if (*cptr == '\n') // end of line { mid_line((const char *)buf, cptr - buf); buf = cptr; } else // therefore (!my_isprint(*cptr)) { mid_line(buf, cptr - buf); buf = cptr; } } } // input format: name=number, name=number, name=number, etc. // 'name' is the name of a log service // 'number' is the number of the log level to use. bool WvLogRcv::set_custom_levels(WvString descr) { custom_levels.zap(); // Parse the filter line into individual rules WvStringList lst; WvStringList::Iter i(lst); lst.split(descr, ",= "); if (lst.isempty()) return true; WvString src(""); for (i.rewind(); i.next(); ) { if (src != "") { if (atoi(*i) > 0 && atoi(*i) <= WvLog::NUM_LOGLEVELS) { custom_levels.add(new Src_Lvl(src, atoi(*i)), true); src = ""; } else return false; } else { src = *i; strlwr(trim_string(src.edit())); } } if (src != "") return false; return true; } ///////////////////////////////////// WvLogConsole WvLogConsole::WvLogConsole(int _fd, WvLog::LogLevel _max_level) : WvFDStream(_fd), WvLogRcv(_max_level) { } WvLogConsole::~WvLogConsole() { end_line(); } void WvLogConsole::_mid_line(const char *str, size_t len) { uwrite(str, len); } wvstreams-4.6.1/streams/wvpipe.cc0000644000175000001440000001566311036722347016111 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of a WvPipe stream. WvPipes allow you to create a new * process, attaching its stdin/stdout to a WvStream. * * See wvpipe.h for more information. */ #include #include #include #include #include #include #include #include #include "wvpipe.h" // this code is pretty handy for debugging, since 'netstat -nap' can't tell // you the endpoints of a socketpair(), but it can tell you the name of a // "real" Unix domain socket. #if 0 #include "wvaddr.h" static int socketpair(int d, int type, int protocol, int sv[2]) { static int counter = 10; int f1 = socket(PF_UNIX, SOCK_STREAM, protocol); int f2 = socket(PF_UNIX, SOCK_STREAM, protocol); WvString s("/tmp/sock%s", ++counter); WvString s2("/tmp/sock%sb", counter); WvUnixAddr a(s), a2(s2); unlink(s); unlink(s2); bind(f1, a.sockaddr(), a.sockaddr_len()); bind(f2, a2.sockaddr(), a2.sockaddr_len()); listen(f1, 10); connect(f2, a.sockaddr(), a.sockaddr_len()); socklen_t ll = a.sockaddr_len(); int f3 = accept(f1, a.sockaddr(), &ll); close(f1); sv[0] = f3; sv[1] = f2; return 0; } #endif // The assorted WvPipe::WvPipe() constructors are described in wvpipe.h WvPipe::WvPipe(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, int stdin_fd, int stdout_fd, int stderr_fd, WvStringList *env) { setup(program, argv, writable, readable, catch_stderr, stdin_fd, stdout_fd, stderr_fd, env); } WvPipe::WvPipe(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, WvFDStream *stdin_str, WvFDStream *stdout_str, WvFDStream *stderr_str, WvStringList *env) { int fd0 = 0, fd1 = 1, fd2 = 2; if (stdin_str) fd0 = stdin_str->getrfd(); if (stdout_str) fd1 = stdout_str->getwfd(); if (stderr_str) fd2 = stderr_str->getwfd(); setup(program, argv, writable, readable, catch_stderr, fd0, fd1, fd2, env); } WvPipe::WvPipe(const char *program, const char **argv, bool writable, bool readable, bool catch_stderr, WvFDStream *stdio_str, WvStringList *env) { if (stdio_str) { int rfd = stdio_str->getrfd(), wfd = stdio_str->getwfd(); setup(program, argv, writable, readable, catch_stderr, rfd, wfd, wfd, env); } else setup(program, argv, writable, readable, catch_stderr, 0, 1, 2, env); } void WvPipe::setup(const char *program, const char * const *argv, bool writable, bool readable, bool catch_stderr, int stdin_fd, int stdout_fd, int stderr_fd, WvStringList *env) { int socks[2]; int flags; int waitfd; int pid; if (!program || !argv) { seterr(EINVAL); return; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks)) { seterr(errno); return; } fcntl(socks[0], F_SETFL, O_RDWR|O_NONBLOCK); setfd(socks[0]); if (env) { WvStringList::Iter it(*env); for (it.rewind(); it.next(); ) { proc.env.append(*it); } } pid = proc.fork(&waitfd); if (!pid) { // child process ::close(socks[0]); if (writable) dup2(socks[1], 0); // writable means redirect child stdin else if (stdin_fd == -1) ::close(0); else dup2(stdin_fd, 0); if (readable) dup2(socks[1], 1); // readable means we redirect child stdout else if (stdout_fd == -1) ::close(1); else dup2(stdout_fd, 1); if (catch_stderr) dup2(socks[1], 2); // but catch_stderr does what you think else if (stderr_fd == -1) ::close(2); else dup2(stderr_fd, 2); /* never close stdin/stdout/stderr */ fcntl(0, F_SETFD, 0); fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); /* drop the O_NONBLOCK from stdin/stdout/stderr, it confuses * some programs */ flags = fcntl(0, F_GETFL); fcntl(0, F_SETFL, flags & ~O_NONBLOCK); flags = fcntl(1, F_GETFL); fcntl(1, F_SETFL, flags & ~O_NONBLOCK); flags = fcntl(2, F_GETFL); fcntl(2, F_SETFL, flags & ~O_NONBLOCK); /* If we're not capturing any of these through the socket, it * means that the child end of the socket will be closed right * at the execvp, which is bad. If we set the close-on-exec to * false, the child end of the socket will be closed when the * child (or sub-) process exits. */ if (!writable && !readable && !catch_stderr) fcntl(socks[1], F_SETFD, 0); // never close the socketpair else ::close(socks[1]); // has already been duplicated // this will often fail, but when it does work it is probably // the Right Thing To Do (tm) if (!readable && stdout_fd != 1) { setsid(); // Only on some OSes will we find TIOCSCTTY to set the controlling tty. // On others, we need to use TCSETCTTY, but we are too lazy to implement that. #ifdef TIOCSCTTY ioctl(1, TIOCSCTTY, 1); #else # ifdef TCSETCTTY # warning You should implement TCSETCTTY here. Thanks! # endif #endif } ::close(waitfd); // now run the program. If it fails, use _exit() so no destructors // get called and make a mess. execvp(program, (char * const *)argv); _exit(242); } else if (pid > 0) { // parent process. // now that we've forked, it's okay to close this fd if we fork again. fcntl(socks[0], F_SETFD, 1); ::close(socks[1]); } else { ::close(socks[0]); ::close(socks[1]); return; } } // send the child process a signal void WvPipe::kill(int signum) { if (proc.running) proc.kill(signum); } // wait for the child to die int WvPipe::finish(bool wait_children) { shutdown(getwfd(), SHUT_WR); close(); while (proc.running) proc.wait(1000, wait_children); return proc.estatus; } bool WvPipe::child_exited() { /* FIXME: bug in WvSubProc? */ proc.wait(0); proc.wait(0); return !proc.running; } // if child_exited(), return true if it died because of a signal, or // false if it died due to a call to exit(). bool WvPipe::child_killed() const { int st = proc.estatus; assert (WIFEXITED(st) || WIFSIGNALED(st)); return WIFSIGNALED(st); } // return the numeric exit status of the child (if it exited) or the // signal that killed the child (if it was killed). int WvPipe::exit_status() { /* FIXME: bug in WvSubProc? */ proc.wait(0); proc.wait(0); int st = proc.estatus; assert (WIFEXITED(st) || WIFSIGNALED(st)); if (child_killed()) return WTERMSIG(st); else return WEXITSTATUS(st); } WvPipe::~WvPipe() { close(); } // this is necessary when putting, say, sendmail through a WvPipe on the // globallist so we can forget about it. We call nowrite() so that it'll // get the EOF and then go away when it's done, but we need to read from it // for it the WvPipe stop selecting true and get deleted. void WvPipe::ignore_read(WvStream& s) { char buf[512]; s.read(&buf, sizeof(buf)); } wvstreams-4.6.1/streams/wvlogstream.cc0000644000175000001440000000045711036722347017144 0ustar wlachusers#include "wvlogstream.h" WvLogStream::WvLogStream(IWvStream *s, WvLog::LogLevel _max_level) : WvLogRcv(_max_level) { cloned = s; } WvLogStream::~WvLogStream() { WVRELEASE(cloned); } void WvLogStream::_mid_line(const char *str, size_t len) { if (cloned) cloned->write(str, len); } wvstreams-4.6.1/streams/wvloopback.cc0000644000175000001440000000144711036722347016741 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of the WvLoopback stream. WvLoopback uses a * socketpair() to create a stream that allows you to read() * everything written to it, even (especially) across a fork() call. */ #include "wvloopback.h" #include "wvsocketpair.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(WvLoopback); static IWvStream *create_loopback(WvStringParm, IObject *) { return new WvLoopback(); } static WvMoniker reg("loop", create_loopback); WvLoopback::WvLoopback() { int socks[2]; if (wvsocketpair(SOCK_STREAM, socks)) { seterr(errno); return; } rfd = socks[0]; wfd = socks[1]; set_close_on_exec(true); set_nonblock(true); } wvstreams-4.6.1/streams/wvdaemon.cc0000644000175000001440000001756511077124114016413 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * High-level abstraction for creating daemon processes. Handles * command-line argument processing, forking into the background, * and signal handling. */ #include "wvdaemon.h" #include "wvlinklist.h" #include "wvsyslog.h" #ifndef _WIN32 #include "wvcrash.h" #include "wvcrashlog.h" #include "wvfile.h" #include "wvatomicfile.h" #include #include #include #include #else #include "wvlogrcv.h" #endif #ifndef _WIN32 # define CAN_SYSLOG true # define CAN_DAEMONIZE true #else # define CAN_SYSLOG false # define CAN_DAEMONIZE false #endif #ifdef _MSC_VER static const int STDOUT_FILENO = 0; #endif WvDaemon *WvDaemon::singleton = NULL; #ifndef _WIN32 static void sighup_handler(int signum) { signal(signum, SIG_IGN); WvDaemon::me()->log(WvLog::Notice, "Restarting on signal %s.\n", signum); WvDaemon::me()->restart(); } static void sigterm_handler(int signum) { signal(signum, SIG_DFL); WvDaemon::me()->log(WvLog::Notice, "Dying on signal %s.\n", signum); WvDaemon::me()->die(); } static void sigquit_handler(int signum) { signal(signum, SIG_IGN); exit(1); } #endif // _WIN32 void WvDaemon::init(WvStringParm _name, WvStringParm _version, WvDaemonCallback _start_callback, WvDaemonCallback _run_callback, WvDaemonCallback _stop_callback) { name = _name; version = _version; pid_file = WvString("/var/run/%s.pid", _name); daemonize = false; log_level = WvLog::Info; syslog = false; start_callback = _start_callback; run_callback = _run_callback; stop_callback = _stop_callback; assert(singleton == NULL); singleton = this; args.add_option('q', "quiet", "Decrease log level (can be used multiple times)", wv::bind(&WvDaemon::dec_log_level, this, _1)); args.add_option('v', "verbose", "Increase log level (can be used multiple times)", wv::bind(&WvDaemon::inc_log_level, this, _1)); if (CAN_DAEMONIZE) args.add_option('d', "daemonize", "Fork into background and return (implies --syslog)", wv::bind(&WvDaemon::set_daemonize, this, _1)); if (CAN_SYSLOG) { args.add_set_bool_option('s', "syslog", "Write log entries to syslog", syslog); args.add_reset_bool_option(0, "no-syslog", "Do not write log entries to syslog", syslog); } args.set_version(WvString("%s version %s", name, version).cstr()); } WvDaemon::~WvDaemon() { } int WvDaemon::run(const char *argv0) { #ifndef _WIN32 if (CAN_DAEMONIZE && daemonize) { pid_t pid = ::fork(); if (pid < 0) { wverr->print("Failed to fork daemon: %s\n", strerror(errno)); return 3; } else if (pid == 0) { setsid(); pid = fork(); if (pid < 0) { wverr->print("Failed to double-fork daemon: %s\n", strerror(errno)); } else if (pid == 0) { // FIXME: this happens *before* we do the daemon setup! // We should only fork into the background *after* doing // things like opening our listen sockets. ::chdir("/"); ::umask(0); int null_fd; do { null_fd = ::open("/dev/null", O_RDWR); if (null_fd == -1) { log(WvLog::Error, "Failed to open /dev/null: %s\n", strerror(errno)); _exit(1); } } while (null_fd == 0 || null_fd == 1 || null_fd == 2); if (::dup2(null_fd, 0) == -1 || ::dup2(null_fd, 1) == -1 || ::dup2(null_fd, 2) == -1) { log(WvLog::Error, "Failed to dup2(null_fd, (0|1|2)): %s\n", strerror(errno)); _exit(1); } ::close(null_fd); // Make sure the close-on-exec flag is not set for // the first three descriptors, since many programs // assume that they are open after exec() if (::fcntl(0, F_SETFD, 0) == -1 || ::fcntl(1, F_SETFD, 0) == -1 || ::fcntl(2, F_SETFD, 0) == -1) { log(WvLog::Warning, "Failed to fcntl((0|1|2), F_SETFD, 0): %s\n", strerror(errno)); } return _run(argv0); // Make sure destructors are called } _exit(0); } return 0; } else #endif // !_WIN32 { WvLogConsole console_log(STDOUT_FILENO, log_level); if (CAN_SYSLOG && syslog) { WvSyslog syslog(name, false); return _run(argv0); } else return _run(argv0); } } int WvDaemon::run(int argc, char **argv) { if (!args.process(argc, argv, &_extra_args)) return 1; return run(argv[0]); } int WvDaemon::_run(const char *argv0) { WvLogRcv *logr = NULL; #ifndef _WIN32 WvCrashLog crashlog; wvcrash_setup(argv0, version); #endif if (CAN_SYSLOG && syslog) logr = new WvSyslog(name, false); _want_to_die = false; do_load(); while (!want_to_die()) { _want_to_restart = false; do_start(); while (should_run()) do_run(); do_stop(); } do_unload(); if (logr) delete logr; return _exit_status; } void WvDaemon::do_load() { #ifndef _WIN32 if (!!pid_file && daemonize) { // FIXME: this is racy! // First, make sure we aren't already running WvFile old_pid_fd(pid_file, O_RDONLY); if (old_pid_fd.isok()) { WvString line = old_pid_fd.getline(0); if (!!line) { pid_t old_pid = line.num(); if (old_pid > 0 && (kill(old_pid, 0) == 0 || errno == EPERM)) { log(WvLog::Error, "%s is already running (pid %s); exiting\n", name, old_pid); die(); } } } old_pid_fd.close(); if (want_to_die()) return; // Now write our new PID file WvAtomicFile pid_fd(pid_file, O_WRONLY, 0600); pid_fd.print("%s\n", getpid()); if (!pid_fd.isok()) log(WvLog::Warning, "Failed to write PID file %s: %s\n", pid_file, pid_fd.errstr()); pid_fd.close(); } #endif log(WvLog::Notice, "Starting %s version %s.\n", name, version); #ifndef _WIN32 if (daemonize) signal(SIGINT, SIG_IGN); else signal(SIGINT, sigterm_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigquit_handler); signal(SIGHUP, sighup_handler); #endif if (load_callback) load_callback(); } void WvDaemon::do_start() { if (start_callback) start_callback(); } void WvDaemon::do_run() { if (run_callback) run_callback(); } void WvDaemon::do_stop() { if (stop_callback) stop_callback(); } void WvDaemon::do_unload() { if (unload_callback) unload_callback(); #ifndef _WIN32 signal(SIGHUP, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); #endif log(WvLog::Notice, "Exiting with status %s\n", _exit_status); #ifndef _WIN32 if (!!pid_file && daemonize) ::unlink(pid_file); #endif } bool WvDaemon::set_daemonize(void *) { daemonize = true; syslog = true; return true; } wvstreams-4.6.1/streams/wvfdstream.cc0000644000175000001440000001473111036722347016754 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Base class for streams built on Unix file descriptors. */ #include "wvfdstream.h" #include "wvmoniker.h" #include #ifndef _WIN32 #include inline bool isselectable(int fd) { return true; } #else // _WIN32 #define getsockopt(a,b,c,d,e) getsockopt(a,b,c,(char *)d, e) #define SHUT_RD SD_RECEIVE #define SHUT_WR SD_SEND #define ENOBUFS WSAENOBUFS #undef EAGAIN #define EAGAIN WSAEWOULDBLOCK #include "streams.h" #undef errno #define errno GetLastError() // in win32, only sockets can be in the FD_SET for select() static inline bool isselectable(int s) { // if _get_osfhandle() works, it's a msvcrt fd, not a winsock handle. // msvcrt fds can't be select()ed on correctly. return ((HANDLE)_get_osfhandle(s) == INVALID_HANDLE_VALUE) ? true : false; } #endif // _WIN32 /***** WvFdStream *****/ static IWvStream *creator(WvStringParm s, IObject *) { return new WvFdStream(s.num()); } static WvMoniker reg("fd", creator); WvFdStream::WvFdStream(int _rwfd) : rfd(_rwfd), wfd(_rwfd) { shutdown_read = shutdown_write = false; } WvFdStream::WvFdStream(int _rfd, int _wfd) : rfd(_rfd), wfd(_wfd) { shutdown_read = shutdown_write = false; } WvFdStream::~WvFdStream() { close(); } static int _cloexec(int fd, bool close_on_exec) { #ifndef _WIN32 // there is no exec() in win32, so this is meaningless there return fcntl(fd, F_SETFD, close_on_exec ? FD_CLOEXEC : 0); #else return 0; #endif } static int _nonblock(int fd, bool nonblock) { #ifndef _WIN32 int flag = fcntl(fd, F_GETFL); return fcntl(fd, F_SETFL, (flag & ~O_NONBLOCK) | (nonblock ? O_NONBLOCK : 0)); #else u_long arg = nonblock ? 1 : 0; return ioctlsocket(fd, FIONBIO, &arg); #endif } void WvFdStream::set_nonblock(bool nonblock) { int rfd = getrfd(), wfd = getwfd(); if (rfd >= 0) _nonblock(rfd, nonblock); if (wfd >= 0 && rfd != wfd) _nonblock(wfd, nonblock); } void WvFdStream::set_close_on_exec(bool close_on_exec) { int rfd = getrfd(), wfd = getwfd(); if (rfd >= 0) _cloexec(rfd, close_on_exec); if (wfd >= 0 && rfd != wfd) _cloexec(wfd, close_on_exec); } void WvFdStream::close() { // fprintf(stderr, "closing fdstream!\n"); if (!closed) { WvStream::close(); //fprintf(stderr, "closing%d:%d/%d\n", (int)this, rfd, wfd); if (rfd >= 0) ::close(rfd); if (wfd >= 0 && wfd != rfd) ::close(wfd); rfd = wfd = -1; //fprintf(stderr, "closed!\n"); } } bool WvFdStream::isok() const { return WvStream::isok() && (rfd != -1 || wfd != -1); } size_t WvFdStream::uread(void *buf, size_t count) { assert(!count || buf); if (!count || !buf || !isok()) return 0; int in = ::read(rfd, buf, count); // a read that returns zero bytes signifies end-of-file (EOF). if (in <= 0) { if (in < 0 && (errno==EINTR || errno==EAGAIN || errno==ENOBUFS)) return 0; // interrupted seterr(in < 0 ? errno : 0); return 0; } // fprintf(stderr, "read %d bytes\n", in); return in; } size_t WvFdStream::uwrite(const void *buf, size_t count) { assert(!count || buf); if (!buf || !count || !isok()) return 0; // fprintf(stderr, "write %d bytes\n", count); int out = ::write(wfd, buf, count); if (out <= 0) { int err = errno; // fprintf(stderr, "(fd%d-err-%d)", wfd, err); if (out < 0 && (err == ENOBUFS || err==EAGAIN)) return 0; // kernel buffer full - data not written (yet!) seterr(out < 0 ? err : 0); // a more critical error return 0; } //TRACE("write obj 0x%08x, bytes %d/%d\n", (unsigned int)this, out, count); return out; } void WvFdStream::maybe_autoclose() { if (stop_write && !shutdown_write && !outbuf.used()) { shutdown_write = true; if (wfd < 0) return; if (rfd != wfd) ::close(wfd); else ::shutdown(wfd, SHUT_WR); // might be a socket wfd = -1; } if (stop_read && !shutdown_read && !inbuf.used()) { shutdown_read = true; if (rfd != wfd) ::close(rfd); else ::shutdown(rfd, SHUT_RD); // might be a socket rfd = -1; } WvStream::maybe_autoclose(); } void WvFdStream::pre_select(SelectInfo &si) { WvStream::pre_select(si); #if 0 fprintf(stderr, "%d/%d wr:%d ww:%d wx:%d inh:%d\n", rfd, wfd, si.wants.readable, si.wants.writable, si.wants.isexception, si.inherit_request); #endif if (si.wants.readable && (rfd >= 0)) { if (isselectable(rfd)) FD_SET(rfd, &si.read); else si.msec_timeout = 0; // not selectable -> *always* readable } // FIXME: outbuf flushing should really be in WvStream::pre_select() // instead! But it's hard to get the equivalent behaviour there. if ((si.wants.writable || outbuf.used() || autoclose_time) && (wfd >= 0)) { if (isselectable(wfd)) FD_SET(wfd, &si.write); else si.msec_timeout = 0; // not selectable -> *always* writable } if (si.wants.isexception) { if (rfd >= 0 && isselectable(rfd)) FD_SET(rfd, &si.except); if (wfd >= 0 && isselectable(wfd)) FD_SET(wfd, &si.except); } if (si.max_fd < rfd) si.max_fd = rfd; if (si.max_fd < wfd) si.max_fd = wfd; } bool WvFdStream::post_select(SelectInfo &si) { bool result = WvStream::post_select(si); // flush the output buffer if possible size_t outbuf_used = outbuf.used(); if (wfd >= 0 && (outbuf_used || autoclose_time) && FD_ISSET(wfd, &si.write) && should_flush()) { flush_outbuf(0); // flush_outbuf() might have closed the file! if (!isok()) return result; } bool rforce = si.wants.readable && !isselectable(rfd), wforce = si.wants.writable && !isselectable(wfd); bool val = (rfd >= 0 && (rforce || FD_ISSET(rfd, &si.read))) || (wfd >= 0 && (wforce || FD_ISSET(wfd, &si.write))) || (rfd >= 0 && (FD_ISSET(rfd, &si.except))) || (wfd >= 0 && (FD_ISSET(wfd, &si.except))); // fprintf(stderr, "fds_post_select: %d/%d %d/%d %d\n", // rfd, wfd, rforce, wforce, val); if (val && si.wants.readable && read_requires_writable && read_requires_writable->isok() && !read_requires_writable->select(0, false, true)) return result; if (val && si.wants.writable && write_requires_readable && write_requires_readable->isok() && !write_requires_readable->select(0, true, false)) return result; return val || result; } wvstreams-4.6.1/crypto/0000755000175000001440000000000011260431126014106 5ustar wlachuserswvstreams-4.6.1/crypto/wvocsp.cc0000644000175000001440000001111611100157013015727 0ustar wlachusers#include "wvocsp.h" #include "wvsslhacks.h" static const int OCSP_MAX_VALIDITY_PERIOD = (5 * 60); // 5 min: openssl default WvOCSPReq::WvOCSPReq(const WvX509 &cert, const WvX509 &issuer) { wvssl_init(); req = OCSP_REQUEST_new(); assert(req); if (cert.isok() && issuer.isok()) { id = OCSP_cert_to_id(NULL, cert.cert, issuer.cert); OCSP_request_add0_id(req, id); } } WvOCSPReq::~WvOCSPReq() { if (req) OCSP_REQUEST_free(req); wvssl_free(); } void WvOCSPReq::encode(WvBuf &buf) { BIO *bufbio = BIO_new(BIO_s_mem()); assert(bufbio); BUF_MEM *bm; // there is no reason why the following should fail, except for OOM assert(wv_i2d_OCSP_REQUEST_bio(bufbio, req) > 0); BIO_get_mem_ptr(bufbio, &bm); buf.put(bm->data, bm->length); BIO_free(bufbio); } WvOCSPResp::WvOCSPResp() : resp(NULL), bs(NULL), log("OCSP Response", WvLog::Debug5) { wvssl_init(); } WvOCSPResp::~WvOCSPResp() { if (bs) OCSP_BASICRESP_free(bs); if (resp) OCSP_RESPONSE_free(resp); wvssl_free(); } void WvOCSPResp::decode(WvBuf &encoded) { BIO *membuf = BIO_new(BIO_s_mem()); BIO_write(membuf, encoded.get(encoded.used()), encoded.used()); resp = d2i_OCSP_RESPONSE_bio(membuf, NULL); if (resp) bs = OCSP_response_get1_basic(resp); else log("Failed to decode response.\n"); BIO_free_all(membuf); } bool WvOCSPResp::isok() const { if (!resp) return false; int i = OCSP_response_status(resp); if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { log("Status not successful: %s\n", wvssl_errstr()); return false; } return true; } bool WvOCSPResp::check_nonce(const WvOCSPReq &req) const { if (!bs) return false; int i; if ((i = OCSP_check_nonce(req.req, bs)) <= 0) { if (i == -1) log("No nonce in response\n"); else log("Nonce verify error\n"); return false; } return true; } bool WvOCSPResp::signedbycert(const WvX509 &cert) const { EVP_PKEY *skey = X509_get_pubkey(cert.cert); int i = OCSP_BASICRESP_verify(bs, skey, 0); EVP_PKEY_free(skey); if(i > 0) return true; return false; } WvX509 WvOCSPResp::get_signing_cert() const { if (!bs || !sk_X509_num(bs->certs)) return WvX509(); // note: the following bit of code is taken almost verbatim from // ocsp_vfy.c in OpenSSL 0.9.8. Copyright and attribution should // properly belong to them OCSP_RESPID *id = bs->tbsResponseData->responderId; if (id->type == V_OCSP_RESPID_NAME) { X509 *x = X509_find_by_subject(bs->certs, id->value.byName); if (x) return WvX509(X509_dup(x)); } if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL; unsigned char tmphash[SHA_DIGEST_LENGTH]; unsigned char *keyhash = id->value.byKey->data; for (int i = 0; i < sk_X509_num(bs->certs); i++) { X509 *x = sk_X509_value(bs->certs, i); X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) return WvX509(X509_dup(x)); } return WvX509(); } WvOCSPResp::Status WvOCSPResp::get_status(const WvX509 &cert, const WvX509 &issuer) const { if (!isok()) return Error; if (!cert.isok() && !issuer.isok()) return Error; int status, reason; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; OCSP_CERTID *id = OCSP_cert_to_id(NULL, cert.cert, issuer.cert); assert(id); // only fails in case of OOM if(!OCSP_resp_find_status(bs, id, &status, &reason, &rev, &thisupd, &nextupd)) { log("OCSP Find Status Error: %s\n", wvssl_errstr()); OCSP_CERTID_free(id); return Error; } OCSP_CERTID_free(id); if (!OCSP_check_validity(thisupd, nextupd, OCSP_MAX_VALIDITY_PERIOD, -1)) { log("Error checking for OCSP validity: %s\n", wvssl_errstr()); return Error; } if (status == V_OCSP_CERTSTATUS_GOOD) return Good; else if (status == V_OCSP_CERTSTATUS_REVOKED) return Revoked; log("OCSP cert status is %s, marking as 'Unknown'.\n", OCSP_cert_status_str(status)); return Unknown; } WvString WvOCSPResp::status_str(WvOCSPResp::Status status) { if (status == Good) return "good"; else if (status == Error) return "error"; else if (status == Revoked) return "revoked"; return "unknown"; } wvstreams-4.6.1/crypto/wvcrl.cc0000644000175000001440000002521711077124114015563 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * X.509v3 CRL management classes. */ #include #include #include "wvcrl.h" #include "wvx509mgr.h" #include "wvbase64.h" static const char * warning_str_get = "Tried to determine %s, but CRL is blank!\n"; #define CHECK_CRL_EXISTS_GET(x, y) \ if (!crl) { \ debug(WvLog::Warning, warning_str_get, x); \ return y; \ } static ASN1_INTEGER * serial_to_int(WvStringParm serial) { if (!!serial) { BIGNUM *bn = NULL; BN_dec2bn(&bn, serial); ASN1_INTEGER *retval = ASN1_INTEGER_new(); retval = BN_to_ASN1_INTEGER(bn, retval); BN_free(bn); return retval; } return NULL; } WvCRL::WvCRL() : debug("X509 CRL", WvLog::Debug5) { crl = NULL; } WvCRL::WvCRL(const WvX509Mgr &ca) : debug("X509 CRL", WvLog::Debug5) { assert(crl = X509_CRL_new()); // Use Version 2 CRLs - Of COURSE that means // to set it to 1 here... grumble.. X509_CRL_set_version(crl, 1); X509_CRL_set_issuer_name(crl, X509_get_issuer_name(ca.cert)); // most of this copied from wvx509.cc, sigh ASN1_OCTET_STRING *ikeyid = NULL; X509_EXTENSION *ext; int i = X509_get_ext_by_NID(ca.cert, NID_subject_key_identifier, -1); if ((i >= 0) && (ext = X509_get_ext(ca.cert, i))) ikeyid = static_cast(X509V3_EXT_d2i(ext)); if (ikeyid) { AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new(); akeyid->issuer = NULL; akeyid->serial = NULL; akeyid->keyid = ikeyid; ext = X509V3_EXT_i2d(NID_authority_key_identifier, 0, akeyid); X509_CRL_add_ext(crl, ext, -1); X509_EXTENSION_free(ext); AUTHORITY_KEYID_free(akeyid); } // Sign the CRL and set some expiration params ca.signcrl(*this); } WvCRL::~WvCRL() { debug("Deleting.\n"); if (crl) X509_CRL_free(crl); } bool WvCRL::isok() const { return crl; } bool WvCRL::signedbyca(const WvX509 &cacert) const { CHECK_CRL_EXISTS_GET("if CRL is signed by CA", false); EVP_PKEY *pkey = X509_get_pubkey(cacert.cert); int result = X509_CRL_verify(crl, pkey); EVP_PKEY_free(pkey); if (result < 0) { debug("There was an error (%s) determining whether or not we were " "signed by CA '%s'\n", wvssl_errstr(), cacert.get_subject()); return false; } bool issigned = (result > 0); debug("CRL was%s signed by CA %s\n", issigned ? "" : " NOT", cacert.get_subject()); return issigned; } bool WvCRL::issuedbyca(const WvX509 &cacert) const { CHECK_CRL_EXISTS_GET("if CRL is issued by CA", false); WvString name = get_issuer(); bool issued = (cacert.get_subject() == name); if (issued) debug("CRL issuer '%s' matches subject '%s' of cert. We can say " "that it appears to be issued by this CA.\n", name, cacert.get_subject()); else debug("CRL issuer '%s' doesn't match subject '%s' of cert. Doesn't " "appear to be issued by this CA.\n", name, cacert.get_subject()); return issued; } bool WvCRL::expired() const { CHECK_CRL_EXISTS_GET("if CRL has expired", false); if (X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)) < 0) { debug("CRL appears to be expired.\n"); return true; } debug("CRL appears not to be expired.\n"); return false; } bool WvCRL::has_critical_extensions() const { CHECK_CRL_EXISTS_GET("if CRL has critical extensions", false); int critical = X509_CRL_get_ext_by_critical(crl, 1, 0); return (critical > 0); } WvString WvCRL::get_aki() const { CHECK_CRL_EXISTS_GET("CRL's AKI", WvString::null); AUTHORITY_KEYID *aki = NULL; int i; aki = static_cast( X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, &i, NULL)); if (aki) { char *tmp = hex_to_string(aki->keyid->data, aki->keyid->length); WvString str(tmp); OPENSSL_free(tmp); AUTHORITY_KEYID_free(aki); return str; } return WvString::null; } WvString WvCRL::get_issuer() const { CHECK_CRL_EXISTS_GET("CRL's issuer", WvString::null); char *name = X509_NAME_oneline(X509_CRL_get_issuer(crl), 0, 0); WvString retval(name); OPENSSL_free(name); return retval; } WvString WvCRL::encode(const DumpMode mode) const { WvDynBuf retval; encode(mode, retval); return retval.getstr(); } void WvCRL::encode(const DumpMode mode, WvBuf &buf) const { if (mode == CRLFileDER || mode == CRLFilePEM) return; // file modes are no ops with encode if (!crl) { debug(WvLog::Warning, "Tried to encode CRL, but CRL is blank!\n"); return; } BIO *bufbio = BIO_new(BIO_s_mem()); BUF_MEM *bm; switch (mode) { case CRLPEM: debug("Dumping CRL in PEM format.\n"); PEM_write_bio_X509_CRL(bufbio, crl); break; case CRLDER: debug("Dumping CRL in DER format.\n"); i2d_X509_CRL_bio(bufbio, crl); break; default: debug("Tried to dump CRL in unknown format!\n"); break; } BIO_get_mem_ptr(bufbio, &bm); buf.put(bm->data, bm->length); BIO_free(bufbio); } void WvCRL::decode(const DumpMode mode, WvStringParm str) { if (crl) { debug("Replacing already existant CRL.\n"); X509_CRL_free(crl); crl = NULL; } if (mode == CRLFileDER) { BIO *bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, str.cstr()) <= 0) { debug(WvLog::Warning, "Import CRL from '%s': %s\n", str, wvssl_errstr()); BIO_free(bio); return; } if (!(crl = d2i_X509_CRL_bio(bio, NULL))) debug(WvLog::Warning, "Read CRL from '%s': %s\n", str, wvssl_errstr()); BIO_free(bio); return; } else if (mode == CRLFilePEM) { FILE * fp = fopen(str, "rb"); if (!fp) { int errnum = errno; debug(WvLog::Warning, "open '%s': %s\n", str, strerror(errnum)); return; } if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL))) debug(WvLog::Warning, "Import CRL from '%s': %s\n", str, wvssl_errstr()); fclose(fp); return; } // we use the buffer decode functions for everything else WvDynBuf buf; buf.putstr(str); decode(mode, buf); } void WvCRL::decode(const DumpMode mode, WvBuf &buf) { if (crl) { debug("Replacing already existant CRL.\n"); X509_CRL_free(crl); crl = NULL; } if (mode == CRLFileDER || mode == CRLFilePEM) { decode(mode, buf.getstr()); return; } BIO *bufbio = BIO_new(BIO_s_mem()); BIO_write(bufbio, buf.get(buf.used()), buf.used()); if (mode == CRLPEM) { debug("Decoding CRL from PEM format.\n"); crl = PEM_read_bio_X509_CRL(bufbio, NULL, NULL, NULL); } else if (mode == CRLDER) { debug("Decoding CRL from DER format.\n"); crl = d2i_X509_CRL_bio(bufbio, NULL); } else debug(WvLog::Warning, "Attempted to decode unknown format.\n"); if (!crl) debug(WvLog::Warning, "Couldn't decode CRL.\n"); BIO_free(bufbio); } bool WvCRL::isrevoked(const WvX509 &cert) const { if (cert.cert) { debug("Checking to see if certificate with name '%s' and serial " "number '%s' is revoked.\n", cert.get_subject(), cert.get_serial()); return isrevoked(cert.get_serial()); } else { debug(WvLog::Error, "Given certificate to check revocation status, " "but certificate is blank. Declining.\n"); return true; } } bool WvCRL::isrevoked(WvStringParm serial_number) const { CHECK_CRL_EXISTS_GET("if certificate is revoked in CRL", false); if (!!serial_number) { ASN1_INTEGER *serial = serial_to_int(serial_number); if (serial) { X509_REVOKED mayberevoked; mayberevoked.serialNumber = serial; if (crl->crl->revoked) { int idx = sk_X509_REVOKED_find(crl->crl->revoked, &mayberevoked); ASN1_INTEGER_free(serial); if (idx >= 0) { debug("Certificate is revoked.\n"); return true; } else { debug("Certificate is not revoked.\n"); return false; } } else { ASN1_INTEGER_free(serial); debug("CRL does not have revoked list.\n"); return false; } } else debug(WvLog::Warning, "Can't convert serial number to ASN1 format. " "Saying it's not revoked.\n"); } else debug(WvLog::Warning, "Serial number for certificate is blank.\n"); debug("Certificate is not revoked (or could not determine whether it " "was).\n"); return false; } WvCRL::Valid WvCRL::validate(const WvX509 &cacert) const { if (!issuedbyca(cacert)) return NOT_THIS_CA; if (!signedbyca(cacert)) return NO_VALID_SIGNATURE; if (expired()) return EXPIRED; // neither we or openssl handles any critical extensions yet if (has_critical_extensions()) { debug("CRL has unhandled critical extensions.\n"); return UNHANDLED_CRITICAL_EXTENSIONS; } return VALID; } int WvCRL::numcerts() const { CHECK_CRL_EXISTS_GET("number of certificates in CRL", 0); STACK_OF(X509_REVOKED) *rev; rev = X509_CRL_get_REVOKED(crl); int certcount = sk_X509_REVOKED_num(rev); if (certcount < 0) certcount = 0; return certcount; } void WvCRL::addcert(const WvX509 &cert) { if (!crl) { debug(WvLog::Warning, "Tried to add certificate to CRL, but CRL is " "blank!\n"); return; } if (cert.isok()) { ASN1_INTEGER *serial = serial_to_int(cert.get_serial()); X509_REVOKED *revoked = X509_REVOKED_new(); ASN1_GENERALIZEDTIME *now = ASN1_GENERALIZEDTIME_new(); X509_REVOKED_set_serialNumber(revoked, serial); X509_gmtime_adj(now, 0); X509_REVOKED_set_revocationDate(revoked, now); // FIXME: We don't deal with the reason here... X509_CRL_add0_revoked(crl, revoked); ASN1_GENERALIZEDTIME_free(now); ASN1_INTEGER_free(serial); } else { debug(WvLog::Warning, "Tried to add a certificate to the CRL, but " "certificate is either bad or broken.\n"); } } wvstreams-4.6.1/crypto/wvrsa.cc0000644000175000001440000001760111036722347015575 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * RSA cryptography abstractions. */ #include #include #include #include "wvsslhacks.h" #include "wvrsa.h" #include "wvhex.h" #include "wvfileutils.h" /***** WvRSAKey *****/ WvRSAKey::WvRSAKey() : debug("RSA", WvLog::Debug5) { rsa = NULL; } WvRSAKey::WvRSAKey(const WvRSAKey &k) : debug("RSA", WvLog::Debug5) { priv = k.priv; if (!priv) rsa = RSAPublicKey_dup(k.rsa); else rsa = RSAPrivateKey_dup(k.rsa); } WvRSAKey::WvRSAKey(struct rsa_st *_rsa, bool _priv) : debug("RSA", WvLog::Debug5) { if (_rsa == NULL) { rsa = NULL; debug("Initializing with a NULL key.. are you insane?\n"); return; } rsa = _rsa; priv = _priv; } WvRSAKey::WvRSAKey(WvStringParm keystr, bool _priv) : debug("RSA", WvLog::Debug5) { rsa = NULL; if (_priv) decode(RsaHex, keystr); else decode(RsaPubHex, keystr); priv = _priv; } WvRSAKey::WvRSAKey(int bits) : debug("RSA", WvLog::Debug5) { rsa = RSA_generate_key(bits, 0x10001, NULL, NULL); priv = true; } WvRSAKey::~WvRSAKey() { if (rsa) RSA_free(rsa); } bool WvRSAKey::isok() const { return rsa && (!priv || RSA_check_key(rsa) == 1); } WvString WvRSAKey::encode(const DumpMode mode) const { WvString nil; WvDynBuf retval; encode(mode, retval); return retval.getstr(); } void WvRSAKey::encode(const DumpMode mode, WvBuf &buf) const { if (!rsa) { debug(WvLog::Warning, "Tried to encode RSA key, but RSA key is " "blank!\n"); return; } if (mode == RsaHex || mode == RsaPubHex) { WvDynBuf keybuf; if (mode == RsaHex && priv) { size_t size = i2d_RSAPrivateKey(rsa, NULL); unsigned char *key = keybuf.alloc(size); size_t newsize = i2d_RSAPrivateKey(rsa, & key); assert(size == newsize); } else { size_t size = i2d_RSAPublicKey(rsa, NULL); unsigned char *key = keybuf.alloc(size); size_t newsize = i2d_RSAPublicKey(rsa, & key); assert(size == newsize); } buf.putstr(WvString(WvHexEncoder().strflushbuf(keybuf, true))); } else { BIO *bufbio = BIO_new(BIO_s_mem()); BUF_MEM *bm; const EVP_CIPHER *enc = EVP_get_cipherbyname("rsa"); if (mode == RsaPEM) PEM_write_bio_RSAPrivateKey(bufbio, rsa, enc, NULL, 0, NULL, NULL); else if (mode == RsaPubPEM) PEM_write_bio_RSAPublicKey(bufbio, rsa); else debug(WvLog::Warning, "Should never happen: tried to encode RSA " "key with unsupported mode."); BIO_get_mem_ptr(bufbio, &bm); buf.put(bm->data, bm->length); BIO_free(bufbio); } } void WvRSAKey::decode(const DumpMode mode, WvStringParm encoded) { if (!encoded) return; WvDynBuf buf; buf.putstr(encoded); decode(mode, buf); } void WvRSAKey::decode(const DumpMode mode, WvBuf &encoded) { debug("Decoding RSA key.\n"); if (rsa) { debug("Replacing already existent RSA key.\n"); RSA_free(rsa); rsa = NULL; } priv = false; // we handle hexified keys a bit differently, since // OpenSSL has no built-in support for them... if (mode == RsaHex || mode == RsaPubHex) { // unhexify the supplied key WvDynBuf keybuf; if (!WvHexDecoder().flush(encoded, keybuf, true) || keybuf.used() == 0) { debug("Couldn't unhexify RSA key.\n"); return; } size_t keylen = keybuf.used(); const unsigned char *key = keybuf.get(keylen); // create the RSA struct if (mode == RsaHex) { rsa = wv_d2i_RSAPrivateKey(NULL, &key, keylen); priv = true; } else rsa = wv_d2i_RSAPublicKey(NULL, &key, keylen); return; } else { BIO *membuf = BIO_new(BIO_s_mem()); BIO_write(membuf, encoded.get(encoded.used()), encoded.used()); if (mode == RsaPEM) { rsa = PEM_read_bio_RSAPrivateKey(membuf, NULL, NULL, NULL); priv = true; } else if (mode == RsaPubPEM) rsa = PEM_read_bio_RSAPublicKey(membuf, NULL, NULL, NULL); else debug(WvLog::Warning, "Should never happen: tried to encode RSA " "key with unsupported mode."); BIO_free_all(membuf); } } /***** WvRSAEncoder *****/ WvRSAEncoder::WvRSAEncoder(Mode _mode, const WvRSAKey & _key) : mode(_mode), key(_key) { if (key.isok() && key.rsa != NULL) rsasize = RSA_size(key.rsa); else rsasize = 0; // BAD KEY! (should assert but would break compatibility) } WvRSAEncoder::~WvRSAEncoder() { } bool WvRSAEncoder::_reset() { return true; } bool WvRSAEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { if (rsasize == 0) { // IGNORE BAD KEY! in.zap(); return false; } bool success = true; switch (mode) { case Encrypt: case SignEncrypt: { // reserve space for PKCS1_PADDING const size_t maxchunklen = rsasize - 12; size_t chunklen; while ((chunklen = in.used()) != 0) { if (chunklen >= maxchunklen) chunklen = maxchunklen; else if (! flush) break; // encrypt a chunk const unsigned char *data = in.get(chunklen); unsigned char *crypt = out.alloc(rsasize); size_t cryptlen = (mode == Encrypt) ? RSA_public_encrypt(chunklen, const_cast(data), crypt, key.rsa, RSA_PKCS1_PADDING) : RSA_private_encrypt(chunklen, const_cast(data), crypt, key.rsa, RSA_PKCS1_PADDING); if (cryptlen != rsasize) { out.unalloc(rsasize); success = false; } } break; } case Decrypt: case SignDecrypt: { const size_t chunklen = rsasize; while (in.used() >= chunklen) { // decrypt a chunk const unsigned char *crypt = in.get(chunklen); unsigned char *data = out.alloc(rsasize); int cryptlen = (mode == Decrypt) ? RSA_private_decrypt(chunklen, const_cast(crypt), data, key.rsa, RSA_PKCS1_PADDING) : RSA_public_decrypt(chunklen, const_cast(crypt), data, key.rsa, RSA_PKCS1_PADDING); if (cryptlen == -1) { out.unalloc(rsasize); success = false; } else out.unalloc(rsasize - cryptlen); } // flush does not make sense for us here if (flush && in.used() != 0) success = false; break; } } return success; } /***** WvRSAStream *****/ WvRSAStream::WvRSAStream(WvStream *_cloned, const WvRSAKey &_my_key, const WvRSAKey &_their_key, WvRSAEncoder::Mode readmode, WvRSAEncoder::Mode writemode) : WvEncoderStream(_cloned) { readchain.append(new WvRSAEncoder(readmode, _my_key), true); writechain.append(new WvRSAEncoder(writemode, _their_key), true); if (_my_key.isok() && _my_key.rsa) min_readsize = RSA_size(_my_key.rsa); } wvstreams-4.6.1/crypto/tests/0000755000175000001440000000000011260431131015244 5ustar wlachuserswvstreams-4.6.1/crypto/tests/printcert.cc0000644000175000001440000000536711057766345017626 0ustar wlachusers#include "wvargs.h" #include "wvcrash.h" #include "wvfile.h" #include "wvlog.h" #include "wvstrutils.h" #include "wvx509.h" #include "wvautoconf.h" void print_details(WvX509 *x509) { wvcon->print("Subject: %s\n", x509->get_subject()); wvcon->print("Issuer: %s\n", x509->get_issuer()); wvcon->print("Serial: %s\n", x509->get_serial()); time_t t1 = x509->get_notvalid_before(); time_t t2 = x509->get_notvalid_after(); wvcon->print("Not Valid Before: %s\n", ctime(&t1)); wvcon->print("Not Valid After: %s\n", ctime(&t2)); wvcon->print("Key Usage: %s\n", x509->get_key_usage()); wvcon->print("Ext Key Usage: %s\n", x509->get_ext_key_usage()); wvcon->print("Authority Info Access: \n%s\n", x509->get_aia()); WvStringList list; x509->get_ca_urls(list); wvcon->print("CA Issuers available from:\n%s\n", list.join("\n")); list.zap(); x509->get_ocsp(list); wvcon->print("OCSP Responders available from:\n%s\n", list.join("\n")); list.zap(); x509->get_crl_urls(list); wvcon->print("CRL Distribution Points:\n%s\n", list.join("\n")); list.zap(); x509->get_policies(list); wvcon->print("Certificate Policy OIDs:\n%s\n", list.join("\n")); #ifdef HAVE_OPENSSL_POLICY_MAPPING int requireExplicitPolicy, inhibitPolicyMapping; x509->get_policy_constraints(requireExplicitPolicy, inhibitPolicyMapping); wvcon->print("Certificate Policy Constraints: requireExplicitPolicy: %s " "inhibitPolicyMapping: %s\n", requireExplicitPolicy, inhibitPolicyMapping); WvX509::PolicyMapList maplist; x509->get_policy_mapping(maplist); wvcon->print("Policy mappings:\n"); WvX509::PolicyMapList::Iter i(maplist); for (i.rewind(); i.next();) wvcon->print("%s -> %s\n", i().issuer_domain, i().subject_domain); #endif } int main(int argc, char **argv) { wvcrash_setup(argv[0]); WvString certtype = "pem"; WvStringList remaining_args; WvArgs args; args.add_required_arg("certificate"); args.add_option('t', "type", "Certificate type: der or pem (default: pem)", "type", certtype); if (!args.process(argc, argv, &remaining_args) || remaining_args.count() < 1) { args.print_help(argc, argv); return -1; } // FIXME: not working yet #if 0 WvX509 x509; if (certtype == "der") x509.load(WvX509Mgr::CertDER, remaining_args.popstr()); else if (certtype == "pem") x509.load(WvX509Mgr::CertPEM, remaining_args.popstr()); else { wverr->print("Invalid certificate type '%s'\n", certtype); return -1; } if (x509.isok()) print_details(&x509); else wverr->print("X509 certificate not valid\n"); #endif return 0; } wvstreams-4.6.1/crypto/tests/cryptotest.cc0000644000175000001440000002432111036722347020012 0ustar wlachusers/* * Test WvCryptoStream classes by encrypting or decrypting stdin * and writing to stdout. * * This should let us get an impression of how fast the cryptostreams are, and * how much latency they introduce. * * This test case BADLY needs to be rewritten. */ #include "wvcrypto.h" #include "wvrsa.h" #include "wvblowfish.h" #include "wvtripledes.h" #include "wvxor.h" #include "wvcountermode.h" #include "wvdigest.h" #include "wvhex.h" #include "wvlog.h" #include "wvtimeutils.h" #include "wvistreamlist.h" #include #define PRIVATE_KEY "3082025b02010002818100b0873b623907cffea3aebca4815e579d06"\ "217f8c79f4992776a0efcd4223df678266c03936af92282b0b8233a0"\ "0d538a36b8b02800cbb5908e47af45b378091fd51b8c36f78372526d"\ "149d621ba2b538d5ad21b5523c36801f6735f504ee068da5821b13f1"\ "3ca4966503a9712792a77dfe80cd8b9cc35efc2aae2033605aeb1b02"\ "010302818075af7cec260535546d1f286dab943a68aec0ffb2fbf866"\ "1a4f15f533816d3f9a56ef2ad0cf1fb6c57207ac226ab38d06cf25ca"\ "c555dd23b5b42fca2e77a55b697142efd8b9ce56d244162ed7c16cfc"\ "65b77cd0386beac17a77bfb9f1a51db5b64981c6b238032213790ba1"\ "f9b76ab3c65d6674d2b9a1c3ef0ba05f855f6cfdeb024100ea833de9"\ "b8b6ed75f76c151fc1fe3462944ff5f081dbd5f8c7d17b6c52cb3359"\ "2b92921c7a736db8d2a7cc57e86da6885206dfe06b72fcc6efd57398"\ "3dd893b1024100c0b3e688281702a10f8741feb781063dae21f3702e"\ "803e4fa3f6239e3a7642a30bacdeec22c483c05cca6a22ac04f34c20"\ "603e6f1addbc4ea9681d53135eda8b0241009c577e9bd079f3a3fa48"\ "0e152bfecd970d8aa3f5abe7e3fb2fe0fcf2e1dccce61d0c616851a2"\ "4925e1c532e5459e6f058c04954047a1fdd9f538f7bad3e5b7cb0241"\ "008077ef05700f57160a5a2bff2500aed3c96bf7a01f00298a6d4ec2"\ "697c4ed7175d1de9f2c1d857d593319c171d58a232c040299f673e7d"\ "89c64568e20ce9e70702406fb58e17541b988269c2e739063bfa836f"\ "98493c0d43791cf3ee8374e51c6d519ec08194e5c482362126a8b805"\ "758ea0ee40f3a36c947bb4d957b51ac56430ab" extern char *optarg; static void usage(WvLog &log, const char *progname) { log.lvl(WvLog::Error); log("Usage: %s -x|-r|-b|-d [-E|-D]\n" " where -x is for an XOREncoder test\n" " -r is for an RSAEncoder test\n" " -b is for a BlowfishEncoder test\n" " -d is for a TripleDESEncoder test\n" " -c is for a CounterModeEncoder Blowfish test\n" " -M is for a MD5Digest test\n" " -S is for a SHA1Digest test\n" " -H is for a HMACDigest over SHA1Digest test\n" " -E encrypts stdin (default)\n" " -D decrypts stdin (makes no sense for digests)\n" " -i XXX sets the input file\n" " -o XXX sets the output file\n", progname); } size_t copy(WvStream *in, WvStream *out) { size_t total = 0; char buf[10240]; WvIStreamList slist; slist.append(in, false, "in"); slist.append(out, false, "out"); while (in->isok() && out->isok()) { if (slist.select(-1)) slist.callback(); size_t len = in->read(buf, sizeof(buf)); if (len != 0) { total += len; out->write(buf, len); } } out->flush(0); return total; } int main(int argc, char **argv) { WvLog log(argv[0], WvLog::Info); int opt; enum { None, XOR, RSA, Blowfish, CounterMode, MD5, SHA1, HMAC, TripleDES } crypt_type = None; enum { Encrypt, Decrypt } direction = Encrypt; WvRSAKey *rsakey = NULL; unsigned char *blowkey = NULL, *deskey1 = NULL, *deskey2 = NULL, *deskey3 = NULL; WvStreamClone *crypto; int numbits = 0; struct timeval start, stop; struct timezone tz; WvStream *in = NULL; WvStream *out = NULL; if (argc < 2) { usage(log, argv[0]); return 1; } while ((opt = getopt(argc, argv, "?xrbcdMSHEDB:i:o:")) >= 0) { switch (opt) { case '?': usage(log, argv[0]); return 2; case 'x': crypt_type = XOR; numbits = 8; break; case 'r': crypt_type = RSA; if (!numbits) numbits = 1024; break; case 'b': crypt_type = Blowfish; if (!numbits) numbits = 128; break; case 'd': crypt_type = TripleDES; numbits = 192; break; case 'c': crypt_type = CounterMode; if (!numbits) numbits = 128; break; case 'M': crypt_type = MD5; numbits = 128; direction = Decrypt; break; case 'S': crypt_type = SHA1; numbits = 160; direction = Decrypt; break; case 'H': crypt_type = HMAC; if (!numbits) numbits = 128; direction = Decrypt; break; case 'E': direction = Encrypt; break; case 'D': direction = Decrypt; break; case 'B': numbits = atoi(optarg); break; case 'i': WVRELEASE(in); in = new WvFile(optarg, O_RDONLY); break; case 'o': WVRELEASE(out); out = new WvFile(optarg, O_WRONLY | O_CREAT); break; } } if (! in) in = wvin; if (! out) out = wvout; if (crypt_type == None) { log(WvLog::Error, "No encryption type specified on command line.\n"); usage(log, argv[0]); return 4; } if (!numbits || numbits < 8 || numbits > 4096) { log(WvLog::Error, "Invalid key size: %s bits.\n", numbits); return 5; } WvStreamClone *base; if (direction == Encrypt) base = new WvStreamClone((out->addRef(), out)); else base = new WvStreamClone((in->addRef(), in)); switch (crypt_type) { case XOR: { log("Using 8-bit XOR encryption.\n"); char key = 1; crypto = new WvXORStream(base, &key, 1); break; } case RSA: numbits = 1024; log("Using %s-bit RSA encryption.\n", numbits); //log("Generating key..."); //rsakey = new WvRSAKey(numbits); //log("ok.\n"); rsakey = new WvRSAKey(PRIVATE_KEY, true); crypto = new WvRSAStream(base, *rsakey, *rsakey); break; case Blowfish: log("Using %s-bit Blowfish encryption.\n", numbits); blowkey = new unsigned char[numbits/8]; for (int count = 0; count < numbits/8; count++) blowkey[count] = count; crypto = new WvBlowfishStream(base, blowkey, numbits/8); break; case TripleDES: { const char *private_key = PRIVATE_KEY; log("Using %s-bit TripleDES encryption.\n", numbits); deskey1 = new unsigned char[DES_KEY_SZ]; memcpy(deskey1, private_key, DES_KEY_SZ); deskey2 = new unsigned char[DES_KEY_SZ]; memcpy(deskey1, private_key + DES_KEY_SZ, DES_KEY_SZ); deskey3 = new unsigned char[DES_KEY_SZ]; memcpy(deskey1, private_key + DES_KEY_SZ * 2, DES_KEY_SZ); crypto = new WvTripleDESStream(base, deskey1, deskey2, deskey3); break; } case CounterMode: { log("Using %s-bit Counter Mode Blowfish encryption.\n", numbits); unsigned char blowkey[numbits/8]; for (int count = 0; count < numbits/8; count++) blowkey[count] = count; WvEncoder *enc = new WvCounterModeEncoder( new WvBlowfishEncoder(WvBlowfishEncoder::ECBEncrypt, blowkey, numbits / 8), "\0\0\0\0\0\0\0\0", 8); WvEncoderStream *encstream = new WvEncoderStream(base); encstream->writechain.append(enc, true); encstream->readchain.append(enc, false); encstream->auto_flush(false); crypto = encstream; break; } case MD5: { log("Using MD5 digest.\n"); WvEncoder *enc = new WvMD5Digest(); WvEncoder *hex = new WvHexEncoder(); WvEncoderStream *encstream = new WvEncoderStream(base); encstream->writechain.append(enc, true); encstream->writechain.append(hex, true); encstream->readchain.append(enc, false); encstream->readchain.append(hex, false); encstream->auto_flush(false); crypto = encstream; break; } case SHA1: { log("Using SHA1 digest.\n"); WvEncoder *enc = new WvSHA1Digest(); WvEncoder *hex = new WvHexEncoder(); WvEncoderStream *encstream = new WvEncoderStream(base); encstream->writechain.append(enc, true); encstream->writechain.append(hex, true); encstream->readchain.append(enc, false); encstream->readchain.append(hex, false); encstream->auto_flush(false); crypto = encstream; break; } case HMAC: { unsigned char key[numbits/8]; for (int count = 0; count < numbits/8; count++) key[count] = count; log("Using HMAC over SHA1 digest.\n"); WvEncoder *enc = new WvHMACDigest(new WvSHA1Digest(), key, numbits / 8); WvEncoder *hex = new WvHexEncoder(); WvEncoderStream *encstream = new WvEncoderStream(base); encstream->writechain.append(enc, true); encstream->writechain.append(hex, true); encstream->readchain.append(enc, false); encstream->readchain.append(hex, false); encstream->auto_flush(false); crypto = encstream; break; } default: assert(0); break; } gettimeofday(&start, &tz); size_t total; if (direction == Encrypt) { log("Encrypting stdin to stdout.\n"); total = copy(in, crypto); } else { log("Decrypting stdin to stdout.\n"); total = copy(crypto, out); } crypto->close(); WVRELEASE(crypto); if (in != base && in != wvin) WVRELEASE(in); if (out != base && out != wvout) WVRELEASE(out); gettimeofday(&stop, &tz); long tdiff = msecdiff(stop, start); log("Processed %s bytes in %s.%03s seconds.\n" "Transfer rate: %s kbytes/sec.\n", total, tdiff/1000, tdiff % 1000, (int)(1000.0 * total / tdiff / 1024)); if (rsakey) delete rsakey; if (blowkey) deletev blowkey; } wvstreams-4.6.1/crypto/tests/ssltest.cc0000644000175000001440000000365111036722347017276 0ustar wlachusers#include "wvargs.h" #include "wvistreamlist.h" #include "wvsslstream.h" #include "wvstrutils.h" #include "wvtcp.h" #include "wvx509mgr.h" #include volatile bool want_to_die = false; void sighandler_die(int sig) { fprintf(stderr,"Exiting on signal %d.\n", sig); want_to_die = true; signal(sig, SIG_DFL); } int main(int argc, char **argv) { signal(SIGINT, sighandler_die); signal(SIGTERM, sighandler_die); signal(SIGPIPE, SIG_IGN); WvLog log("ssltest", WvLog::Info); WvString pkcs12file, pkcs12pass; WvX509Mgr *x509 = NULL; WvArgs args; args.add_option('c', "certificate", "Identify self using the specified " "certificate and key pair (in pkcs12 format)", "FILE", pkcs12file); args.add_option('p', "password", "Password for opening the specified " "certificate (if given)", "PASS", pkcs12pass); args.add_required_arg("HOST:PORT", false); WvStringList remaining_args; if (!args.process(argc, argv, &remaining_args)) return 1; WvString target = remaining_args.popstr(); if (!!pkcs12file) { x509 = new WvX509Mgr; x509->read_p12(pkcs12file, pkcs12pass); if (!x509->isok()) { log(WvLog::Error, "Couldn't load certificate! (did you specify a password?)\n"); return 1; } } log("Connecting to %s...\n", target); WvSSLStream *cli = new WvSSLStream(new WvTCPConn(target), x509); WvIStreamList::globallist.append(cli, false, "client"); WvIStreamList::globallist.append(wvin, false, "wvin"); cli->autoforward(*wvout); wvin->autoforward(*cli); while (cli->isok() && !want_to_die) WvIStreamList::globallist.runonce(); if (cli->geterr()) log("Stream closed with error: %s\n", cli->errstr()); log("Done!\n"); WVRELEASE(cli); WVRELEASE(x509); return 0; } wvstreams-4.6.1/crypto/tests/md5test.cc0000644000175000001440000000125011036722347017153 0ustar wlachusers#include "wvlog.h" #include "wvdigest.h" #include "wvhex.h" #include "wvfile.h" // Quick program to test the MD5 Routines... int main() { free(malloc(1)); // For Electric Fence... WvString request = "md5test"; WvDynBuf md5buf; WvMD5Digest md5; WvLog log("MD5test", WvLog::Info); log("Starting...\n"); WvFile file(request, O_RDONLY); WvDynBuf filein; while (file.isok()) { file.read(filein, 1024); md5.encode(filein, md5buf); } md5.finish(md5buf); WvString md5str = WvHexEncoder().strflushbuf(md5buf, true); log("%s -> %s\n", request, md5str); log("Done...\n"); } wvstreams-4.6.1/crypto/tests/sslsrvtest.cc0000644000175000001440000000572311036722347020033 0ustar wlachusers#include "wvargs.h" #include "wvcrash.h" #include "wvistreamlist.h" #include "wvlog.h" #include "wvsslstream.h" #include "wvstrutils.h" #include "wvtcplistener.h" #include "wvx509mgr.h" #include static bool want_to_die = false; static const int DEFAULT_KEYSIZE = 1024; bool validateme(WvX509 *x509) { if (x509 && x509->isok()) { wvcon->print("X509 Subject: %s\n", x509->get_subject()); return true; } else { wvcon->print("X509 Error: %s\n", x509->errstr()); return false; } } void sighandler_die(int sig) { fprintf(stderr, "Exiting on signal %d.\n", sig); want_to_die = true; signal(sig, SIG_DFL); } static void bounce_to_list(IWvStream *s) { char buf[1024]; size_t len; len = s->read(buf, sizeof(buf)); WvIStreamList::Iter i(WvIStreamList::globallist); for (i.rewind(); i.next(); ) if (i.ptr() != s) i->write(buf, len); } static void tcp_incoming(WvX509Mgr *x509, IWvStream *s) { WvSSLStream *sslsrvr = new WvSSLStream(s, x509, validateme, true); WvIStreamList::globallist.append(sslsrvr, true, "ss tcp"); sslsrvr->setcallback(wv::bind(bounce_to_list, s)); } int main(int argc, char **argv) { wvcrash_setup(argv[0]); WvLog log("SSL-Server", WvLog::Info); WvX509Mgr *x509cert; WvString pkcs12file; WvString pkcs12pass = "123"; signal(SIGINT, sighandler_die); signal(SIGTERM, sighandler_die); signal(SIGPIPE, SIG_IGN); WvArgs args; args.add_option('c', "certificate", "Identify self using the specified " "certificate and key pair (in pkcs12 format)", "FILE", pkcs12file); args.add_option('p', "password", "Password for opening the specified " "certificate (if given)", "PASS", pkcs12pass); WvStringList remaining_args; if (!args.process(argc, argv, &remaining_args)) return 1; if (!!pkcs12file) { x509cert = new WvX509Mgr; x509cert->read_p12(pkcs12file, pkcs12pass); } else { WvString dName = encode_hostname_as_DN(fqdomainname()); x509cert = new WvX509Mgr(dName, DEFAULT_KEYSIZE); } if (!x509cert->isok()) { log("X509 certificate + rsa pair not ok!\n"); return 1; } WvTCPListener tcplisten("0.0.0.0:5238"); tcplisten.onaccept(wv::bind(tcp_incoming, x509cert, _1)); if (!tcplisten.isok()) { log("Can't listen: %s\n", tcplisten.errstr()); return 1; } log("Listening on %s.\n", *tcplisten.src()); WvIStreamList::globallist.append(&tcplisten, false, "ss tcp listener"); WvIStreamList::globallist.append(wvcon, false, "wvcon"); wvcon->setcallback(wv::bind(bounce_to_list, wvcon)); while (!want_to_die && wvcon->isok() && tcplisten.isok()) WvIStreamList::globallist.runonce(); if (!tcplisten.isok()) wvcon->print("Exited with error: %s\n", tcplisten.errstr()); return 0; } wvstreams-4.6.1/crypto/tests/reqtest.cc0000644000175000001440000000165611036722347017267 0ustar wlachusers#include "wvrsa.h" #include "wvx509.h" #include "wvlog.h" // Quick program to test the certificate request generation routines // from WvX509Mgr. Output should be put through: // openssl req -text // (The part between ----BEGIN CERTIFICATE REQUEST---- and // ----END CERTIFICATE REQUEST---- ) int main(int argc, char **argv) { free(malloc(1)); // For Electric Fence... WvString request; WvLog log("reqtest", WvLog::Info); log("Starting...\n"); // Setup a new DN entry, like a server would set. WvString dn(argc > 1 ? argv[1] : "cn=test.foo.com,dc=foo,dc=com"); // Setup a key WvRSAKey rsa(1024); // Create a new certificate WvString certreq = WvX509::certreq(dn, rsa); log("Private RSA key follows (KEEP THIS!):\n"); wvcon->write(rsa.encode(WvRSAKey::RsaPEM)); log("Certificate request follows:\n"); wvcon->write(certreq); log("Done...\n"); } wvstreams-4.6.1/crypto/tests/ocsptest.cc0000644000175000001440000000611511100136363017424 0ustar wlachusers#include "wvargs.h" #include "wvbuf.h" #include "wvfile.h" #include "wvhttppool.h" #include "wvocsp.h" static int got_response = 0; void load_cert(WvStringParm fname, WvX509 &cert) { WvFile f(fname, O_RDONLY); WvDynBuf buf; while (f.isok()) f.read(buf, 100); WvX509::DumpMode dumpmode = WvX509::CertDER; if (!strncmp("-----BEGIN", (const char *) buf.peek(0, 10), 10)) dumpmode = WvX509::CertPEM; cert.decode(dumpmode, buf); wvcon->print("Loaded certificate with name %s\n", cert.get_subject()); } static void response_cb(WvStream &s, WvDynBuf &respbuf) { char buf[1024]; size_t numread = 0; size_t totalread = 0; while (s.isreadable() && totalread < 32768) { numread = s.read(buf, 1024); if (numread) respbuf.put(buf, numread); totalread += numread; } } static void response_closed_cb() { wvcon->print("Response closed!\n"); // we just assume that we were successful got_response = 1; } int main(int argc, char *argv[]) { WvArgs args; args.add_required_arg("CLIENT_CERTIFICATE", false); args.add_required_arg("SIGNING_CERTIFICATE", false); args.add_required_arg("URL", false); WvStringList remaining_args; if (!args.process(argc, argv, &remaining_args)) return 1; WvString clicertfname = remaining_args.popstr(); WvString issuercertfname = remaining_args.popstr(); WvString url = remaining_args.popstr(); WvX509 clicert; WvX509 issuer; WvX509 ocspserver; load_cert(clicertfname, clicert); load_cert(issuercertfname, issuer); wvcon->print("Sending request...\n"); WvOCSPReq req(clicert, issuer); WvDynBuf reqbuf; req.encode(reqbuf); WvBufStream input_stream; input_stream.write(reqbuf, reqbuf.used()); WvHttpStream::global_enable_pipelining = false; WvHttpPool pool; WvIStreamList::globallist.append(&pool, false, "http pool"); WvStream * response_stream = pool.addurl( url, "POST", "Content-Type: application/ocsp-request\r\n", &input_stream); WvDynBuf respbuf; response_stream->setcallback(wv::bind(&response_cb, wv::ref(*response_stream), wv::ref(respbuf))); response_stream->setclosecallback(&response_closed_cb); WvIStreamList::globallist.append(response_stream, false, "response stream"); wvcon->print("Beginning downloading of response...\n"); while (!got_response) WvIStreamList::globallist.runonce(); wvcon->print("Got response (length: %s), attempting to decode...\n", respbuf.used()); WvOCSPResp resp; resp.decode(respbuf); if (!resp.isok()) { wvcon->print("Response not ok!\n"); exit(1); } if (!resp.check_nonce(req)) { wvcon->print("Response nonce does not check out!\n"); exit(1); } WvOCSPResp::Status status = resp.get_status(clicert, issuer); wvcon->print("Response status: %s.\n", WvOCSPResp::status_str(status)); } wvstreams-4.6.1/crypto/tests/crltest.cc0000644000175000001440000000224211036722347017250 0ustar wlachusers#include "wvcrl.h" #include "wvx509.h" #include "wvhex.h" #include "wvcrash.h" int main(int argc, char **argv) { wvcrash_setup(argv[0]); WvCRL crl; crl.isok(); #if 0 WvX509Mgr ca("o=ca", 1024); ca.create_selfsigned(true); crl.setca(&ca); fprintf(stderr,"\n\n\nFoo\n\n\n\n"); crl.numcerts(); WvX509Mgr user("cn=user,o=ca", 1024); WvString request = user.certreq(); fprintf(stderr,"Request:\n%s\n", request.cstr()); WvString srequest = ca.signreq(request); fprintf(stderr,"Got past the signing bit\n"); user.decode(WvX509Mgr::CertPEM, srequest); fprintf(stderr,"Imported the certificate\n"); crl.isrevoked(&user); fprintf(stderr,"Checking that new cert isn't revoked\n"); crl.isrevoked(user.get_serial()); fprintf(stderr,"Still isn't revoked!\n"); crl.addcert(&user); fprintf(stderr,"Ok - just added it"); crl.numcerts(); fprintf(stderr,"And now, the number of certs should be 1\n"); crl.isrevoked(&user); fprintf(stderr,"And user cert should be revoked\n"); crl.isrevoked(user.get_serial()); fprintf(stderr,"And should still be revoked!\n"); #endif return 0; } wvstreams-4.6.1/crypto/t/0000755000175000001440000000000011260431126014351 5ustar wlachuserswvstreams-4.6.1/crypto/t/wvx509.t.cc0000644000175000001440000006101411077124114016210 0ustar wlachusers#include "wvfile.h" #include "wvfileutils.h" #include "wvrsa.h" #include "wvtest.h" #include "wvx509.h" #include "wvx509mgr.h" #include "wvautoconf.h" // default keylen for where we're not using pre-existing certs const static int DEFAULT_KEYLEN = 512; // carillon cert: has a number of interesting characteristics (policy, // aia information, ...) which we can test against const static char carillon_cert[] = "-----BEGIN CERTIFICATE-----\n" "MIIFSzCCBDOgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBgDELMAkGA1UEBhMCQ0Ex\n" "KzApBgNVBAoTIkNhcmlsbG9uIEluZm9ybWF0aW9uIFNlY3VyaXR5IEluYy4xHzAd\n" "BgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxIzAhBgNVBAMTGlRlc3QgQ2Vy\n" "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MTIyNDIyMzgzNVoXDTA5MTIyMzIyMzgz\n" "NVowgYIxCzAJBgNVBAYTAkNBMSswKQYDVQQKDCJDYXJpbGxvbiBJbmZvcm1hdGlv\n" "biBTZWN1cml0eSBJbmMuMQ4wDAYDVQQLDAVVc2VyczEVMBMGA1UEAwwMVGVzdGlu\n" "ZyBVc2VyMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGNhcmlsbG9uLmNhMIGfMA0GCSqG\n" "SIb3DQEBAQUAA4GNADCBiQKBgQCwYnEgxl9uly9EeXg6N/SLzx6ZB5iU/REgB1bi\n" "9u/4O7S7ebAh5VKO8JIo+0JaHW7pBFM0ywe3KvHwpvdsHvmRCQ4+Qze8itFuhDSS\n" "TFJ7eP9bxiyroYIaRuS9G3xrM6jGdkw1IhmN2FDpWXBTWtfF/8Lor4p9TemGUARl\n" "prfDjQIDAQABo4ICTjCCAkowCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwUAYJ\n" "YIZIAYb4QgENBEMWQURvIE5vdCB0cnVzdCAtIENlcnRpUGF0aCBjb21wbGlhbnQg\n" "SUQgQ2VydCBmb3IgVEVTVCBwdXJwb3NlcyBvbmx5MB0GA1UdDgQWBBRI8EWCS88U\n" "Hug1TLLei5iiJGJSXTAfBgNVHSMEGDAWgBQZ8G5V0iRoGnd6l8LUaI01I0M3+jAb\n" "BgNVHREEFDASgRB0ZXN0QGNhcmlsbG9uLmNhMEsGCCsGAQUFBwEBBD8wPTA7Bggr\n" "BgEFBQcwAoYvaHR0cDovL3d3dy5jYXJpbGxvbi5jYS9jYW9wcy9tZWRpdW0tdGVz\n" "dC1jYS5jcnQwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL3d3dy5jYXJpbGxvbi5j\n" "YS9jYW9wcy9tZWRpdW0tY3JsMS5jcmwwgfEGA1UdIASB6TCB5jBuBgsrBgEEAYHD\n" "XgEBZTBfMF0GCCsGAQUFBwICMFEwKRoiQ2FyaWxsb24gSW5mb3JtYXRpb24gU2Vj\n" "dXJpdHkgSW5jLjADAgEBGiRURVNUIG1lZGl1bSBzdyBwb2xpY3kgLSBkbyBub3Qg\n" "dHJ1c3QwdAYLKwYBBAGBw14BAWYwZTBjBggrBgEFBQcCAjBXMCkaIkNhcmlsbG9u\n" "IEluZm9ybWF0aW9uIFNlY3VyaXR5IEluYy4wAwIBARoqVEVTVCBtZWRpdW0gaGFy\n" "ZHdhcmUgcG9saWN5IC0gZG8gbm90IHRydXN0MA0GCSqGSIb3DQEBBQUAA4IBAQAH\n" "NnhF+cbDe2jCPZ8J36Vb9p7QBFhGHiPQKpWVgEISjfYDqyilDUMvqo1RshBnxdTt\n" "cPMu1MxcQOOvU1f3jRCJPngzzZXW91zOZKQREPanekUcil7ZrY9MPgpIPqMgGw5h\n" "rX5R/RyAG/vkfJXe5SMd4GeUOuPuDVCxM3y2cylT0TS5zaWSYNdmERDm5tp2fHlj\n" "rqE1w9PZDeLz9ZhKfo/pcxCvE7RdS1Zhpi3KMUEtDXq9RN2D81mvo1TyzHvm84QB\n" "R7Z/1y/HH8vZj7q//xJrJt/IqPuXcYUacaS520ouzPhXNRkMxl4VZ8fCGnbrqPig\n" "0KUUwRu2l4LDN9drx+L5\n" "-----END CERTIFICATE-----\n"; const static char rsakeytext[] = "-----BEGIN RSA PRIVATE KEY-----\n" "MIICXgIBAAKBgQDVQrw1PHhLm2qSGl24SAb4+mJb2jPW0UwsbodDG5Da0h405zUp\n" "0U5yL7zKNQG6BYvuV5bCUeo6Q0uvd7D6eKE7VqzcVHVJfM2KvfKOI5eMiu76pz6V\n" "XxnW53kEdw1ZiCnCQTK1JntJn41ZsWxY7mQ3PLBpcobNIdoyUDwXIOFwOQIDAQAB\n" "AoGAVcyuqgB1KX4Sx0tCT4TzATLDZc8JMjEso2eoldA+XDtTGde3pOZn2DrqirP+\n" "yNe4b6Dfr7iDMwOmLKdMFcl4nAmE8UnOQWFtW52SCWFGLdiSqD8hn0gbKoYvaGDu\n" "vlqN/KvKen0AxiveYS6T24GFzHejr2RVcmT4m5UogNGFR90CQQD7VcPzfcPJZ3c1\n" "jWiJvoUrzdLqYactRoKidm+O7AVjMU7xkXCPLGgXbzVoyuzx11z1D/nFUE615t/v\n" "vkKVsnTDAkEA2TgOnSX6gSClZLUy7bWoSHQwcuj3Ogt2C0zA9p/sRgRaAuNCDWNC\n" "OmkRAHjbOtJK0tChxoG0BYdyv9WIZ5bHUwJBANf+0xH06UezNY2+YzLNmyEUF8j5\n" "93Q/fpEke6c2S0L94zxTo4pHvYU2O449pvgH/4lUG3FpHNvS+GzO8+Y2oYUCQQC8\n" "Nf8rmOmqEvBcB0jegQUT6mDEYCk+yQl6FwInb0AZFtIrKGBmGzgaRkkuAInsOKQO\n" "cCmMR3wFQmxh3ZI4N4PzAkEA4YbOing3yMDXxUFByZMKSX6oqwNePuVfK1IHmoUP\n" "oZxEIiwTN7rE9kRV1OFDUwvGiqcegSxjf6SUgdpBC7Du9A==\n" "-----END RSA PRIVATE KEY-----\n"; const static char x509certtext[] = "-----BEGIN CERTIFICATE-----\n" "MIICXDCCAcWgAwIBAgIEM7WjbjANBgkqhkiG9w0BAQUFADBBMRUwEwYDVQQDEwx0\n" "ZXN0LmZvby5jb20xEzARBgoJkiaJk/IsZAEZEwNmb28xEzARBgoJkiaJk/IsZAEZ\n" "EwNjb20wHhcNMDQwMzI2MjEwNTI5WhcNMTQwMzI0MjEwNTI5WjBBMRUwEwYDVQQD\n" "Ewx0ZXN0LmZvby5jb20xEzARBgoJkiaJk/IsZAEZEwNmb28xEzARBgoJkiaJk/Is\n" "ZAEZEwNjb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANVCvDU8eEubapIa\n" "XbhIBvj6YlvaM9bRTCxuh0MbkNrSHjTnNSnRTnIvvMo1AboFi+5XlsJR6jpDS693\n" "sPp4oTtWrNxUdUl8zYq98o4jl4yK7vqnPpVfGdbneQR3DVmIKcJBMrUme0mfjVmx\n" "bFjuZDc8sGlyhs0h2jJQPBcg4XA5AgMBAAGjYTBfMBEGCWCGSAGG+EIBAQQEAwIG\n" "QDAbBglghkgBhvhCAQwEDhYMdGVzdC5mb28uY29tMA4GA1UdDwEB/wQEAwICpDAd\n" "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEA\n" "D8WtaiTyx3DkHiJwC7EHVCOTqRctuS+3x1y0b2CO/3ijWASg+UDvGFKpAT4i6EF4\n" "/e1aTgQEJ3a29XQEKamk5Py2AAb7acBbuKIUzEzcFx4QzzY+fdz1PgKz4DiUypZj\n" "UFCAL0f74uuFTQ7ylt6F0m554LSniOHDOEzyBZZq/bk=\n" "-----END CERTIFICATE-----\n"; const static char certreqtext[] = "-----BEGIN CERTIFICATE REQUEST-----\n" "MIIBazCB1QIBADAsMSowKAYKCZImiZPyLGQBGRMadGVzdC5mb28uY29tL0RDPWZv\n" "by9EQz1jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANVCvDU8eEubapIa\n" "XbhIBvj6YlvaM9bRTCxuh0MbkNrSHjTnNSnRTnIvvMo1AboFi+5XlsJR6jpDS693\n" "sPp4oTtWrNxUdUl8zYq98o4jl4yK7vqnPpVfGdbneQR3DVmIKcJBMrUme0mfjVmx\n" "bFjuZDc8sGlyhs0h2jJQPBcg4XA5AgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQA3\n" "+zj1ZCRGOqCyWJFT0J6P+LJxn57My7GKkUihXQFo6xym98kKfYwc7HTIVq+clnYA\n" "rqmoQu1THFu6mVRdM9zp2zmRBtsmOxKkhx89RtNDhKu75HQE8S5xGmCPyZhFA0eX\n" "elfqYQM30sg+MeZVTccV0wCd9augzYa2qA8MExu7SQ==\n" "-----END CERTIFICATE REQUEST-----\n"; const static char signedcerttext[] = "-----BEGIN CERTIFICATE-----\n" "MIICiDCCAfGgAwIBAgIBATANBgkqhkiG9w0BAQQFADAUMRIwEAYDVQQKEwlOSVRJ\n" "LVRFU1QwHhcNMDQwMzMwMTgzOTM4WhcNMDUwMzMwMTgzOTM4WjBkMQswCQYDVQQG\n" "EwJDQTEPMA0GA1UECBMGUXVlYmVjMREwDwYDVQQHEwhNb250cmVhbDESMBAGA1UE\n" "ChMJVGVzdHkgT25lMR0wGwYDVQQDExRhcmlhMi53ZWF2ZXJuZXQubnVsbDCBnzAN\n" "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtQcmm+hJqHI+xy1vdpyaTiKPOk58TJSH\n" "dtj1JTZLmM7ZIDFZKgVAQvX+Y3V8wnCsKnF4U0fW14T0uHEWHhPjrCq+XBgw2NJA\n" "GnKXZDX9QXDHKqBj7ttF+gTXztkpdBYjY9eHFfsETWbm7jgqLx6nDo2MULmipXWr\n" "FM19VkZgRjUCAwEAAaOBmTCBljAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P\n" "cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzpHzxgB4JiHt\n" "/EbtqgfEbSpsThUwPAYDVR0jBDUwM4AUx1ECvcgeUvpwQJNQs2g3qq0CPzWhGKQW\n" "MBQxEjAQBgNVBAoTCU5JVEktVEVTVIIBADANBgkqhkiG9w0BAQQFAAOBgQCLUpzC\n" "nPlIYTDK7rq1Mh/Bqcw0RYamxUOCMsNmkMBovb37yfmo4k+HfhiHhiM6Ao6H5GIF\n" "+p09tcn1Iotrek1IGrXsH7Hjkpzf8lkqwEjygIJ0iAWMqAI4AVoRx/5JrG+8ePPU\n" "rKZf8WzBwn45ibb+xwtjdQXVro1l+K4UATTHLQ==\n" "-----END CERTIFICATE-----\n"; static void basic_test(WvX509 &t509, WvStringParm dname) { WVPASS(t509.isok()); WVPASSEQ(t509.get_subject(), dname); WVPASSEQ(t509.get_issuer(), dname); } WVTEST_MAIN("X509") { // Setup a new DN entry, like a server would set. const WvString dName("cn=test.foo.com,dc=foo,dc=com"); const WvString dName1("/CN=test.foo.com/DC=foo/DC=com"); const WvString dName2("/C=CA/ST=Quebec/L=Montreal/O=Testy One" "/CN=aria2.weavernet.null" "/DC=webmaster@weavernet.null"); { WvX509Mgr t509; WVFAIL(t509.isok()); WVFAIL(t509.test()); } // WIN32 people! If your unit tests are crashing here, you probably // linked openssl with a different version of msvcr*.dll than the // unit test. We pass a FILE* from one to the other here, and it // won't work if there's a library mismatch. { WvX509Mgr t509; t509.decode(WvRSAKey::RsaPEM, rsakeytext); t509.decode(WvX509::CertPEM, x509certtext); basic_test(t509, dName1); WvString certencode = t509.encode(WvX509::CertPEM); WVPASSEQ(certencode, x509certtext); WvString rsaencode = t509.encode(WvRSAKey::RsaPEM); WVPASSEQ(rsaencode, rsakeytext); WvRSAKey rsa; rsa.decode(WvRSAKey::RsaPEM, rsakeytext); WVPASSEQ(WvX509::certreq(t509.get_subject(), rsa), certreqtext); } { // test the copy constructor for x509 WvX509 t1; t1.decode(WvX509::CertPEM, x509certtext); basic_test(t1, dName1); WvX509 t2(t1); basic_test(t2, dName1); } { // test the copy construct for x509mgr WvX509Mgr t1; t1.decode(WvX509::CertPEM, x509certtext); t1.decode(WvRSAKey::RsaPEM, rsakeytext); basic_test(t1, dName1); WvX509Mgr t2(t1); basic_test(t2, dName1); WVPASSEQ(t1.encode(WvRSAKey::RsaPEM), t2.encode(WvRSAKey::RsaPEM)); } { WvX509Mgr t509(dName, 1024); basic_test(t509, dName1); } { WvX509 t509; t509.decode(WvX509::CertPEM, signedcerttext); WVPASS(t509.isok()); WVFAIL(t509.validate()); // this certificate has expired WVPASSEQ(t509.get_subject(), "/C=CA/ST=Quebec/L=Montreal/O=Testy One" "/CN=aria2.weavernet.null"); WVPASSEQ(t509.get_issuer(), "/O=NITI-TEST"); WVPASSEQ(t509.get_ski(), "CE:91:F3:C6:00:78:26:21:ED:FC:46:ED:AA:07:C4:6D:2A:6C:4E:15"); WVPASSEQ(t509.get_aki(), "C7:51:02:BD:C8:1E:52:FA:70:40:93:50:B3:68:37:AA:AD:02:3F:35"); } { // Now we stress test it to make sure that it fails predictably... WvX509Mgr t509; t509.decode(WvRSAKey::RsaPEM, WvString::null); t509.decode(WvX509::CertPEM, ""); WVFAIL(t509.test()); WVFAIL(t509.isok()); WVFAIL(t509.get_subject() == "/CN=test.foo.com/DC=foo/DC=com"); WVFAIL(t509.get_issuer() == "/CN=test.foo.com/DC=foo/DC=com"); } } WVTEST_MAIN("mismatched key / certificate") { WvX509Mgr t509; t509.decode(WvX509::CertPEM, signedcerttext); t509.decode(WvRSAKey::RsaPEM, rsakeytext); WVFAIL(t509.isok()); WVFAIL(t509.test()); } WVTEST_MAIN("Hexified encoding/decoding") { const char cert_hex[] ="3082030030820269a003020102020460ad1ad" "5300d06092a864886f70d010105050030818e310b3009060355040613024341310" "f300d060355040813065175656265633111300f060355040713084d6f6e7472656" "16c31123010060355040a13095465737479204f6e65311d301b060355040313146" "1726961322e7765617665726e65742e6e756c6c31283026060a0992268993f22c6" "4011916187765626d6173746572407765617665726e65742e6e756c6c301e170d3" "034303333313230343235315a170d3134303332393230343235315a30818e310b3" "009060355040613024341310f300d060355040813065175656265633111300f060" "355040713084d6f6e747265616c31123010060355040a13095465737479204f6e6" "5311d301b0603550403131461726961322e7765617665726e65742e6e756c6c312" "83026060a0992268993f22c64011916187765626d6173746572407765617665726" "e65742e6e756c6c30819f300d06092a864886f70d010101050003818d003081890" "2818100b507269be849a8723ec72d6f769c9a4e228f3a4e7c4c948776d8f525364" "b98ced92031592a054042f5fe63757cc270ac2a71785347d6d784f4b871161e13e" "3ac2abe5c1830d8d2401a72976435fd4170c72aa063eedb45fa04d7ced92974162" "363d78715fb044d66e6ee382a2f1ea70e8d8c50b9a2a575ab14cd7d56466046350" "203010001a3693067301106096086480186f842010104040302064030230609608" "6480186f842010c0416161461726961322e7765617665726e65742e6e756c6c300" "e0603551d0f0101ff0404030202a4301d0603551d250416301406082b060105050" "7030106082b06010505070302300d06092a864886f70d010105050003818100b2b" "fe7b80feec0bfe23250f5d9eb3d409364628c001fee50185eb755ffb863093fe23" "973c939fdd03bc90b32eb697f1eb9b4a7a0134ee78a509992da0d803af22b5148a" "76b197a54126be4a3d03897ed6cc98e77e65b797aee3f3b66c17afb4a2fd6dc498" "cd86f4d7952cfde7d1e044a38373f80b9d1da51461267a83d967f24"; const char rsa_hex[] = "3082025e02010002818100b507269be849a872" "3ec72d6f769c9a4e228f3a4e7c4c948776d8f525364b98ced92031592a054042f5" "fe63757cc270ac2a71785347d6d784f4b871161e13e3ac2abe5c1830d8d2401a72" "976435fd4170c72aa063eedb45fa04d7ced92974162363d78715fb044d66e6ee38" "2a2f1ea70e8d8c50b9a2a575ab14cd7d5646604635020301000102818100b277a4" "469c10d1f21f95f963240a6bcd9020a818ec4e0b3829a0e6bd92f3a0687c825264" "571aea29999efbaabe1e6b3a3075c16c492cb338ae928f5a80b897005fdeca7966" "14f58329552bfd117755fae42ba39aa3266bb2560377d5d747e31ddfd2ae1bbd9b" "8979e8748d4d47573588a4140715fbc14ea373f2461517749641024100f0b0ddee" "376d6e08c9dc0bce540e9b464bf23121241cf6dd69fd67c9e195c6dce0ddb47012" "56761567a8c70fff3e12cc412e8cb74f120eb620d7d129624c359d024100c08acd" "153fe5f801c81a85a62b63f50b9346ebe350a18c3aecd11379a17093f52fdea874" "df97b22189dd4ca479723422c0a5b5124873e087f316cbf681d2fb79024100810c" "33517fc25a56b7f4151861151bc78afca5bec1200e741459db85f03f5fca197e85" "39f97b0600dffd2c0db5aa5065d724e02980698c1db66a4028d21d4e3902405e57" "a48574f9c9bb95c0e91bb2c7179ac45f4bd5e5fc4229dd3fd4bb144f852fee74bb" "360918db3f73bdeb7febc1f9a9cd9b644dc112864216ea64a634969c81024100e5" "453ec9a3cdbe2fe17e86b32e998fe8713066ed254a60390f7898e4e536dea92af7" "743d55a35fad75c14fe1e239251c471e133ca8e85ef3a1d3c5b6b288bfda"; const WvString dName2("/C=CA/ST=Quebec/L=Montreal" "/O=Testy One/CN=aria2.weavernet.null" "/DC=webmaster@weavernet.null"); WvX509Mgr t509; t509.decode(WvX509Mgr::CertHex, cert_hex); t509.decode(WvRSAKey::RsaHex, rsa_hex); basic_test(t509, dName2); WVPASSEQ(t509.get_serial(), "1621957333"); WVPASSEQ(t509.encode(WvX509Mgr::CertHex), cert_hex); WVPASSEQ(t509.encode(WvRSAKey::RsaHex), rsa_hex); } WVTEST_MAIN("Replacing key failure") { WvX509Mgr t509("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN); WVPASS(t509.test()); WvRSAKey rsakey(DEFAULT_KEYLEN); t509.decode(WvRSAKey::RsaHex, rsakey.encode(WvRSAKey::RsaHex)); WVFAIL(t509.test()); } WVTEST_MAIN("Get extensions memory corruption") { // this test validates a workaround for a bug // in openssl 0.9.8 -- where getting certain attributes using // ASN1_item_d2i could cause openssl to shuffle around // const pointers, leading to weird memory behaviour on // destroys WvX509 t509; t509.decode(WvX509Mgr::CertPEM, carillon_cert); WVPASS(t509.isok()); WVPASSEQ("CA Issuers - " "URI:http://www.carillon.ca/caops/medium-test-ca.crt", t509.get_aia()); } WVTEST_MAIN("set_aia") { // yeah, the certificate generated doesn't make much sense here, // but we're only testing that the extension works properly WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); WvStringList ca_in; WvStringList ocsp_in; ca_in.append("http://localhost/~wlach/testca.pem"); ca_in.append("http://localhost/~wlach/testca-alt.pem"); ocsp_in.append("http://localhost/~wlach/blah.ocsp"); ocsp_in.append("http://localhost/~wlach/blarg.ocsp"); x.set_aia(ca_in, ocsp_in); WvStringList ca_out; x.get_ca_urls(ca_out); WvStringList ocsp_out; x.get_ocsp(ocsp_out); WVPASSEQ(ca_in.popstr(), ca_out.popstr()); WVPASSEQ(ca_in.popstr(), ca_out.popstr()); WVPASSEQ(ocsp_in.popstr(), ocsp_out.popstr()); WVPASSEQ(ocsp_in.popstr(), ocsp_out.popstr()); WVPASSEQ(ca_in.count(), 0); WVPASSEQ(ca_out.count(), 0); WVPASSEQ(ocsp_in.count(), 0); WVPASSEQ(ocsp_out.count(), 0); } WVTEST_MAIN("set_crl_dp") { WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); WvStringList dp_in; dp_in.append("http://localhost/~wlach/testca.crl"); dp_in.append("http://localhost/~wlach/testca-alt.crl"); x.set_crl_urls(dp_in); WvStringList dp_out; x.get_crl_urls(dp_out); WVPASSEQ(dp_in.popstr(), dp_out.popstr()); WVPASSEQ(dp_in.popstr(), dp_out.popstr()); WVPASSEQ(dp_in.count(), 0); WVPASSEQ(dp_out.count(), 0); } WVTEST_MAIN("certreq / signreq / signcert") { // certificate request WvRSAKey rsakey(DEFAULT_KEYLEN); WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com", rsakey); WvX509Mgr cacert("CN=test.foo.com,DC=foo,DC=com", DEFAULT_KEYLEN, true); WVPASS(cacert.isok()); WVPASS(cacert.validate()); WvX509 cert; WvString certpem = cacert.signreq(certreq); cert.decode(WvX509Mgr::CertPEM, certpem); // test that it initially checks out WVPASS(cert.isok()); WVPASS(cert.validate()); WVPASS(cert.issuedbyca(cacert)); WVPASS(cert.signedbyca(cacert)); WVPASSEQ(cert.get_aki(), cacert.get_ski()); // change some stuff, verify that tests fail WvStringList ca_in, ocsp_in; ca_in.append("http://localhost/~wlach/testca.pem"); ca_in.append("http://localhost/~wlach/testca-alt.pem"); cert.set_aia(ca_in, ocsp_in); WVPASS(cert.issuedbyca(cacert)); WVFAIL(cert.signedbyca(cacert)); // should pass again after re-signing cacert.signcert(cert); WVPASSEQ(cert.get_issuer(), cacert.get_subject()); WVPASS(cert.issuedbyca(cacert)); WVPASS(cert.signedbyca(cacert)); } WVTEST_MAIN("certificate policies") { WvX509 t509; t509.decode(WvX509Mgr::CertPEM, carillon_cert); WvStringList policies; WVPASS(t509.get_policies(policies)); WVPASSEQ(policies.popstr(), "1.3.6.1.4.1.25054.1.1.101"); WVPASSEQ(policies.popstr(), "1.3.6.1.4.1.25054.1.1.102"); WVPASSEQ(policies.count(), 0); policies.zap(); WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true); WVFAIL(cacert.get_policies(policies)); WVPASSEQ(policies.count(), 0); } WVTEST_MAIN("certificate policies set and get") { WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); WvStringList policies_in; policies_in.append("1.2.3.4"); policies_in.append("1.2.3.5"); x.set_policies(policies_in); WvStringList policies_out; x.get_policies(policies_out); WVPASSEQ(policies_in.popstr(), policies_out.popstr()); WVPASSEQ(policies_in.popstr(), policies_out.popstr()); WVPASSEQ(policies_in.count(), 0); WVPASSEQ(policies_out.count(), 0); } WVTEST_MAIN("basic constraints") { bool is_ca; int pathlen; // the carillon cert is a user cert, so it should have no path length, // and the ca bit of basicConstraints set to false WvX509 t509; t509.decode(WvX509Mgr::CertPEM, carillon_cert); WVPASS(t509.get_basic_constraints(is_ca, pathlen)); WVFAIL(is_ca); WVPASSEQ(pathlen, (-1)); // no path length restriction // by default, a CA certificate we create should have the ca bit set to // true, and no path length restriction. WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true); WVPASS(cacert.get_basic_constraints(is_ca, pathlen)); WVPASS(is_ca); WVPASSEQ(pathlen, (-1)); // no path length restriction // now, let's try setting the path length, and see what the result is cacert.set_basic_constraints(true, 5); WVPASS(cacert.get_basic_constraints(is_ca, pathlen)); WVPASS(is_ca); WVPASSEQ(pathlen, 5); } #ifdef HAVE_OPENSSL_POLICY_MAPPING WVTEST_MAIN("get/set certificate policy extensions") { WvRSAKey rsakey(DEFAULT_KEYLEN); WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com", rsakey); WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true); WvString certpem = cacert.signreq(certreq); WvX509Mgr cert; cert.decode(WvX509Mgr::CertPEM, certpem); int require_explicit_policy_in = 10; int inhibit_policy_mapping_in = 5; cert.set_policy_constraints(require_explicit_policy_in, inhibit_policy_mapping_in); WvString issuer_domain_in = "2.16.840.1.101.3.2.1.48.1"; WvString subject_domain_in = "2.16.840.1.101.3.2.1.48.2"; WvX509Mgr::PolicyMapList list; list.append(new WvX509Mgr::PolicyMap(issuer_domain_in, subject_domain_in), true); cert.set_policy_mapping(list); list.zap(); cacert.signcert(cert); int require_explicit_policy_out = 0; int inhibit_policy_mapping_out = 0; cert.get_policy_constraints(require_explicit_policy_out, inhibit_policy_mapping_out); WVPASSEQ(require_explicit_policy_in, require_explicit_policy_out); WVPASSEQ(inhibit_policy_mapping_in, inhibit_policy_mapping_out); WVPASS(cert.get_policy_mapping(list)); WVPASSEQ(list.count(), 1); if (list.count() > 0) { WvX509Mgr::PolicyMap *map = list.first(); WVPASSEQ(map->issuer_domain, issuer_domain_in); WVPASSEQ(map->subject_domain, subject_domain_in); } } WVTEST_MAIN("ski / aki") { WvRSAKey rsakey(DEFAULT_KEYLEN); WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com", rsakey); WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true); WvString certpem = cacert.signreq(certreq); wvcon->print("\n%s\n", certpem); WvX509Mgr cert; cert.decode(WvX509Mgr::CertPEM, certpem); WVPASS(!!cert.get_ski()); WVPASS(!!cert.get_aki()); WVPASS(!!cacert.get_ski()); WVFAIL(!!cacert.get_aki()); WVPASSEQ(cert.get_aki(), cacert.get_ski()); } #endif // HAVE_OPENSSL_POLICY_MAPPING bool test_encode_decode_str(WvX509::DumpMode mode) { WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); WvString s = cert1.encode(mode); WvX509Mgr cert2; cert2.decode(mode, s); WVPASSEQ(cert1.get_subject(), cert2.get_subject()); return cert1.get_subject() == cert2.get_subject(); } bool test_encode_decode_buf(WvX509::DumpMode mode) { WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); WvDynBuf buf; cert1.encode(mode, buf); WvX509Mgr cert2; cert2.decode(mode, buf); WVPASSEQ(cert1.get_subject(), cert2.get_subject()); return cert1.get_subject() == cert2.get_subject(); } bool test_encode_load_file(WvX509::DumpMode mode) { WvString tmpfile = wvtmpfilename("cert"); WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false); { WvFile f(tmpfile, O_WRONLY); WvDynBuf buf; cert1.encode(mode, buf); fprintf(stderr, "Encode to file '%s' (%ld bytes)\n", tmpfile.cstr(), (long)buf.used()); size_t used = buf.used(), len; len = f.write(buf, buf.used()); WVPASSEQ(len, used); fprintf(stderr, "Write result: %s\n", f.errstr().cstr()); } WvX509Mgr cert2; if (mode == WvX509::CertPEM) cert2.decode(WvX509::CertFilePEM, tmpfile); else cert2.decode(WvX509::CertFileDER, tmpfile); unlink(tmpfile); WVPASSEQ(cert1.get_subject(), cert2.get_subject()); return cert1.get_subject() == cert2.get_subject(); } WVTEST_MAIN("encode / decode / load") { WVPASS(test_encode_decode_str(WvX509::CertPEM)); WVPASS(test_encode_decode_str(WvX509::CertHex)); WVPASS(test_encode_decode_buf(WvX509::CertPEM)); WVPASS(test_encode_decode_buf(WvX509::CertHex)); WVPASS(test_encode_decode_buf(WvX509::CertDER)); WVPASS(test_encode_load_file(WvX509::CertPEM)); WVPASS(test_encode_load_file(WvX509::CertDER)); } WVTEST_MAIN("pkcs12") { WvX509Mgr cert1("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true); WvString p12fname = wvtmpfilename("p12"); cert1.write_p12(p12fname, "123"); WvX509Mgr cert2; cert2.read_p12(p12fname, "123"); WVPASS(cert2.isok()); WVPASSEQ(cert1.get_ski(), cert2.get_ski()); WvX509Mgr cert3; cert3.read_p12(p12fname, "321"); WVFAIL(cert3.isok()); ::unlink(p12fname); } const char random_cert[] = "-----BEGIN CERTIFICATE-----\n" "MIIDvzCCAqegAwIBAgIEShc7yDANBgkqhkiG9w0BAQUFADBWMR0wGwYDVQQDExRj\n" "b250aW5nZW5jeXdvcmtzLmNvbTEgMB4GCgmSJomT8ixkARkTEGNvbnRpbmdlbmN5\n" "d29ya3MxEzARBgoJkiaJk/IsZAEZEwNjb20wHhcNMDgwNzMxMjAyMzE4WhcNMTgw\n" "NzI5MjAyMzE4WjBWMR0wGwYDVQQDExRjb250aW5nZW5jeXdvcmtzLmNvbTEgMB4G\n" "CgmSJomT8ixkARkTEGNvbnRpbmdlbmN5d29ya3MxEzARBgoJkiaJk/IsZAEZEwNj\n" "b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrFneQgdQSoVfzCDNu\n" "IAXhFpaCJvxDzWPCCZXWPf1/OlncskrRs4FirMnrPUyvw74krPh4lVILKZxIp+Io\n" "s7DX8oPHct1ZjQoi7eK7r6iva38ghI3YFPtZSXC3z1DllKzUTezBzNJDkhg/SqUX\n" "ne4NNw1mZ90Q07Y8KgREyjJ8/A0+jUNoQ3TydXPWsdNevP6jcczyULbzhlZrCj5J\n" "7c21sSWkrm7HUegvJNPPv7vX67onYCMhj0f8Fsiw7TqacmmrJksrW3ifpCf5smIZ\n" "/W8F9RwSefnVLn1TA2UoNAFTPDxwPVWFuOEkP8ObDnZXzfWc5WHRbXeVLnTAKbab\n" "T6slAgMBAAGjgZQwgZEwHQYDVR0OBBYEFGryLpBlzbGgYCcpX/MbiAQj8nb8MBEG\n" "CWCGSAGG+EIBAQQEAwIGQDAjBglghkgBhvhCAQwEFhYUY29udGluZ2VuY3l3b3Jr\n" "cy5jb20wDgYDVR0PAQH/BAQDAgOoMAkGA1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYB\n" "BQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQBkWsSLHPmDajwg12AT\n" "2QW3pxJKVu46nfdgLLTo6bQekAF+kYRERjbC9E/T5Eia5+6yTUbWR8xxDZoftkSK\n" "/m3h7/Y+mqb13XiOowTkiJWzL5kwdv3Pb4O5X7YYMcNC4Rnax806b5pplXmzDY9Z\n" "rqq/uP6wsRFiu5S7UcfA+KjoTrjMYsSLERAEus5RaP9J6uDvdBn0PwdfTT5rr2yb\n" "et8AuJcBLFfFuLXPKfUlbnMe29BUr9s1A01OfHDCmzVN8hAhndBs2xDI1FOy9xDt\n" "QXj9z/yvsK0AYwxknkHKqRboW//DVk6tcsL9dCiGSlZta5ob5yt6KK+R5X+rtQ0W\n" "InR4\n" "-----END CERTIFICATE-----"; WVTEST_MAIN("get_fingerprint") { WvX509 foo; foo.decode(WvX509::CertPEM, random_cert); WVPASSEQ(foo.get_fingerprint(WvX509::FingerSHA1), "CA:49:50:D4:44:51:0B:AD:46:4F:E8:6C:3B:B2:3E:3F:61:31:27:ED"); WVPASSEQ(foo.get_fingerprint(WvX509::FingerMD5), "53:FD:C7:D4:8F:45:AE:1D:90:14:45:B4:0C:1B:02:BD"); } WVTEST_MAIN("extended key usage") { WvX509Mgr ca("CN=test.foo.com,DC=foo,DC=com", DEFAULT_KEYLEN, true); WVPASSEQ(ca.get_ext_key_usage(), ""); ca.set_ext_key_usage("TLS Web Server Authentication, " "TLS Web Client Authentication, OCSP Signing"); WVPASSEQ(ca.get_ext_key_usage(), "TLS Web Server Authentication;\n" "TLS Web Client Authentication;\nOCSP Signing"); ca.set_ext_key_usage("OCSP Signing"); WVPASSEQ(ca.get_ext_key_usage(), "OCSP Signing"); } wvstreams-4.6.1/crypto/t/wvdigest.t.cc0000644000175000001440000000366411036722347017000 0ustar wlachusers#include "wvtest.h" #include "wvdigest.h" #include "wvhex.h" WVTEST_MAIN("MD5 Test") { WvMD5Digest md5; WvDynBuf inbuf, md5buf; inbuf.put("floogle", 7); md5.encode(inbuf, md5buf); md5.finish(md5buf); WvString md5str = WvHexEncoder().strflushbuf(md5buf, true); WVPASS(md5str == "85c42eea90a6586f2b75be98e15e9a1f"); } WVTEST_MAIN("SHA-1 Test") { WvSHA1Digest sha1; WvDynBuf inbuf, sha1buf; inbuf.put("floogle", 7); sha1.encode(inbuf, sha1buf); sha1.finish(sha1buf); WvString sha1str = WvHexEncoder().strflushbuf(sha1buf, true); WVPASS(sha1str == "9ec117f204872bdd467b6c337ba1cf78be0ad5d9"); } /* * HMACs leak memory * WVTEST_MAIN("HMAC Test") { WvSHA1Digest *sha1 = new WvSHA1Digest(); WvDynBuf inbuf, hmacbuf; WvHMACDigest hmac(sha1, "imakey", 6); inbuf.put("floogle", 7); hmac.encode(inbuf, hmacbuf); hmac.finish(hmacbuf); WvString hmacstr = WvHexEncoder().strflushbuf(hmacbuf, true); fprintf(stderr, "%s\n", hmacstr.cstr()); WVPASS(hmacstr == "63d79e4bdaedf6c39564f2c9251c5edacbeabd30"); delete sha1; } */ WVTEST_MAIN("CRC32 Test") { WvCrc32Digest crc32; WvDynBuf inbuf, crc32buf; inbuf.put("floogle", 7); crc32.encode(inbuf, crc32buf); crc32.finish(crc32buf); WvString crc32str = WvHexEncoder().strflushbuf(crc32buf, true); WVPASSEQ(crc32str, "cb130290"); inbuf.put("hoopy frood", 11); crc32.reset(); crc32.encode(inbuf, crc32buf); crc32.finish(crc32buf); crc32str = WvHexEncoder().strflushbuf(crc32buf, true); WVPASSEQ(crc32str, "ccdf6289"); } WVTEST_MAIN("Adler32 Test") { // Example taken from Adler32 wikipedia entry. WvAdler32Digest adler32; WvDynBuf inbuf, adler32buf; inbuf.put("Wikipedia", 9); adler32.encode(inbuf, adler32buf); adler32.finish(adler32buf); WvString adler32str = WvHexEncoder().strflushbuf(adler32buf, true); WVPASSEQ(adler32str, "11e60398"); } wvstreams-4.6.1/crypto/t/wvocsp.t.cc0000644000175000001440000001217211100163451016442 0ustar wlachusers#include "wvfile.h" #define private public #include "wvocsp.h" #include "wvtest.h" #include "wvx509mgr.h" #undef private #include "wvfileutils.h" #include "wvrsa.h" #include "wvsystem.h" // default keylen for where we're not using pre-existing certs const static int DEFAULT_KEYLEN = 512; // for objects with only one kind of encoding (e.g. ocsp requests/replies) #define ENCODE_TO_FILE(FNAME, OBJ) \ { \ WvDynBuf buf; \ OBJ.encode(buf); \ WvFile f(FNAME, O_CREAT|O_WRONLY); \ f.write(buf); \ } // for objects with multiple encodings (e.g. certs) #define ENCODE_TO_FILE2(FNAME, OBJ, FORMAT) \ { \ WvDynBuf buf; \ OBJ.encode(FORMAT, buf); \ WvFile f(FNAME, O_CREAT|O_WRONLY); \ f.write(buf); \ } // dumping some stuff to file #define DUMP_TO_FILE(FNAME, STUFF) \ { \ WvFile f(FNAME, O_CREAT|O_WRONLY); \ f.print(STUFF); \ } static WvOCSPResp::Status test_ocsp_req(WvX509 &cert, WvX509Mgr &cacert, WvX509Mgr &ocspcert, WvStringParm indexcontents) { WvString reqfname = wvtmpfilename("ocspreq"); WvString respfname = wvtmpfilename("ocspresp"); WvString indexfname = wvtmpfilename("ocspidx"); WvString cafname = wvtmpfilename("ocspca"); WvString cakeyfname = wvtmpfilename("ocspcakey"); WvString ocspfname = wvtmpfilename("ocspresp"); WvString ocspkeyfname = wvtmpfilename("ocsprespkey"); WvString clifname = wvtmpfilename("ocspcli"); ENCODE_TO_FILE2(clifname, cert, WvX509::CertPEM); ENCODE_TO_FILE2(cafname, cacert, WvX509::CertPEM); ENCODE_TO_FILE2(ocspfname, ocspcert, WvX509::CertPEM); ENCODE_TO_FILE2(cakeyfname, cacert, WvRSAKey::RsaPEM); ENCODE_TO_FILE2(ocspkeyfname, ocspcert, WvRSAKey::RsaPEM); DUMP_TO_FILE(indexfname, indexcontents); WvOCSPReq req(cert, cacert); ENCODE_TO_FILE(reqfname, req); WvSystem("openssl", "ocsp", "-CAfile", cafname, "-index", indexfname, "-rsigner", ocspfname, "-rkey", ocspkeyfname, "-CA", cafname, "-reqin", reqfname, "-respout", respfname); WvOCSPResp resp; { WvFile f(respfname, O_RDONLY); WvDynBuf buf; while (f.isok()) f.read(buf, 1024); resp.decode(buf); } if (WVPASS(resp.isok())) { WVPASS(resp.check_nonce(req)); WvX509 signing_cert = resp.get_signing_cert(); WVPASS(signing_cert.isok()); WVPASSEQ(signing_cert.get_subject(), ocspcert.get_subject()); WVPASS(resp.signedbycert(ocspcert)); WVFAIL(resp.signedbycert(cert)); } ::unlink(reqfname); ::unlink(respfname); ::unlink(indexfname); ::unlink(cafname); ::unlink(cakeyfname); ::unlink(ocspfname); ::unlink(ocspkeyfname); return resp.get_status(cert, cacert); } WVTEST_MAIN("encoding request") { WvRSAKey rsakey(DEFAULT_KEYLEN); WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com", rsakey); WvX509Mgr cacert("CN=test.foo.com,DC=foo,DC=com", DEFAULT_KEYLEN, true); // cacert.set_ext_key_usage("OCSP Signing"); // cacert.signcert(cacert); // resign self WvX509Mgr cert; // only need wvx509mgr to test bogus signer problem WvString certpem = cacert.signreq(certreq); cert.decode(WvX509Mgr::CertPEM, certpem); cert.set_rsa(&rsakey); // this test breaks after 2020. oh well. static const char *EXPDATE = "202010194703Z"; //dec 10, 2049 static const char *REVDATE = "071211195254Z"; //dec 11 2007 { WvSystem caller("openssl", "version"); if (caller.go()) { WVFAIL("Failed to run openssl utility, is it installed and in your PATH?"); return; } } // unknown, because the cert's serial not in CRL list WVPASSEQ(test_ocsp_req(cert, cacert, cacert, ""), WvOCSPResp::Unknown); // revoked WVPASSEQ(test_ocsp_req(cert, cacert, cacert, WvString("R\t%s\t%s\t%s\tunknown\t%s\n", EXPDATE, REVDATE, cert.get_serial(true), cert.get_subject())), WvOCSPResp::Revoked); // good WVPASSEQ(test_ocsp_req(cert, cacert, cacert, WvString("V\t%s\t%s\t%s\tunknown\t%s\n", EXPDATE, REVDATE, cert.get_serial(true), cert.get_subject())), WvOCSPResp::Good); } wvstreams-4.6.1/crypto/t/wvrsa.t.cc0000644000175000001440000001337311036722347016304 0ustar wlachusers/* FIXME: horribly incomplete */ #include "wvtest.h" #include "wvrsa.h" WVTEST_MAIN("extremely basic test") { // this test tests to make sure that the cause // of BUGZID:3850 hasn't re-appeared... // (pub and prv weren't being initialized when // we were initializing with a NULL value) { WvRSAKey rsa(NULL, false); WVPASSEQ(rsa.encode(WvRSAKey::RsaPubHex), WvString::null); WVPASSEQ(rsa.encode(WvRSAKey::RsaHex), WvString::null); WVFAIL(rsa.isok()); } { WvRSAKey rsa(NULL, true); WVPASSEQ(rsa.encode(WvRSAKey::RsaPubHex), WvString::null); WVPASSEQ(rsa.encode(WvRSAKey::RsaHex), WvString::null); WVFAIL(rsa.isok()); } } static const char rsa_private[] = "3082025b02010002818100e16d0efd5b89d50761fc6" "b4befad25cdddfdcfc9409013e01984bb6ea88f45404df25f0f7e89d39295df774c0fca14" "91e0bb731e4af179ad3f3585671ac78002bdca7de4007ad575360d4335d3eb5f261124003" "62ee33301a947b725ce0a65bb5c4de0b66eb501032b90fd35d0faac9b7d1c1bf5dcb4fb7a" "9f128c59ed9073f50203010001028180325dfeb2672885bb8f8e299f1edf2e0a30668c6da" "80a4916923d10efe9a391528bd7f29b70a774e954a9486b6b3fb896db82a6770741aaf125" "a55cb82bc895761bd5747732c45dc1e7d58ee89fe4f0d359270e5d942ab9ae41c161b2ab5" "3ba990e64b8c93791a859ab08a026a48f7446d9aaca75279db7e8b245a9c82b6987250241" "00fdaaa281dfee19c0e959c1bcb47f3acf9243377e5884244828773e3fa2c973b4b9d4167" "43fd41f4d23471ea2e3d5354bf0807eccf1695756dd477ff8fe7c8467024100e37feb62d7" "01e4bb4849950cf5db2515a70764f7c7ae3461fe8e807c586c13a1ac01fa446a2a2740744" "1c58d297ec0daf9a77292a2d4e816807d2073a78fab43024066b5b8a72dac92f0f18b4e4e" "c226e2013a0fcd607326ce2a09787ed3f56dec53b90a8f2cf2cb49014acf79302b6020fc6" "69d20ba8ae5445fffa8fbc02e0aecf102406097c5a797c6b40958adf55d255e40a6aade96" "de25a82f9193f58954426ed0ff09fb64f97b621e7c5d6037b2b1f5a188d80b62b823eee60" "3f7d628db323febe502403f03ed55da41c33011c61014f7c6bd0d21be0292f586802f9e9c" "7e141016f2ac58b958980d874f2cc9d902b2be25ee900900cffe729d5401f1ad784992a1b" "3db"; static const char rsa_public[] = "30818902818100e16d0efd5b89d50761fc6b4befad25" "cdddfdcfc9409013e01984bb6ea88f45404df25f0f7e89d39295df774c0fca1491e0bb731" "e4af179ad3f3585671ac78002bdca7de4007ad575360d4335d3eb5f26112400362ee33301" "a947b725ce0a65bb5c4de0b66eb501032b90fd35d0faac9b7d1c1bf5dcb4fb7a9f128c59e" "d9073f50203010001"; // like rsa_public, but with a small bit of corruption static const char rsa_junk[] = "30818902818100e16d0efd5b89d50761fc6b4befad25" "cdddfdcfc9409013e01984bb6ea88f45404df25f0f7e89d39295df774c0fca1491e0bb731" "e4af179ad3f3585671ad78002bdca7de4007ad575360d4335d3eb5f26112400362ee33301" "a947b725ce0a65bb5c4de0b66eb501032b90fd35d0faac9b7d1c1bf5dcb4fb7a9f128c59e" "d9073f50203010001"; // like rsa_public, but truncated static const char rsa_junk2[] = "30818902818100e16d0efd5b89d50761fc6b4befad25" "cdddfdcfc9409013e01984bb6ea88f45404df25f0f7e89d39295df774c0fca1491e0bb731" "e4af179ad3f3585671ac78002bdca7de4007ad575360d4335d3eb5f26112400362ee33301" "a947b725ce0a65bb5c4de0b66eb501032b90fd35d0faac9b7d1c1bf5dcb4fb7a9f128c59e" "d9073f502030100"; // like rsa_private, but with a small bit of corruption static const char rsa_junk3[] = "3082025b02010002818100e16d0efd5b89d50761fc6" "b4befad25cdddfdcfc9409013e01984bb6ea88f45404df25f0f7e89d39295df774c0fca14" "91e0bb731e4af179ad3f3585671ac78002bdca7de4007ad575360d4335d3eb5f261124003" "62ee33301a947b725ce0a65bb5c4de0b66eb501032b90fd35d0faac9b7d1c1bf5dcb4fb7a" "9f128c59ed9073f50203010001028180325dfeb2672885bb8f8e299f1edf2e0a30668c6da" "80a4916923d10efe9a391528bd7f29b70a774e954a9486b6b3fb896db82a6770741aaf125" "a55cb82bc895761bd5747732c45dc1e7d58ee89fe4f0d359270e5d942ab9ae41c161b2ab5" "3ba990e64b8c93791a859ab08a026a48f7446d9aaca75279db7e8b245a9c82b6987250241" "00fdaaa281dfee19c0e959c1bcb47f3acf9243377e5884244828773e3fa2c973b4b9d4167" "43fd41f4d23471ea2e3d5354bf0807eccf1695756dd477ff8fe7c8467024100e37feb62d7" "01e4bb4849950cf5db2515a70764f7c7ae3461fe8e807c586c13a1ac01fa446a2a2740744" "1c58d297ec0daf9a77292a1d4e816807d2073a78fab43024066b5b8a72dac92f0f18b4e4e" "c226e2013a0fcd607326ce2a09787ed3f56dec53b90a8f2cf2cb49014acf79302b6020fc6" "69d20ba8ae5445fffa8fbc02e0aecf102406097c5a797c6b40958adf55d255e40a6aade96" "de25a82f9193f58954426ed0ff09fb64f97b621e7c5d6037b2b1f5a188d80b62b823eee60" "3f7d628db323febe502403f03ed55da41c33011c61014f7c6bd0d21be0292f586802f9e9c" "7e141016f2ac58b958980d874f2cc9d902b2be25ee900900cffe729d5401f1ad784992a1b" "3db"; WVTEST_MAIN("rsa isok") { { // make sure isok() doesn't crash when a private key is given WvRSAKey rsa(rsa_private, true); WVPASS(rsa.isok()); } { // make sure isok() doesn't crash when only a public key is given WvRSAKey rsa(rsa_public, false); WVPASS(rsa.isok()); } #if 0 // openssl can't verify public keys... sigh. { // catch invalid keys WvRSAKey rsa(rsa_junk, false); WVFAIL(rsa.isok()); } { // catch invalid keys WvRSAKey rsa(rsa_junk2, false); WVFAIL(rsa.isok()); } #endif { // catch invalid keys WvRSAKey rsa(rsa_junk3, true); WVFAIL(rsa.isok()); } { // make sure isok() doesn't crash when a public key is given instead // of a private key WvRSAKey rsa(rsa_public, true); WVFAIL(rsa.isok()); } } WVTEST_MAIN("rsagen") { // test to make sure copying works with private + public keys WvRSAKey rsa(512); WVPASS(1); WvRSAKey rsa_priv(rsa); WVPASS(2); WVPASSEQ(rsa.encode(WvRSAKey::RsaHex), rsa_priv.encode(WvRSAKey::RsaHex)); WVPASS(3); WvString pub_hex = rsa.encode(WvRSAKey::RsaPubHex); WvRSAKey rsa_pub(pub_hex, false); WvRSAKey rsa_pub2(rsa_pub); WVPASSEQ(rsa_pub.encode(WvRSAKey::RsaPubHex), rsa_pub2.encode(WvRSAKey::RsaPubHex)); } wvstreams-4.6.1/crypto/t/wvsslstream.t.cc0000644000175000001440000002210011202637334017514 0ustar wlachusers#include "wvtest.h" #include "wvsslstream.h" #include "wvloopback2.h" #include "wvx509mgr.h" #include "wvrsa.h" #include "wvtcp.h" #include "wvtcplistener.h" #include "wvistreamlist.h" #include "wvstrutils.h" #include #define MSG "fubar" static bool gotmessage = false; static WvX509Mgr *x509 = NULL; static WvSSLStream *singleconn = NULL; static size_t tlen = 0; static void run(WvStream &list, WvStream *s1, WvStream *s2) { for (int i = 0; i < 100; i++) { list.runonce(10); if ((s1 && s1->isreadable()) || (s2 && s2->isreadable())) break; } } static void sslloop(WvIStreamList &list, WvX509Mgr &x509, WvSSLStream *&s1, WvSSLStream *&s2, bool clicert = false) { signal(SIGPIPE, SIG_IGN); IWvStream *_s1, *_s2; wvloopback2(_s1, _s2); s1 = new WvSSLStream(_s1, &x509, 0, true); s2 = new WvSSLStream(_s2, clicert ? &x509 : NULL); list.auto_prune = false; list.append(s1, true, "s1"); list.append(s2, true, "s2"); } WVTEST_MAIN("crypto basics") { WvX509Mgr x509("cn=random_stupid_dn", 1024); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, x509, s1, s2); // test some basic data transfer WVPASS(s1->isok()); WVPASS(s2->isok()); s1->print("s1 output\ns1 line2\n"); s2->print("s2 output\ns2 line2\n"); run(list, s1, s2); WVPASSEQ(s1->blocking_getline(10000), "s2 output"); WVPASSEQ(s2->blocking_getline(10000), "s1 output"); WVPASSEQ(s2->getline(), "s1 line2"); WVPASSEQ(s1->blocking_getline(10000), "s2 line2"); // test special close() behaviour. At one point, WvSSLStream::uread() // would return nonzero, but close the stream anyway *before* returning. // This causes very confusing behaviour, because the calling stream // receives the SSL stream's closecallback() before getting the final // data from uread(). Thus, uread() should only call close() if it's // planning to return 0. s2->nowrite(); s1->print("foostring"); run(list, s1, s2); s1->cloned->close(); list.unlink(s1); // auto_prune disabled, so we need to do this by hand run(list, NULL, s2); WvDynBuf buf; WVPASSEQ(s2->read(buf, 1024), 9); WVPASSEQ(buf.getstr(), "foostring"); WVPASS(s2->isok()); run(list, NULL, s2); WVPASS(s2->isok()); WVPASSEQ(s2->read(buf, 1024), 0); WVFAIL(s2->isreadable()); run(list, NULL, s2); WVPASSEQ(s2->read(buf, 1024), 0); WVFAIL(s2->isok()); } WVTEST_MAIN("sslconnect") { WvX509Mgr x509("cn=random_stupid_dn", 1024); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, x509, s1, s2); s1->print("hello\n"); WvDynBuf buf; WVPASSEQ(s1->read(buf, 1024), 0); // make sure s1 has sent/received all the data currently in its pipe, // but without giving s2 a chance to run for (int i = 0; i < 50; i++) s1->runonce(5); WVFAIL(s1->isreadable()); for (int i = 0; i < 50; i++) s2->runonce(5); WVFAIL(s2->isreadable()); } WVTEST_MAIN("sslclose 1") { WvX509Mgr x509("cn=random_stupid_dn", 1024); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, x509, s1, s2); s2->print("hello\n"); run(list, s1, s2); WVPASSEQ(s1->getline(), "hello"); s2->cloned->close(); run(list, s1, s2); list.unlink(s2); run(list, s1, NULL); WvDynBuf buf; WVPASSEQ(s1->read(buf, 1024), 0); WVFAIL(s1->isok()); } // like sslclose1, but shutting down SSL politely (ie. closing the sslstream // instead of the underlying stream). This tests a different code path // in WvSSLStream. WVTEST_MAIN("sslclose 2") { WvX509Mgr x509("cn=random_stupid_dn", 1024); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, x509, s1, s2); s2->print("hello\n"); run(list, s1, s2); WVPASSEQ(s1->getline(), "hello"); s2->close(); run(list, s1, s2); list.unlink(s2); run(list, s1, NULL); WvDynBuf buf; WVPASSEQ(s1->read(buf, 1024), 0); WVFAIL(s1->isok()); } // This test relies on the fact that reading a stream will never cause it // to go !isok() until the inbuf is actually empty. I'm not sure if that's // desirable behaviour or not, but it definitely isn't the *current* // behaviour. Rather than try to fix it, let's comment out the test for now; // there seems to be no remaining way to actually aggravate the problem other // than what we do in this test (which is definitely impolite behaviour). // -- apenwarr (2004/11/09) #if INBUF_CONTENT_ALWAYS_PREVENTS_NOT_ISOK WVTEST_MAIN("ssl inbuf after read error") { WvX509Mgr x509("cn=random_stupid_dn", 1024); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, x509, s1, s2); // connect up run(list, s1, s2); s2->nowrite(); s1->print("1\n2\n"); s1->flush(0); WVPASS(1); run(list, s1, s2); s1->print("3\n4"); WVPASS(1); run(list, s1, s2); s1->cloned->close(); WVPASS(1); run(list, s1, s2); WVFAIL(s1->isok()); WVPASSEQ(s2->blocking_getline(10000), "1"); WVPASSEQ(s2->blocking_getline(10000), "2"); WVPASS(s2->isok()); // force SSL to try reading again, even though it doesn't need to. This // emulates a poorly-behaved wrapper stream, like maybe WvEncoderStream. s2->queuemin(1024); char buf[1024]; WVFAIL(s2->read(buf, 1024)); WVFAIL(s2->read(buf, 1024)); s2->queuemin(0); // inbuf still has data! WVPASS(s2->isok()); WVPASSEQ(s2->blocking_getline(10000), "3"); WVPASSEQ(s2->blocking_getline(10000), "4"); WVFAIL(s2->blocking_getline(10000)); WVFAIL(s2->isok()); } #endif static void do_transfer(WvSSLStream *ssl) { char buf[1024]; int rlen = ssl->read(buf, sizeof(buf)); tlen += rlen; printf("Read %d bytes (%zd total)\n", rlen, tlen); } static void getmessage(WvSSLStream *ssl) { singleconn = ssl; WvString msg = ssl->getline(0); if (msg == MSG) gotmessage = true; } static void lcallback(IWvStream *conn) { WvSSLStream *ssl = new WvSSLStream(conn, x509, 0, true); ssl->setcallback(wv::bind(getmessage, ssl)); WvIStreamList::globallist.append(ssl, true, "ssl stream"); } WVTEST_MAIN("ssl establish connection") { WvIStreamList::globallist.zap(); int port = 0; WvString hname(hostname()), dname(fqdomainname()); WvString dn("cn=%s,dc=%s", dname, dname); WvRSAKey *rsa = new WvRSAKey(1024); x509 = new WvX509Mgr(dn, rsa); WVPASS(x509->test()); WvString laddrstr("0.0.0.0:%s", port); WvIPPortAddr laddr(laddrstr); WvTCPListener l(laddr); l.onaccept(lcallback); WvIStreamList::globallist.append(&l, false, "listener"); printf("Starting listener on %s\n", laddrstr.cstr()); WVPASS(l.isok()); if (!l.isok()) wvcon->print("Error was: %s\n", l.errstr()); // get the port we actually bound to port = l.src()->port; printf("Using port %d\n", port); WvString caddrstr("127.0.0.1:%s", port); WvIPPortAddr caddr(caddrstr); WvTCPConn *c = new WvTCPConn(caddr); WvSSLStream *ssl = new WvSSLStream(c, NULL); WvIStreamList::globallist.append(ssl, true, "ssl stream"); WVPASS(ssl->isok()); if (!ssl->isok()) wvcon->print("Error was: %s\n", ssl->errstr()); // wait for ssl to connect ssl->force_select(false, true, false); for (int i=0; i<10; i++) { WvIStreamList::globallist.runonce(); if (ssl->iswritable()) break; } // send a message and ensure it's received ssl->print(MSG "\n"); WvIStreamList::globallist.runonce(); WVPASS(gotmessage); // check for BUGZID:10781 char data[20000]; size_t wlen = ssl->write(data, sizeof(data)); printf("Wrote %zd bytes\n", wlen); // setup for next test singleconn->setcallback(wv::bind(do_transfer, singleconn)); WVPASS(singleconn->select(0)); // read until we get all the data, or die if there's ever none // because it's all there already while (tlen < wlen && WvIStreamList::globallist.select(10000)) WvIStreamList::globallist.callback(); // if this fails, see BUGZID:10781 WVPASS(tlen == wlen); WVRELEASE(x509); WvIStreamList::globallist.zap(); } WVTEST_MAIN("x509 refcounting") { WvX509Mgr *x509 = new WvX509Mgr("cn=random_stupid_dn,dn=foo", 512); WvIStreamList list; WvSSLStream *s1, *s2; sslloop(list, *x509, s1, s2, true); WVRELEASE(x509); run(list, s1, s2); s1->write("Hello\n"); run(list, s1, s2); WVPASSEQ(s2->getline(-1), "Hello"); s2->write("Yellow\n"); run(list, s1, s2); WVPASSEQ(s1->getline(-1), "Yellow"); } WVTEST_MAIN("sslcert moniker creation") { WvX509Mgr foo("cn=random_stupid_dn,dn=foo", 1024, false); WvList l; WvString certpem = foo.encode(WvX509::CertPEM); WvString rsapem = foo.encode(WvRSAKey::RsaPEM); WvString connmoniker("tcp:127.0.0.1:2222"); l.append(&certpem, false); l.append(&rsapem, false); l.append(&connmoniker, false); IWvStream *dumb = IWvStream::create(WvString("%s%s", "sslcert:", wvtcl_encode(l))); WVPASS(dumb != NULL); if (dumb) WVPASSEQ(dumb->wstype(), "WvSSLStream"); WVRELEASE(dumb); } wvstreams-4.6.1/crypto/t/wvcrl.t.cc0000644000175000001440000000570311077124114016266 0ustar wlachusers#include "wvtest.h" #include "wvcrl.h" #include "wvfile.h" #include "wvfileutils.h" #include "wvx509mgr.h" // default keylen for where we're not using pre-existing certs const static int DEFAULT_KEYLEN = 512; const static char crl_pem[] = "-----BEGIN X509 CRL-----\n" "MIIBOjCBpAIBATANBgkqhkiG9w0BAQUFADBBMQswCQYDVQQGEwJVUzEaMBgGA1UE\n" "ChMRVGVzdCBDZXJ0aWZpY2F0ZXMxFjAUBgNVBAMTDUJhZCBTaWduZWQgQ0EXDTAx\n" "MDQxOTE0NTcyMFoXDTExMDQxOTE0NTcyMFqgLzAtMB8GA1UdIwQYMBaAFEIbb5cL\n" "I3kfwQhXnjqmCpyQiB/YMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUAA4GBABGR\n" "fRmlA06n8R8YYpT6l6BGQZYxlRlJeanl8YSqyNzIf5IH5PxmlpsujnOqrXARGf2O\n" "vvJ0P3kCWuYqZ7RG1x2K3sjQt8z2hduQpkacrSMJR6rwREVj9UDd/HW/S4Uv+nQJ\n" "+BmPKZeSrjRcbmtrQHRRWCbflbdyEz2xdpoKQzcx\n" "-----END X509 CRL-----\n"; WVTEST_MAIN("decoding and encoding basics") { WvCRL crl; crl.decode(WvCRL::CRLPEM, crl_pem); WVPASSEQ(crl.get_aki(), "42:1B:6F:97:0B:23:79:1F:C1:08:57:9E:3A:A6:0A:9C:90:88:1F:D8"); WVPASSEQ(crl.get_issuer(), "/C=US/O=Test Certificates/CN=Bad Signed CA"); WvString s = crl.encode(WvCRL::CRLPEM); WVPASSEQ(s, crl_pem); WvDynBuf d; crl.encode(WvCRL::CRLDER, d); WVPASSEQ(d.used(), 318); // size of der encoded certificate WvCRL crl2; crl2.decode(WvCRL::CRLDER, d); WVPASSEQ(crl.get_aki(), crl2.get_aki()); } WVTEST_MAIN("CRL creation and use basics") { WvX509Mgr ca("cn=testca.ca,dc=testca,dc=ca", DEFAULT_KEYLEN, true); WvCRL crl(ca); WVPASSEQ(crl.numcerts(), 0); WVPASSEQ(crl.get_issuer(), ca.get_subject()); WVPASSEQ(crl.get_aki(), ca.get_ski()); WVPASS(crl.signedbyca(ca)); WvRSAKey rsakey(DEFAULT_KEYLEN); WvString certreq = WvX509Mgr::certreq( "cn=test.signed.com,dc=signed,dc=com", rsakey); WvString srequest = ca.signreq(certreq); WvX509 user; user.decode(WvX509::CertPEM, srequest); WVFAIL(crl.isrevoked(user)); WVFAIL(crl.isrevoked(user.get_serial())); crl.addcert(user); WVPASSEQ(crl.numcerts(), 1); WVPASS(crl.isrevoked(user)); WVPASS(crl.isrevoked(user.get_serial())); } static bool exists(WvStringParm filename) { return access(filename, F_OK) == 0; } bool test_encode_load_file(WvCRL::DumpMode mode) { WvString tmpfile = wvtmpfilename("crl"); WvX509Mgr ca("o=ca", DEFAULT_KEYLEN, true); WvCRL crl1(ca); WVPASS(exists(tmpfile)); { WvFile f(tmpfile, O_WRONLY); WvDynBuf buf; crl1.encode(mode, buf); f.write(buf, buf.used()); } WVPASS(exists(tmpfile)); WvCRL crl2; if (mode == WvCRL::CRLPEM) crl2.decode(WvCRL::CRLFilePEM, tmpfile); else crl2.decode(WvCRL::CRLFileDER, tmpfile); ::unlink(tmpfile); WVFAIL(exists(tmpfile)); WVPASSEQ(crl1.get_issuer(), crl2.get_issuer()); return (crl1.get_issuer() == crl2.get_issuer()); } WVTEST_MAIN("Loading/unloading from file") { WVPASS(test_encode_load_file(WvCRL::CRLPEM)); WVPASS(test_encode_load_file(WvCRL::CRLDER)); } wvstreams-4.6.1/crypto/wvsslhacks.c0000644000175000001440000000223111077124114016442 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Functions to make us compile with both newer and older versions of openssl. * * THIS FILE MUST BE COMPILED AS STANDARD C, NOT C++!!! * * See wvsslhacks.h. */ #include "wvsslhacks.h" RSA *wv_d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length) { return d2i_RSAPublicKey(a, (void *)pp, length); } RSA *wv_d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length) { return d2i_RSAPrivateKey(a, (void *)pp, length); } DSA *wv_d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length) { return d2i_DSAPublicKey(a, (void *)pp, length); } DSA *wv_d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length) { return d2i_DSAPrivateKey(a, (void *)pp, length); } X509_REQ *wv_d2i_X509_REQ(X509_REQ **a, const unsigned char **pp, long length) { return d2i_X509_REQ(a, (void *)pp, length); } X509 *wv_d2i_X509(X509 **a, unsigned char **pp, long length) { return d2i_X509(a, (void *)pp, length); } int wv_i2d_OCSP_REQUEST_bio(BIO *bio, OCSP_REQUEST *req) { return i2d_OCSP_REQUEST_bio(bio, req); } wvstreams-4.6.1/crypto/wvx509mgr.cc0000644000175000001440000003625111100162104016202 0ustar wlachusers#include "wvbase64.h" #include "wvsslhacks.h" #include "wvx509mgr.h" #include "wvautoconf.h" #include #include #include #include #include #include namespace { class AutoClose { public: AutoClose(FILE *fp): fp(fp) { } ~AutoClose() { if (fp) fclose(fp); } operator FILE *() const { return fp; } private: FILE *fp; }; } // anomymous namespace... WvX509Mgr::WvX509Mgr() : WvX509(), debug("X509 Manager", WvLog::Debug5) { rsa = NULL; } WvX509Mgr::WvX509Mgr(const WvX509Mgr &x) : WvX509(x), debug("X509 Manager", WvLog::Debug5) { rsa = NULL; set_rsa(x.rsa); } WvX509Mgr::WvX509Mgr(WvStringParm _dname, WvRSAKey *_rsa, bool ca) : WvX509(), debug("X509 Manager", WvLog::Debug5) { debug("Creating new certificate+key pair for %s.\n", _dname); rsa = _rsa; if (!!_dname) { create_selfissued(_dname, ca); debug("Ok - Parameters set... now signing certificate.\n"); signcert(*this); } else debug("Sorry, can't create an anonymous certificate."); } WvX509Mgr::WvX509Mgr(WvStringParm _dname, int bits, bool ca) : WvX509(), debug("X509 Manager", WvLog::Debug5) { debug("Creating new certificate+key pair for %s.\n", _dname); rsa = NULL; if (!!_dname) { rsa = new WvRSAKey(bits); create_selfissued(_dname, ca); debug("Ok - Parameters set... now signing certificate.\n"); signcert(*this); } else debug("Sorry, can't create an anonymous certificate."); } void WvX509Mgr::create_selfissued(WvStringParm dname, bool is_ca) { if (cert) { debug("Replacing already existant certificate...\n"); X509_free(cert); cert = NULL; } // double check RSA key if (rsa->isok()) debug("RSA Key is fine.\n"); else return; if ((cert = X509_new()) == NULL) return; // Completely broken in my mind - this sets the version // string to '3' (I guess version starts at 0) set_version(); // RFC2459 says that this number must be unique for each certificate // issued by a CA. It may be that some web browsers get confused if // more than one cert with the same name has the same serial number, so // let's be careful. srand(time(NULL)); int serial = rand(); set_serial(serial); // 10 years... set_lifetime(60*60*24*3650); set_pubkey(*rsa); set_issuer(dname); set_subject(dname); set_ski(); if (is_ca) { debug("Setting Extensions with CA Parameters.\n"); debug("Setting Key Usage.\n"); set_key_usage("critical, keyCertSign, cRLSign"); debug("Setting Basic Constraints.\n"); set_extension(NID_basic_constraints, "critical, CA:TRUE"); debug("Setting Netscape Certificate Type.\n"); set_extension(NID_netscape_cert_type, "SSL CA, S/MIME CA, Object Signing CA"); #if 0 // uncomment this to allow certificate to be used as // an OCSP signer (seems too obscure to enable by default // right now). set_ext_key_usage("OCSP Signing"); #endif // debug("Setting Constraints.\n"); // set_constraints("requireExplicitPolicy"); } else { debug("Setting Key Usage with normal server parameters\n"); set_nsserver(dname); set_key_usage("critical, digitalSignature, keyEncipherment, " "keyAgreement"); set_extension(NID_basic_constraints, "CA:FALSE"); set_ext_key_usage("TLS Web Server Authentication," "TLS Web Client Authentication"); } // we do not actually sign the certificate here: that must be done by the // user (WvX509Mgr most likely) debug("Certificate for %s created\n", dname); } WvX509Mgr::~WvX509Mgr() { debug("Deleting.\n"); WVDELETE(rsa); } bool WvX509Mgr::isok() const { return WvX509::isok() && rsa && rsa->isok() && test(); } bool WvX509Mgr::operator! () const { return !isok(); } WvString WvX509Mgr::errstr() const { if (!WvX509::isok()) return WvX509::errstr(); if (!rsa) return "No RSA key set."; else if (!rsa->isok()) return "RSA key not valid."; else if (!test()) return "RSA key and certificate do not match."; return WvString::empty; } bool WvX509Mgr::bind_ssl(SSL_CTX *ctx) { if (SSL_CTX_use_certificate(ctx, get_cert()) <= 0) { return false; } debug("Certificate activated.\n"); if (SSL_CTX_use_RSAPrivateKey(ctx, rsa->rsa) <= 0) { return false; } debug("RSA private key activated.\n"); return true; } bool WvX509Mgr::test() const { if (!cert) { debug("No X509 certificate: test fails.\n"); return false; } if (rsa) { EVP_PKEY *pk = EVP_PKEY_new(); assert(pk); if (!EVP_PKEY_set1_RSA(pk, rsa->rsa)) { debug("Error setting RSA keys: test fails.\n"); EVP_PKEY_free(pk); return false; } bool bad = false; int verify_return = X509_verify(cert, pk); if (verify_return != 1) // only '1' means okay { // However let's double check: WvString rsapub = rsa->encode(WvRSAKey::RsaPubPEM); WvRSAKey *temprsa = get_rsa_pub(); WvString certpub = temprsa->encode(WvRSAKey::RsaPubPEM); delete temprsa; // debug("rsapub:\n%s\n", rsapub); // debug("certpub:\n%s\n", certpub); if (certpub == rsapub) ; // do nothing, since OpenSSL is lying else { // I guess that it really did fail. debug("Certificate test failed: %s\n", wvssl_errstr()); bad = true; } } EVP_PKEY_free(pk); return !bad; } return false; } WvString WvX509Mgr::signreq(WvStringParm pkcs10req) const { debug("Signing a certificate request with: %s\n", get_subject()); if (!isok()) { debug(WvLog::Warning, "Asked to sign certificate request, but not ok! " "Aborting.\n"); return false; } // Break this next part out into a de-pemify section, since that is what // this part up until the FIXME: is about. WvString pkcs10(pkcs10req); BIO *membuf = BIO_new(BIO_s_mem()); BIO_write(membuf, pkcs10req, pkcs10req.len()); X509_REQ *certreq = PEM_read_bio_X509_REQ(membuf, NULL, NULL, NULL); BIO_free_all(membuf); if (certreq) { WvX509 newcert(X509_new()); newcert.set_subject(X509_REQ_get_subject_name(certreq)); newcert.set_version(); // Set the Serial Number for the certificate srand(time(NULL)); int serial = rand(); newcert.set_serial(serial); newcert.set_lifetime(60*60*24*3650); // The public key of the new cert should be the same as that from // the request. EVP_PKEY *pk = X509_REQ_get_pubkey(certreq); X509_set_pubkey(newcert.get_cert(), pk); EVP_PKEY_free(pk); // every good cert needs an ski+aki newcert.set_ski(); newcert.set_aki(*this); // The Issuer name is the subject name of the current cert newcert.set_issuer(*this); X509_EXTENSION *ex = NULL; // Set the RFC2459-mandated keyUsage field to critical, and restrict // the usage of this cert to digital signature and key encipherment. newcert.set_key_usage("critical, digitalSignature, keyEncipherment"); // This could cause Netscape to barf because if we set // basicConstraints to critical, we break RFC2459 compliance. Why // they chose to enforce that bit, and not the rest is beyond me... // but oh well... ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, (char*)"CA:FALSE"); X509_add_ext(newcert.get_cert(), ex, -1); X509_EXTENSION_free(ex); newcert.set_ext_key_usage("critical, TLS Web Client Authentication"); signcert(newcert); X509_REQ_free(certreq); return WvString(newcert.encode(WvX509::CertPEM)); } else { debug("Can't decode Certificate Request\n"); return WvString::null; } } bool WvX509Mgr::signcert(WvX509 &unsignedcert) const { if (!isok()) { debug(WvLog::Warning, "Asked to sign certificate, but not ok! " "Aborting.\n"); return false; } if (cert == unsignedcert.cert) { debug("Self Signing!\n"); } #ifdef HAVE_OPENSSL_POLICY_MAPPING else if (!X509_check_ca(cert)) { debug("This certificate is not a CA, and is thus not allowed to sign " "certificates!\n"); return false; } #endif else if (!((cert->ex_flags & EXFLAG_KUSAGE) && (cert->ex_kusage & KU_KEY_CERT_SIGN))) { debug("This Certificate is not allowed to sign certificates!\n"); return false; } debug("Ok, now sign the new cert with the current RSA key.\n"); EVP_PKEY *certkey = EVP_PKEY_new(); bool cakeyok = EVP_PKEY_set1_RSA(certkey, rsa->rsa); if (cakeyok) { X509_sign(unsignedcert.get_cert(), certkey, EVP_sha1()); } else { debug("No keys??\n"); EVP_PKEY_free(certkey); return false; } EVP_PKEY_free(certkey); return true; } bool WvX509Mgr::signcrl(WvCRL &crl) const { if (!isok() || !crl.isok()) { debug(WvLog::Warning, "Asked to sign CRL, but certificate or CRL (or " "both) not ok! Aborting.\n"); return false; } #ifdef HAVE_OPENSSL_POLICY_MAPPING else if (!X509_check_ca(cert)) { debug("This certificate is not a CA, and is thus not allowed to sign " "CRLs!\n"); return false; } else if (!((cert->ex_flags & EXFLAG_KUSAGE) && (cert->ex_kusage & KU_CRL_SIGN))) { debug("Certificate not allowed to sign CRLs! (%s %s)\n", (cert->ex_flags & EXFLAG_KUSAGE), (cert->ex_kusage & KU_CRL_SIGN)); return false; } #endif EVP_PKEY *certkey = EVP_PKEY_new(); bool cakeyok = EVP_PKEY_set1_RSA(certkey, rsa->rsa); if (cakeyok) { ASN1_TIME *tmptm = ASN1_TIME_new(); // Set the LastUpdate time to now. X509_gmtime_adj(tmptm, 0); X509_CRL_set_lastUpdate(crl.getcrl(), tmptm); // CRL's are valid for 30 days X509_gmtime_adj(tmptm, (long)60*60*24*30); X509_CRL_set_nextUpdate(crl.getcrl(), tmptm); ASN1_TIME_free(tmptm); // OK - now sign it... X509_CRL_sign(crl.getcrl(), certkey, EVP_sha1()); } else { debug(WvLog::Warning, "Asked to sign CRL, but no RSA key associated " "with certificate. Aborting.\n"); EVP_PKEY_free(certkey); return false; } EVP_PKEY_free(certkey); return true; } WvString WvX509Mgr::sign(WvStringParm data) const { WvDynBuf buf; buf.putstr(data); return sign(buf); } WvString WvX509Mgr::sign(WvBuf &data) const { assert(rsa); EVP_MD_CTX sig_ctx; unsigned char sig_buf[4096]; EVP_PKEY *pk = EVP_PKEY_new(); assert(pk); // OOM if (!EVP_PKEY_set1_RSA(pk, rsa->rsa)) { debug("Error setting RSA keys.\n"); EVP_PKEY_free(pk); return WvString::null; } EVP_SignInit(&sig_ctx, EVP_sha1()); EVP_SignUpdate(&sig_ctx, data.peek(0, data.used()), data.used()); unsigned int sig_len = sizeof(sig_buf); int sig_err = EVP_SignFinal(&sig_ctx, sig_buf, &sig_len, pk); if (sig_err != 1) { debug("Error while signing.\n"); EVP_PKEY_free(pk); return WvString::null; } EVP_PKEY_free(pk); EVP_MD_CTX_cleanup(&sig_ctx); // this isn't my fault :// WvDynBuf buf; buf.put(sig_buf, sig_len); debug("Signature size: %s\n", buf.used()); return WvBase64Encoder().strflushbuf(buf, true); } bool WvX509Mgr::write_p12(WvStringParm _fname, WvStringParm _pkcs12pass) const { debug("Dumping RSA Key and X509 Cert to PKCS12 structure.\n"); AutoClose fp = fopen(_fname, "wb"); if (!fp) { debug(WvLog::Warning, "Unable to open file. Error: %s\n", strerror(errno)); return false; } if (!!_pkcs12pass) { if (rsa && cert) { EVP_PKEY *pk = EVP_PKEY_new(); assert(pk); // OOM if (!EVP_PKEY_set1_RSA(pk, rsa->rsa)) { debug("Error setting RSA keys.\n"); EVP_PKEY_free(pk); return false; } else { WvString pkcs12pass(_pkcs12pass); PKCS12 *pkg = PKCS12_create(pkcs12pass.edit(), (char*)"foo", pk, cert, NULL, 0, 0, 0, 0, 0); if (pkg) { debug("Writing the PKCS12 object out...\n"); i2d_PKCS12_fp(fp, pkg); PKCS12_free(pkg); EVP_PKEY_free(pk); } else { debug(WvLog::Warning, "Unable to create PKCS12 object."); EVP_PKEY_free(pk); return false; } } } else { debug(WvLog::Warning, "The RSA key or the certificate is not present."); return false; } } else { debug(WvLog::Warning, "No password specified for PKCS12 dump."); return false; } return true; } void WvX509Mgr::read_p12(WvStringParm _fname, WvStringParm _pkcs12pass) { debug("Reading Certificate and Private Key from PKCS12 file: %s\n", _fname); if (rsa) WVDELETE(rsa); AutoClose fp = fopen(_fname, "r"); if (!fp) { debug("Unable to open file '%s'!\n", _fname); return; } if (!!_pkcs12pass) { PKCS12 *pkg = d2i_PKCS12_fp(fp, NULL); if (pkg) { EVP_PKEY *pk = NULL; // Parse out the bits out the PKCS12 package. X509 *x; PKCS12_parse(pkg, _pkcs12pass, &pk, &x, NULL); PKCS12_free(pkg); if (!pk || !x) { debug("Could not decode pkcs12 file.\n"); EVP_PKEY_free(pk); return; } cert = x; // Now, cert should be OK, let's try and set up the RSA stuff // since we've essentially got a PKEY, and not a WvRSAKey // We need to create a new WvRSAKey from the PKEY... rsa = new WvRSAKey(EVP_PKEY_get1_RSA(pk), true); EVP_PKEY_free(pk); // Now that we have both, check to make sure that they match if (!test()) { debug("Could not fill in RSA and certificate with matching " "values! Expect problems.\n"); return; } } else { debug("Read in of PKCS12 file '%s' failed", _fname); return; } } else { debug("No password specified for PKCS12 file\n"); return; } } WvString WvX509Mgr::encode(const WvRSAKey::DumpMode mode) const { if (rsa) return rsa->encode(mode); return ""; } WvString WvX509Mgr::encode(const WvX509::DumpMode mode) const { return WvX509::encode(mode); } void WvX509Mgr::encode(const WvRSAKey::DumpMode mode, WvBuf &buf) const { if (rsa) rsa->encode(mode, buf); } void WvX509Mgr::encode(const WvX509::DumpMode mode, WvBuf &buf) const { WvX509::encode(mode, buf); } void WvX509Mgr::decode(const WvRSAKey::DumpMode mode, WvStringParm encoded) { if (rsa) rsa->decode(mode, encoded); else { rsa = new WvRSAKey(); rsa->decode(mode, encoded); } } void WvX509Mgr::decode(const WvX509::DumpMode mode, WvStringParm encoded) { WvX509::decode(mode, encoded); } void WvX509Mgr::decode(const WvRSAKey::DumpMode mode, WvBuf &encoded) { if (rsa) rsa->decode(mode, encoded); else { rsa = new WvRSAKey(); rsa->decode(mode, encoded); } } void WvX509Mgr::decode(const WvX509::DumpMode mode, WvBuf &encoded) { WvX509::decode(mode, encoded); } wvstreams-4.6.1/crypto/wvcountermode.cc0000644000175000001440000000452611036722347017336 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A 'counter mode' cryptography engine abstraction. */ #include "wvcountermode.h" WvCounterModeEncoder::WvCounterModeEncoder(WvEncoder *_keycrypt, const void *_counter, size_t _countersize) : keycrypt(_keycrypt), counter(NULL) { setcounter(_counter, _countersize); } WvCounterModeEncoder::~WvCounterModeEncoder() { delete keycrypt; deletev counter; } void WvCounterModeEncoder::setcounter(const void *_counter, size_t _countersize) { deletev counter; counter = new unsigned char[_countersize]; countersize = _countersize; memcpy(counter, _counter, countersize); } void WvCounterModeEncoder::getcounter(void *_counter) const { memcpy(_counter, counter, countersize); } void WvCounterModeEncoder::incrcounter() { for (size_t i = 0; i < countersize && ! ++counter[i]; ++i); } bool WvCounterModeEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { bool success = true; size_t avail = inbuf.used(); size_t offset = outbuf.used(); // generate a key stream size_t len; for (len = avail; len >= countersize; len -= countersize) { counterbuf.reset(counter, countersize); success = keycrypt->encode(counterbuf, outbuf, true); if (! success) break; incrcounter(); } if (flush && len != 0 && success) { counterbuf.reset(counter, countersize); success = keycrypt->encode(counterbuf, outbuf, true); if (success) { outbuf.unalloc(countersize - len); len = 0; incrcounter(); } else outbuf.unalloc(outbuf.used() - offset - avail); } avail -= len; // XOR in the data while (avail > 0) { len = outbuf.optpeekable(offset); unsigned char *dataout = outbuf.mutablepeek(offset, len); size_t lenopt = inbuf.optgettable(); if (len > lenopt) len = lenopt; const unsigned char *datain = inbuf.get(len); if (len >= avail) { len = avail; avail = 0; } else { avail -= len; offset += len; } while (len-- > 0) *(dataout++) ^= *(datain++); } return success; } wvstreams-4.6.1/crypto/wvblowfish.cc0000644000175000001440000000610611036722347016623 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Blowfish cryptography abstractions. */ #include "wvblowfish.h" #include #include #include /***** WvBlowfishEncoder ****/ WvBlowfishEncoder::WvBlowfishEncoder(Mode _mode, const void *_key, size_t _keysize) : mode(_mode), key(NULL), bfkey(NULL) { setkey(_key, _keysize); } WvBlowfishEncoder::~WvBlowfishEncoder() { deletev key; delete bfkey; } bool WvBlowfishEncoder::_reset() { preparekey(); return true; } void WvBlowfishEncoder::setkey(const void *_key, size_t _keysize) { deletev key; keysize = _keysize; key = new unsigned char[keysize]; memcpy(key, _key, keysize); preparekey(); } void WvBlowfishEncoder::setiv(const void *_iv) { memcpy(ivec, _iv, sizeof(ivec)); ivecoff = 0; } void WvBlowfishEncoder::preparekey() { delete bfkey; bfkey = new BF_KEY; BF_set_key(bfkey, keysize, key); memset(ivec, 0, sizeof(ivec)); ivecoff = 0; } bool WvBlowfishEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { size_t len = in.used(); bool success = true; switch (mode) { case ECBEncrypt: case ECBDecrypt: { size_t remainder = len & 7; len -= remainder; if (remainder != 0 && flush) { if (mode == ECBEncrypt) { // if flushing on encryption, add some randomized padding size_t padlen = 8 - remainder; unsigned char *pad = in.alloc(padlen); RAND_pseudo_bytes(pad, padlen); len += 8; } else // nothing we can do here, flushing does not make sense! success = false; } } default: break; } if (len == 0) return success; const unsigned char *data = in.get(len); unsigned char *crypt = out.alloc(len); switch (mode) { case ECBEncrypt: case ECBDecrypt: // ECB works 64bits at a time while (len >= 8) { BF_ecb_encrypt(data, crypt, bfkey, mode == ECBEncrypt ? BF_ENCRYPT : BF_DECRYPT); len -= 8; data += 8; crypt += 8; } break; case CFBEncrypt: case CFBDecrypt: // CFB simulates a stream BF_cfb64_encrypt(data, crypt, len, bfkey, ivec, &ivecoff, mode == CFBEncrypt ? BF_ENCRYPT : BF_DECRYPT); break; } return success; } /***** WvBlowfishStream *****/ WvBlowfishStream::WvBlowfishStream(WvStream *_cloned, const void *_key, size_t _keysize, WvBlowfishEncoder::Mode readmode, WvBlowfishEncoder::Mode writemode) : WvEncoderStream(_cloned) { readchain.append(new WvBlowfishEncoder(readmode, _key, _keysize), true); writechain.append(new WvBlowfishEncoder(writemode, _key, _keysize), true); } wvstreams-4.6.1/crypto/wvsslstream.cc0000644000175000001440000005010411061256402017010 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #define OPENSSL_NO_KRB5 #include "wvsslstream.h" #include "wvx509mgr.h" #include "wvcrypto.h" #include "wvlistener.h" #include "wvstrutils.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #include #include #include #ifndef _WIN32 # if HAVE_ARGZ_H # include # else # if HAVE_ERRNO_H # include # endif # endif #else #undef errno #define errno GetLastError() #undef EAGAIN #define EAGAIN WSAEWOULDBLOCK #endif WV_LINK(WvSSLStream); static IWvStream *creator(WvStringParm s, IObject *_obj) { return new WvSSLStream(IWvStream::create(s, _obj), NULL, 0, false); } static IWvStream *screator(WvStringParm s, IObject *_obj) { return new WvSSLStream(IWvStream::create(s, _obj), new WvX509Mgr(encode_hostname_as_DN(fqdomainname()), 1024), 0, true); } struct WvTclParseValues { WvX509Mgr *m; WvString s; /* Kind of necessary; the WvX509Mgr object here is meant to be passed into * a WvSSLStream, which will addRef() the object. Thus, once the stream * has been created, we need to release() it here, so that once the stream * itself falls into oblivion, we have no hanging references. */ ~WvTclParseValues() { WVRELEASE(m); } }; static WvTclParseValues *parse_wvtcl_sslcert(WvStringParm s) { /* The idea here is that we've got s, which is a TclStyle string of the * format (without the quotes, of course, but escaped): * "PEM-encoded SSL cert" "PEM-encoded private RSA key" "connection moniker" */ WvList l; wvtcl_decode(l, s); if (l.count() > 3 || l.count() < 2) return NULL; /* we fscked up, no clue how to recover */ // in the case of '2', 'obj' had better be set to the calling function WvTclParseValues *p = new WvTclParseValues; p->m = new WvX509Mgr; p->m->decode(WvX509::CertPEM, *l.first()); l.unlink_first(); p->m->decode(WvRSAKey::RsaPEM, *l.first()); l.unlink_first(); if (!p->m->test()) { /* RSA key and certificate don't match up?? */ delete p; return NULL; } if (l.count()) p->s = *l.first(); return p; } static IWvStream *sslcertcreator(WvStringParm s, IObject *_obj) { WvTclParseValues *p = parse_wvtcl_sslcert(s); if (!p) { WVRELEASE(_obj); return NULL; } WvSSLStream *ret = new WvSSLStream(IWvStream::create(p->s, _obj), p->m, 0, false); delete p; return ret; } static IWvStream *sslcertscreator(WvStringParm s, IObject *_obj) { WvTclParseValues *p = parse_wvtcl_sslcert(s); if (!p) { WVRELEASE(_obj); return NULL; } WvSSLStream *ret = new WvSSLStream(IWvStream::create(p->s, _obj), p->m, 0, true); delete p; return ret; } static WvMoniker reg("ssl", creator); static WvMoniker sreg("sslserv", screator); static WvMoniker sslcertreg("sslcert", sslcertcreator); static WvMoniker sslcertsreg("sslcertserv", sslcertscreator); static IWvListener *listener(WvStringParm s, IObject *obj) { IWvListener *l = IWvListener::create(s, obj); if (l) l->addwrap(wv::bind(&IWvStream::create, "sslserv", _1)); return l; } static IWvListener *sslcertlistener(WvStringParm s, IObject *obj) { WvList li; wvtcl_decode(li, s); WvString connmoniker; if (li.count() == 3) { // We have a connection moniker as well as SSL information connmoniker = *li.last(); li.unlink(li.last()); } else if (li.count() != 2) { // something went very wrong WVRELEASE(obj); return NULL; } IWvListener *l = IWvListener::create(connmoniker, obj); if (l) l->addwrap(wv::bind(&IWvStream::create, WvString("sslcertserv:%s", wvtcl_encode(li)), _1)); return l; } static WvMoniker lreg("ssl", listener); static WvMoniker lsslcertreg("sslcert", sslcertlistener); #define MAX_BOUNCE_AMOUNT (16384) // 1 SSLv3/TLSv1 record static int ssl_stream_count = 0; static int wv_verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { // This is just returns true, since what we really want // is for the WvSSLValidateCallback to do this work return 1; } WvSSLGlobalValidateCallback WvSSLStream::global_vcb = 0; WvSSLStream::WvSSLStream(IWvStream *_slave, WvX509Mgr *_x509, WvSSLValidateCallback _vcb, bool _is_server) : WvStreamClone(_slave), debug(WvString("WvSSLStream %s", ++ssl_stream_count), WvLog::Debug5), write_bouncebuf(MAX_BOUNCE_AMOUNT), write_eat(0), read_bouncebuf(MAX_BOUNCE_AMOUNT), read_pending(false) { x509 = _x509; if (x509) x509->addRef(); // openssl may keep a pointer to this object vcb = _vcb; if (!vcb && global_vcb) vcb = wv::bind(global_vcb, _1, this);; is_server = _is_server; ctx = NULL; ssl = NULL; //meth = NULL; sslconnected = ssl_stop_read = ssl_stop_write = false; wvssl_init(); if (x509 && !x509->isok()) { seterr("Certificate + key pair invalid."); return; } if (is_server && !x509) { seterr("Certificate not available: server mode not possible!"); return; } if (is_server) { debug("Configured algorithms and methods for server mode.\n"); ctx = SSL_CTX_new(SSLv23_server_method()); if (!ctx) { ERR_print_errors_fp(stderr); debug("Can't get SSL context! Error: %s\n", ERR_reason_error_string(ERR_get_error())); seterr("Can't get SSL context!"); return; } // Allow SSL Writes to only write part of a request... SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); // Tell SSL to use 128 bit or better ciphers - this appears to // be necessary for some reason... *sigh* SSL_CTX_set_cipher_list(ctx, "HIGH"); // Enable the workarounds for broken clients and servers // and disable the insecure SSLv2 protocol SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2); if (!x509->bind_ssl(ctx)) { seterr("Unable to bind Certificate to SSL Context!"); return; } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, wv_verify_cb); debug("Server mode ready.\n"); } else { debug("Configured algorithms and methods for client mode.\n"); ctx = SSL_CTX_new(SSLv23_client_method()); if (!ctx) { seterr("Can't get SSL context!"); return; } if (x509 && !x509->bind_ssl(ctx)) { seterr("Unable to bind Certificate to SSL Context!"); return; } } //SSL_CTX_set_read_ahead(ctx, 1); ERR_clear_error(); ssl = SSL_new(ctx); if (!ssl) { seterr("Can't create SSL object!"); return; } // If we set this, it seems we always verify the client... security hole, // no? Well, if we don't set it, the server doesn't even ask the client // for a certificate, so, ya know, it's not actually any more secure. // Client doesn't need this (unless vcb is set), since it always asks the // server for a cert anyway if (!!vcb || is_server) SSL_set_verify(ssl, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, wv_verify_cb); connect_wants.readable = true; connect_wants.writable = true; // force ssl initiation ASAP connect_wants.isexception = false; debug("SSL stream initialized.\n"); } WvSSLStream::~WvSSLStream() { close(); debug("Deleting SSL connection.\n"); if (geterr()) debug("Error was: %s\n", errstr()); WVRELEASE(x509); wvssl_free(); } void WvSSLStream::printerr(WvStringParm func) { unsigned long l = ERR_get_error(); char buf[121]; // man ERR_error_string says must be > 120. while (l) { ERR_error_string(l, buf); debug("%s error: %s\n", func, buf); l = ERR_get_error(); } } size_t WvSSLStream::uread(void *buf, size_t len) { if (!sslconnected) return 0; if (len == 0) return 0; // if SSL buffers stuff on its own, select() may not wake us up // the next time around unless we're sure there is nothing left read_pending = true; size_t total = 0; for (;;) { // handle SSL_read quirk if (read_bouncebuf.used() != 0) { // copy out cached data size_t amount = len < read_bouncebuf.used() ? len : read_bouncebuf.used(); read_bouncebuf.move(buf, amount); // locate next chunk in buffer len -= amount; total += amount; if (len == 0) { read_pending = false; break; } buf = (unsigned char *)buf + amount; // FIXME: this shouldn't be necessary, but it resolves weird // problems when the other end disconnects in the middle of // SSL negotiation, but only on emakela's machine. I don't // know why. -- apenwarr (2004/02/10) break; } // attempt to read read_bouncebuf.zap(); // force use of same position in buffer size_t avail = read_bouncebuf.free(); unsigned char *data = read_bouncebuf.alloc(avail); ERR_clear_error(); int result = SSL_read(ssl, data, avail); // debug("<< SSL_read result %s for %s bytes (wanted %s)\n", // result, avail, len); if (result <= 0) { error_t err = errno; read_bouncebuf.unalloc(avail); int sslerrcode = SSL_get_error(ssl, result); switch (sslerrcode) { case SSL_ERROR_WANT_READ: debug("<< SSL_read() needs to wait for writable.\n"); break; // wait for later case SSL_ERROR_WANT_WRITE: debug("<< SSL_read() needs to wait for readable.\n"); break; // wait for later case SSL_ERROR_NONE: break; // no error, but can't make progress case SSL_ERROR_ZERO_RETURN: debug("<< EOF: zero return\n"); // don't do this if we're returning nonzero! // (SSL has no way to do a one-way shutdown, so if SSL // detects a read problem, it's also a write problem.) if (!total) { noread(); nowrite(); } break; case SSL_ERROR_SYSCALL: if (!err) { if (result == 0) { debug("<< EOF: syscall error " "(%s/%s, %s/%s) total=%s\n", stop_read, stop_write, isok(), cloned && cloned->isok(), total); // don't do this if we're returning nonzero! // (SSL has no way to do a one-way shutdown, so // if SSL detects a read problem, it's also a // write problem.) if (!total) { noread(); nowrite(); } } } else { debug("<< SSL_read() err=%s (%s)\n", err, strerror(err)); seterr_both(err, WvString("SSL read: %s", strerror(err))); } break; default: printerr("SSL_read"); seterr("SSL read error #%s", sslerrcode); break; } read_pending = false; break; // wait for next iteration } // debug("<< read result was %s\n", result); if (result < 0) result = 0; read_bouncebuf.unalloc(avail - result); } // debug("<< read %s bytes (%s, %s)\n", // total, isok(), cloned && cloned->isok()); return total; } size_t WvSSLStream::uwrite(const void *buf, size_t len) { if (!sslconnected) { debug(">> writing, but not connected yet (%s); enqueue.\n", getwfd()); unconnected_buf.put(buf, len); return len; } if (len == 0) return 0; // debug(">> I want to write %s bytes.\n", len); size_t total = 0; // eat any data that was precached and already written if (write_eat >= len) { write_eat -= len; total = len; len = 0; } else { buf = (const unsigned char *)buf + write_eat; total = write_eat; len -= write_eat; write_eat = 0; } // FIXME: WOW!!! Ummm... hope this never spins... // for (;;) { // handle SSL_write quirk if (write_bouncebuf.used() == 0) { if (len == 0) break; // copy new data into the bounce buffer only if empty // if it were not empty, then SSL_write probably returned // SSL_ERROR_WANT_WRITE on the previous call and we // must invoke it with precisely the same arguments size_t amount = len < write_bouncebuf.free() ? len : write_bouncebuf.free(); write_bouncebuf.put(buf, amount); // note: we don't adjust the total yet... } // otherwise we use what we cached last time in bounce buffer // attempt to write size_t used = write_bouncebuf.used(); const unsigned char *data = write_bouncebuf.get(used); ERR_clear_error(); int result = SSL_write(ssl, data, used); // debug("<< SSL_write result %s for %s bytes\n", // result, used); if (result <= 0) { int sslerrcode = SSL_get_error(ssl, result); write_bouncebuf.unget(used); switch (sslerrcode) { case SSL_ERROR_WANT_READ: debug(">> SSL_write() needs to wait for readable.\n"); break; // wait for later case SSL_ERROR_WANT_WRITE: // debug(">> SSL_write() needs to wait for writable.\n"); break; // wait for later case SSL_ERROR_SYSCALL: debug(">> ERROR: SSL_write() failed on socket error.\n"); seterr(WvString("SSL write error: %s", strerror(errno))); break; // This case can cause truncated web pages... give more info case SSL_ERROR_SSL: debug(">> ERROR: SSL_write() failed on internal error.\n"); seterr(WvString("SSL write error: %s", ERR_error_string(ERR_get_error(), NULL))); break; case SSL_ERROR_NONE: break; // no error, but can't make progress case SSL_ERROR_ZERO_RETURN: debug(">> SSL_write zero return: EOF\n"); close(); // EOF break; default: printerr("SSL_write"); seterr(WvString("SSL write error #%s", sslerrcode)); break; } break; // wait for next iteration } else assert((size_t)result == used); write_bouncebuf.zap(); // force use of same position in buffer // locate next chunk to be written // note: we assume that initial contents of buf and of the // bouncebuf match since if we got SSL_ERROR_WANT_WRITE // we did not claim to actually have written the chunk // that we cached so we will have gotten it again here if (size_t(result) >= len) { // if we cached more previously than we were given, claim // we wrote what we got and remember to eat the rest later write_eat = result - len; total += len; break; } total += size_t(result); len -= size_t(result); buf = (const unsigned char *)buf + size_t(result); } //debug(">> wrote %s bytes\n", total); return total; } void WvSSLStream::close() { debug("Closing SSL connection (ok=%s,sr=%s,sw=%s,child=%s).\n", isok(), stop_read, stop_write, cloned && cloned->isok()); if (ssl) { ERR_clear_error(); SSL_shutdown(ssl); SSL_free(ssl); ssl = NULL; sslconnected = false; } WvStreamClone::close(); if (ctx) { SSL_CTX_free(ctx); ctx = NULL; } } bool WvSSLStream::isok() const { return ssl && WvStreamClone::isok(); } void WvSSLStream::noread() { // WARNING: openssl always needs two-way socket communications even for // one-way encrypted communications, so we don't pass noread/nowrite // along to the child stream. This should be mostly okay, though, // because we'll still send it close() once we have both noread() and // nowrite(). ssl_stop_read = true; if (ssl_stop_write) { WvStreamClone::nowrite(); WvStreamClone::noread(); } } void WvSSLStream::nowrite() { // WARNING: see note in noread() ssl_stop_write = true; if (ssl_stop_read) { WvStreamClone::noread(); WvStreamClone::nowrite(); } } void WvSSLStream::pre_select(SelectInfo &si) { SelectRequest oldwant = si.wants; bool oldinherit = si.inherit_request; if (!sslconnected) { si.wants = connect_wants; si.inherit_request = true; // ignore force_select() until connected } // the SSL library might be keeping its own internal buffers // or we might have left buffered data behind deliberately if (si.wants.readable && (read_pending || read_bouncebuf.used())) { // debug("pre_select: try reading again immediately.\n"); si.msec_timeout = 0; si.inherit_request = oldinherit; si.wants = oldwant; return; } WvStreamClone::pre_select(si); si.inherit_request = oldinherit; si.wants = oldwant; } bool WvSSLStream::post_select(SelectInfo &si) { SelectRequest oldwant = si.wants; bool oldinherit = si.inherit_request; if (!sslconnected) { si.wants = connect_wants; si.inherit_request = true; // ignore force_select() until connected } bool result = WvStreamClone::post_select(si); si.wants = oldwant; si.inherit_request = oldinherit; // SSL takes a few round trips to // initialize itself, and we mustn't block in the constructor, so keep // trying here... it is also turning into a rather cool place // to do the validation of the connection ;) if (!sslconnected && cloned && cloned->isok() && result) { debug("!sslconnected in post_select (r=%s/%s, w=%s/%s, t=%s)\n", cloned->isreadable(), si.wants.readable, cloned->iswritable(), si.wants.writable, si.msec_timeout); connect_wants.writable = false; // for ssl streams to work, we have to be cloning a stream that // actually uses a single, valid fd. WvFDStream *fdstream = static_cast(cloned); int fd = fdstream->getfd(); assert(fd >= 0); ERR_clear_error(); SSL_set_fd(ssl, fd); // debug("SSL connected on fd %s.\n", fd); int err; if (is_server) { // If we are a server, get ready to accept an incoming SSL // connection err = SSL_accept(ssl); } else err = SSL_connect(ssl); if (err < 0) { if (errno == EAGAIN) debug("Still waiting for SSL negotiation.\n"); else if (!errno) { printerr(is_server ? "SSL_accept" : "SSL_connect"); seterr(WvString("SSL negotiation failed (%s)!", err)); } else { printerr(is_server ? "SSL_accept" : "SSL_connect"); seterr(errno); } } else // We're connected, so let's do some checks ;) { debug("SSL connection using cipher %s.\n", SSL_get_cipher(ssl)); WvX509 *peercert = new WvX509(SSL_get_peer_certificate(ssl)); //Should we try to validate before storing, or not? if (peercert->isok() && peercert->validate()) setattr("peercert", peercert->encode(WvX509::CertPEM)); if (!!vcb) { debug("SSL Peer is: %s\n", peercert->get_subject()); if (peercert->isok() && peercert->validate() && vcb(peercert)) { setconnected(true); debug("SSL finished negotiating - certificate is valid.\n"); } else { if (!peercert->isok()) seterr("Peer cert: %s", peercert->errstr()); else seterr("Peer certificate is invalid!"); } } else { setconnected(true); debug("SSL finished negotiating " "- certificate validation disabled.\n"); } WVRELEASE(peercert); } return false; } if ((si.wants.readable || readcb) && (read_pending || read_bouncebuf.used())) result = true; return result; } void WvSSLStream::setconnected(bool conn) { sslconnected = conn; if (conn) write(unconnected_buf); } wvstreams-4.6.1/crypto/wvcrypto.cc0000644000175000001440000000043611036722347016326 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Miscellaneous cryptography primitives. */ #include "wvcrypto.h" /***** WvRandomStream *****/ WvRandomStream::WvRandomStream() : WvFile("/dev/urandom", O_RDONLY) { } wvstreams-4.6.1/crypto/wvdigest.cc0000644000175000001440000001021511124271076016255 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * MD5, SHA-1 and HMAC digest abstractions. */ #include "wvdigest.h" #include "wvserialize.h" #include #include #include #include /***** WvEVPMDDigest *****/ WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) : evpmd(_evpmd), active(false) { evpctx = new EVP_MD_CTX; _reset(); } WvEVPMDDigest::~WvEVPMDDigest() { cleanup(); delete evpctx; } bool WvEVPMDDigest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t len; while ((len = inbuf.optgettable()) != 0) { const unsigned char *data = inbuf.get(len); EVP_DigestUpdate(evpctx, data, len); } return true; } bool WvEVPMDDigest::_finish(WvBuf &outbuf) { assert(active); unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int size; // size_t is not an unsigned int on many 64 bit systems EVP_DigestFinal(evpctx, digest, & size); active = false; outbuf.put(digest, size); return true; } bool WvEVPMDDigest::_reset() { cleanup(); // the typecast is necessary for API compatibility with different // versions of openssl. None of them *actually* change the contents of // the pointer. EVP_DigestInit(evpctx, (env_md_st *)evpmd); active = true; return true; } void WvEVPMDDigest::cleanup() { if (active) { // discard digest unsigned char digest[EVP_MAX_MD_SIZE]; EVP_DigestFinal(evpctx, digest, NULL); active = false; } } size_t WvEVPMDDigest::digestsize() const { return EVP_MD_size((env_md_st *)evpmd); } /***** WvMD5Digest *****/ WvMD5Digest::WvMD5Digest() : WvEVPMDDigest(EVP_md5()) { } /***** WvSHA1Digest *****/ WvSHA1Digest::WvSHA1Digest() : WvEVPMDDigest(EVP_sha1()) { } /***** WvHMACDigest *****/ WvHMACDigest::WvHMACDigest(WvEVPMDDigest *_digest, const void *_key, size_t _keysize) : digest(_digest), keysize(_keysize), active(false) { key = new unsigned char[keysize]; memcpy(key, _key, keysize); hmacctx = new HMAC_CTX; _reset(); } WvHMACDigest::~WvHMACDigest() { cleanup(); delete hmacctx; deletev key; delete digest; } bool WvHMACDigest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t len; while ((len = inbuf.optgettable()) != 0) { const unsigned char *data = inbuf.get(len); HMAC_Update(hmacctx, data, len); } return true; } bool WvHMACDigest::_finish(WvBuf &outbuf) { assert(active); unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int size; HMAC_Final(hmacctx, digest, & size); active = false; outbuf.put(digest, size); return true; } bool WvHMACDigest::_reset() { cleanup(); HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd()); active = true; return true; } void WvHMACDigest::cleanup() { if (active) { // discard digest unsigned char digest[EVP_MAX_MD_SIZE]; HMAC_Final(hmacctx, digest, NULL); active = false; } } size_t WvHMACDigest::digestsize() const { return digest->digestsize(); } WvCrc32Digest::WvCrc32Digest() { _reset(); } bool WvCrc32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t len; while ((len = inbuf.optgettable()) != 0) crc = crc32(crc, inbuf.get(len), len); return true; } bool WvCrc32Digest::_finish(WvBuf &outbuf) { wv_serialize(outbuf, crc); return true; } bool WvCrc32Digest::_reset() { crc = crc32(0, NULL, 0); return true; } size_t WvCrc32Digest::digestsize() const { return sizeof(crc); } WvAdler32Digest::WvAdler32Digest() { _reset(); } bool WvAdler32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t len; while ((len = inbuf.optgettable()) != 0) crc = adler32(crc, inbuf.get(len), len); return true; } bool WvAdler32Digest::_finish(WvBuf &outbuf) { wv_serialize(outbuf, crc); return true; } bool WvAdler32Digest::_reset() { crc = adler32(0, NULL, 0); return true; } size_t WvAdler32Digest::digestsize() const { return sizeof(crc); } wvstreams-4.6.1/crypto/wvtripledes.cc0000644000175000001440000000723111036722347017001 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * TripleDES cryptography abstractions. */ #include "wvtripledes.h" #include #include /***** WvTripleDESEncoder ****/ WvTripleDESEncoder::WvTripleDESEncoder(Mode _mode, const void *_key1, const void *_key2, const void *_key3) : mode(_mode) { setkey(_key1, _key2, _key3); } // WvTripleDESEncoder::~WvTripleDESEncoder() // { // delete[] key; // delete deskey1; // delete deskey2; // delete deskey3; // } bool WvTripleDESEncoder::_reset() { memset(ivec, 0, sizeof(ivec)); ivecoff = 0; return true; } void WvTripleDESEncoder::setkey(const void *_key1, const void *_key2, const void *_key3) { memcpy(key, _key1, DES_KEY_SZ); DES_set_key(&key, &deskey1); memcpy(key, _key2, DES_KEY_SZ); DES_set_key(&key, &deskey2); memcpy(key, _key3, DES_KEY_SZ); DES_set_key(&key, &deskey3); memset(ivec, 0, sizeof(ivec)); ivecoff = 0; } void WvTripleDESEncoder::setiv(const void *_iv) { memcpy(ivec, _iv, sizeof(ivec)); ivecoff = 0; } bool WvTripleDESEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { size_t len = in.used(); bool success = true; switch (mode) { case ECBEncrypt: case ECBDecrypt: case CBCEncrypt: // The caller should ensure the padding is correct or case CBCDecrypt: // we do it for them, in probably the wrong way. { size_t remainder = len & 7; // conviently this is the same as len % 8 len -= remainder; if (remainder != 0 && flush) { if (mode == ECBEncrypt || mode == CBCEncrypt) { // if flushing on encryption, add some randomized padding size_t padlen = 8 - remainder; unsigned char *pad = in.alloc(padlen); RAND_pseudo_bytes(pad, padlen); len += 8; } else // nothing we can do here, flushing does not make sense! success = false; } } default: break; } if (len == 0) return success; const unsigned char *data = in.get(len); unsigned char *crypt = out.alloc(len); switch (mode) { case ECBEncrypt: case ECBDecrypt: // ECB works 64bits at a time while (len >= 8) { #if OPENSSL_VERSION_NUMBER >= 0x0090705fL \ && OPENSSL_VERSION_NUMBER < 0x0090800fL DES_ecb3_encrypt(data, crypt, &deskey1, &deskey2, &deskey3, mode == ECBEncrypt ? DES_ENCRYPT : DES_DECRYPT); #else DES_ecb3_encrypt(reinterpret_cast(&data), reinterpret_cast(&crypt), &deskey1, &deskey2, &deskey3, mode == ECBEncrypt ? DES_ENCRYPT : DES_DECRYPT); #endif len -= 8; data += 8; crypt += 8; } break; case CFBEncrypt: case CFBDecrypt: // CFB simulates a stream DES_ede3_cfb64_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3, &ivec, &ivecoff, mode == CFBEncrypt ? DES_ENCRYPT : DES_DECRYPT); break; case CBCEncrypt: DES_ede3_cbc_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3, &ivec, DES_ENCRYPT); break; case CBCDecrypt: DES_ede3_cbc_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3, &ivec, DES_DECRYPT); break; } return success; } /***** WvTripleDESStream *****/ WvTripleDESStream::WvTripleDESStream(WvStream *_cloned, const void *_key1, const void *_key2, const void *_key3, WvTripleDESEncoder::Mode readmode, WvTripleDESEncoder::Mode writemode) : WvEncoderStream(_cloned) { readchain.append(new WvTripleDESEncoder(readmode, _key1, _key2, _key3), true); writechain.append(new WvTripleDESEncoder(writemode, _key1, _key2, _key3), true); } wvstreams-4.6.1/crypto/wvx509.cc0000644000175000001440000011114211100156525015477 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2005 Net Integration Technologies, Inc. * * X.509 certificate management classes. */ #include "wvx509.h" #include "wvcrl.h" #include "wvsslhacks.h" #include "wvcrypto.h" #include "wvstringlist.h" #include "wvbase64.h" #include "wvstrutils.h" #include "wvautoconf.h" #include #include #include #include #include // enable this to add some extra debugging trace messages (this can be VERY // verbose) #if 0 # define TRACE(x, y...) debug(x, ## y); #else #ifndef _MSC_VER # define TRACE(x, y...) #else # define TRACE #endif #endif // helper method to let us return and warn gracefully when getting/setting an // element in a null certificate static const char * warning_str_set = "Tried to set %s, but certificate not ok.\n"; static const char * warning_str_get = "Tried to get %s, but certificate not ok.\n"; #define CHECK_CERT_EXISTS_SET(x) \ if (!cert) { \ debug(WvLog::Warning, warning_str_set, x); \ return; \ } #define CHECK_CERT_EXISTS_GET(x, y) \ if (!cert) { \ debug(WvLog::Warning, warning_str_get, x); \ return y; \ } UUID_MAP_BEGIN(WvX509) UUID_MAP_ENTRY(IObject) UUID_MAP_END static int ssl_init_count = 0; #if !HAVE_OPENSSL_POLICY_MAPPING // HACK: old versions of OpenSSL can't handle ERR_free_strings() being called // more than once in the same process; the next wvssl_init won't work. So // let's make sure to make a global variable that holds the refcount at 1 // even when all the objects go away, then clean it up at exit. class WvSSL_Stupid_Refcount { public: WvSSL_Stupid_Refcount() { wvssl_init(); } ~WvSSL_Stupid_Refcount() { wvssl_free(); } }; WvSSL_Stupid_Refcount wvssl_stupid_refcount; #endif // !HAVE_OPENSSL_POLICY_MAPPING void wvssl_init() { if (!ssl_init_count) { SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); } ssl_init_count++; } void wvssl_free() { assert(ssl_init_count >= 1); if (ssl_init_count >= 1) ssl_init_count--; if (!ssl_init_count) { ERR_free_strings(); EVP_cleanup(); } } WvString wvssl_errstr() { char buf[256]; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); buf[sizeof(buf)-1] = 0; return buf; } WvX509::WvX509(X509 *_cert) : debug("X509", WvLog::Debug5) { wvssl_init(); cert = _cert; } WvX509::WvX509() : debug("X509", WvLog::Debug5) { wvssl_init(); cert = NULL; } WvX509::WvX509(const WvX509 &x509) : debug("X509", WvLog::Debug5) { wvssl_init(); if (x509.cert) cert = X509_dup(x509.cert); else cert = NULL; } WvX509::~WvX509() { TRACE("Deleting.\n"); if (cert) X509_free(cert); wvssl_free(); } // The people who designed this garbage should be shot! // Support old versions of openssl... #ifndef NID_domainComponent #define NID_domainComponent 391 #endif #ifndef NID_Domain #define NID_Domain 392 #endif // returns some approximation of the server's fqdn, or an empty string. static WvString set_name_entry(X509_NAME *name, WvStringParm dn) { WvString fqdn(""), force_fqdn(""); X509_NAME_ENTRY *ne = NULL; int count = 0, nid; WvStringList l; l.split(dn, ","); // dn is of the form: c=ca,o=foo organization,dc=foo,dc=com // (ie. name=value pairs separated by commas) WvStringList::Iter i(l); for (i.rewind(); i.next(); ) { WvString s(*i), sid; char *cptr, *value; cptr = s.edit(); value = strchr(cptr, '='); if (value) *value++ = 0; else value = (char*)"NULL"; sid = strlwr(trim_string(cptr)); if (sid == "c") nid = NID_countryName; else if (sid == "st") nid = NID_stateOrProvinceName; else if (sid == "l") nid = NID_localityName; else if (sid == "o") nid = NID_organizationName; else if (sid == "ou") nid = NID_organizationalUnitName; else if (sid == "cn") { nid = NID_commonName; force_fqdn = value; } else if (sid == "dc") { nid = NID_domainComponent; if (!!fqdn) fqdn.append("."); fqdn.append(value); } else if (sid == "domain") { nid = NID_Domain; force_fqdn = value; } else if (sid == "email") nid = NID_pkcs9_emailAddress; else nid = NID_domainComponent; // Sometimes we just want to parse dn into fqdn. if (name == NULL) continue; if (!ne) ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, V_ASN1_APP_CHOOSE, (unsigned char *)value, -1); else X509_NAME_ENTRY_create_by_NID(&ne, nid, V_ASN1_APP_CHOOSE, (unsigned char *)value, -1); if (!ne) continue; X509_NAME_add_entry(name, ne, count++, 0); } X509_NAME_ENTRY_free(ne); if (!!force_fqdn) return force_fqdn; return fqdn; } WvRSAKey *WvX509::get_rsa_pub() const { EVP_PKEY *pkcert = X509_get_pubkey(cert); RSA *certrsa = EVP_PKEY_get1_RSA(pkcert); EVP_PKEY_free(pkcert); return new WvRSAKey(certrsa, false); } WvString WvX509::certreq(WvStringParm subject, const WvRSAKey &rsa) { WvLog debug("X509::certreq", WvLog::Debug5); EVP_PKEY *pk = NULL; X509_NAME *name = NULL; X509_REQ *certreq = NULL; // double check RSA key if (rsa.isok()) debug("RSA Key is fine.\n"); else { debug(WvLog::Warning, "RSA Key is bad"); return WvString::null; } if ((pk=EVP_PKEY_new()) == NULL) { debug(WvLog::Warning, "Error creating key handler for new certificate"); return WvString::null; } if ((certreq=X509_REQ_new()) == NULL) { debug(WvLog::Warning, "Error creating new PKCS#10 object"); EVP_PKEY_free(pk); return WvString::null; } if (!EVP_PKEY_set1_RSA(pk, rsa.rsa)) { debug(WvLog::Warning, "Error adding RSA keys to certificate"); X509_REQ_free(certreq); EVP_PKEY_free(pk); return WvString::null; } X509_REQ_set_version(certreq, 0); /* version 1 */ X509_REQ_set_pubkey(certreq, pk); name = X509_REQ_get_subject_name(certreq); debug("Creating Certificate request for %s\n", subject); set_name_entry(name, subject); X509_REQ_set_subject_name(certreq, name); char *sub_name = X509_NAME_oneline(X509_REQ_get_subject_name(certreq), 0, 0); debug("SubjectDN: %s\n", sub_name); OPENSSL_free(sub_name); if (!X509_REQ_sign(certreq, pk, EVP_sha1())) { debug(WvLog::Warning, "Could not self sign the request"); X509_REQ_free(certreq); EVP_PKEY_free(pk); return WvString::null; } int verify_result = X509_REQ_verify(certreq, pk); if (verify_result == 0) { debug(WvLog::Warning, "Self signed request failed"); X509_REQ_free(certreq); EVP_PKEY_free(pk); return WvString::null; } else { debug("Self Signed Certificate Request verifies OK!\n"); } // Horribly involuted hack to get around the fact that the // OpenSSL people are too braindead to have a PEM_write function // that returns a char * WvDynBuf retval; BIO *bufbio = BIO_new(BIO_s_mem()); BUF_MEM *bm; PEM_write_bio_X509_REQ(bufbio, certreq); BIO_get_mem_ptr(bufbio, &bm); retval.put(bm->data, bm->length); X509_REQ_free(certreq); EVP_PKEY_free(pk); BIO_free(bufbio); return retval.getstr(); } bool WvX509::validate(WvX509 *cacert) const { if (cert == NULL) { debug(WvLog::Warning, "Tried to validate certificate against CA, but " "certificate is blank!\n"); return false; } bool retval = true; // Check and make sure that the certificate is still valid if (X509_cmp_current_time(X509_get_notAfter(cert)) < 0) { debug("Certificate has expired.\n"); retval = false; } if (X509_cmp_current_time(X509_get_notBefore(cert)) > 0) { debug("Certificate is not yet valid.\n"); retval = false; } if (cacert) { retval &= signedbyca(*cacert); retval &= issuedbyca(*cacert); } return retval; } bool WvX509::signedbyca(WvX509 &cacert) const { if (!cert || !cacert.cert) { debug(WvLog::Warning, "Tried to determine if certificate was signed " "by CA, but either client or CA certificate (or both) are " "blank.\n"); return false; } EVP_PKEY *pkey = X509_get_pubkey(cacert.cert); int result = X509_verify(cert, pkey); EVP_PKEY_free(pkey); if (result < 0) { debug("Can't determine if we were signed by CA %s: %s\n", cacert.get_subject(), wvssl_errstr()); return false; } bool issigned = (result > 0); debug("Certificate was%s signed by CA %s.\n", issigned ? "" : " NOT", cacert.get_subject()); return issigned; } bool WvX509::issuedbyca(WvX509 &cacert) const { if (!cert || !cacert.cert) { debug(WvLog::Warning, "Tried to determine if certificate was issued " "by CA, but either client or CA certificate (or both) are " "blank.\n"); return false; } int ret = X509_check_issued(cacert.cert, cert); debug("issuedbyca: %s==X509_V_OK(%s)\n", ret, X509_V_OK); if (ret != X509_V_OK) return false; return true; } WvString WvX509::encode(const DumpMode mode) const { WvDynBuf retval; encode(mode, retval); return retval.getstr(); } void WvX509::encode(const DumpMode mode, WvBuf &buf) const { if (mode == CertFileDER || mode == CertFilePEM) return; // file modes are no ops with encode if (!cert) { debug(WvLog::Warning, "Tried to encode certificate, but certificate " "is blank!\n"); return; } debug("Encoding X509 certificate.\n"); if (mode == CertHex) { size_t size; unsigned char *keybuf, *iend; WvString enccert; size = i2d_X509(cert, NULL); iend = keybuf = new unsigned char[size]; i2d_X509(cert, &iend); enccert.setsize(size * 2 +1); ::hexify(enccert.edit(), keybuf, size); deletev keybuf; buf.putstr(enccert); } else { BIO *bufbio = BIO_new(BIO_s_mem()); BUF_MEM *bm; if (mode == CertPEM) PEM_write_bio_X509(bufbio, cert); else if (mode == CertDER) i2d_X509_bio(bufbio, cert); else debug(WvLog::Warning, "Tried to encode certificate with unknown " "mode!\n"); BIO_get_mem_ptr(bufbio, &bm); buf.put(bm->data, bm->length); BIO_free(bufbio); } } void WvX509::decode(const DumpMode mode, WvStringParm str) { if (cert) { debug("Replacing an already existant X509 certificate.\n"); X509_free(cert); cert = NULL; } if (mode == CertFileDER) { BIO *bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, str.cstr()) <= 0) { debug(WvLog::Warning, "Open '%s': %s\n", str, wvssl_errstr()); BIO_free(bio); return; } if (!(cert = d2i_X509_bio(bio, NULL))) debug(WvLog::Warning, "Import DER from '%s': %s\n", str, wvssl_errstr()); BIO_free(bio); return; } else if (mode == CertFilePEM) { FILE *fp = fopen(str, "rb"); if (!fp) { int errnum = errno; debug("Open '%s': %s\n", str, strerror(errnum)); return; } if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) debug(WvLog::Warning, "Import PEM from '%s': %s\n", str, wvssl_errstr()); fclose(fp); return; } else if (mode == CertHex) { int hexbytes = str.len(); int bufsize = hexbytes/2; unsigned char *certbuf = new unsigned char[bufsize]; unsigned char *cp = certbuf; X509 *tmpcert; ::unhexify(certbuf, str); tmpcert = cert = X509_new(); cert = wv_d2i_X509(&tmpcert, &cp, bufsize); delete[] certbuf; return; } // we use the buffer decode functions for everything else WvDynBuf buf; buf.putstr(str); decode(mode, buf); } void WvX509::decode(const DumpMode mode, WvBuf &encoded) { if (cert) { debug("Replacing an already existant X509 certificate.\n"); X509_free(cert); cert = NULL; } if (mode == CertHex || mode == CertFileDER || mode == CertFilePEM) decode(mode, encoded.getstr()); else { BIO *membuf = BIO_new(BIO_s_mem()); BIO_write(membuf, encoded.get(encoded.used()), encoded.used()); if (mode == CertPEM) cert = PEM_read_bio_X509(membuf, NULL, NULL, NULL); else if (mode == CertDER) cert = d2i_X509_bio(membuf, NULL); else debug(WvLog::Warning, "Tried to decode certificate with unknown " "mode!\n"); BIO_free_all(membuf); } } WvString WvX509::get_issuer() const { CHECK_CERT_EXISTS_GET("issuer", WvString::null); char *name = X509_NAME_oneline(X509_get_issuer_name(cert),0,0); WvString retval(name); OPENSSL_free(name); return retval; } void WvX509::set_issuer(WvStringParm issuer) { CHECK_CERT_EXISTS_SET("issuer"); X509_NAME *name = X509_get_issuer_name(cert); set_name_entry(name, issuer); X509_set_issuer_name(cert, name); } void WvX509::set_issuer(const WvX509 &cacert) { CHECK_CERT_EXISTS_SET("issuer"); X509_NAME *casubj = X509_get_subject_name(cacert.cert); X509_set_issuer_name(cert, casubj); } WvString WvX509::get_subject() const { CHECK_CERT_EXISTS_GET("subject", WvString::null); char *name = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); WvString retval(name); OPENSSL_free(name); return retval; } void WvX509::set_subject(WvStringParm subject) { CHECK_CERT_EXISTS_SET("subject"); X509_NAME *name = X509_get_subject_name(cert); set_name_entry(name, subject); X509_set_subject_name(cert, name); } void WvX509::set_subject(X509_NAME *name) { CHECK_CERT_EXISTS_SET("subject"); X509_set_subject_name(cert, name); } void WvX509::set_pubkey(WvRSAKey &_rsa) { CHECK_CERT_EXISTS_SET("pubkey"); EVP_PKEY *pk = EVP_PKEY_new(); assert(pk); // Assign RSA Key from WvRSAKey into stupid package that OpenSSL needs if (!EVP_PKEY_set1_RSA(pk, _rsa.rsa)) { debug("Error adding RSA keys to certificate.\n"); return; } X509_set_pubkey(cert, pk); EVP_PKEY_free(pk); } void WvX509::set_nsserver(WvStringParm servername) { CHECK_CERT_EXISTS_SET("nsserver"); WvString fqdn; // FQDN cannot have a = in it, therefore it // must be a distinguished name :) if (strchr(servername, '=')) fqdn = set_name_entry(NULL, servername); else fqdn = servername; if (!fqdn) fqdn = "null.noname.null"; debug("Setting Netscape SSL server name extension to '%s'.\n", fqdn); // Add in the netscape-specific server extension set_extension(NID_netscape_cert_type, "server"); set_extension(NID_netscape_ssl_server_name, fqdn); } WvString WvX509::get_nsserver() const { return get_extension(NID_netscape_ssl_server_name); } WvString WvX509::get_serial(bool hex) const { CHECK_CERT_EXISTS_GET("serial", WvString::null); BIGNUM *bn = BN_new(); bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), bn); char * c; if (hex) c = BN_bn2hex(bn); else c = BN_bn2dec(bn); WvString ret("%s", c); OPENSSL_free(c); BN_free(bn); return ret; } void WvX509::set_version() { CHECK_CERT_EXISTS_SET("version"); X509_set_version(cert, 0x2); } void WvX509::set_serial(long serial) { CHECK_CERT_EXISTS_SET("serial"); ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); } WvString WvX509::get_crl_dp() const { return get_extension(NID_crl_distribution_points); } void WvX509::set_lifetime(long seconds) { CHECK_CERT_EXISTS_SET("lifetime"); // Set the NotBefore time to now. X509_gmtime_adj(X509_get_notBefore(cert), 0); // Now + 10 years... should be shorter, but since we don't currently // have a set of routines to refresh the certificates, make it // REALLY long. X509_gmtime_adj(X509_get_notAfter(cert), seconds); } void WvX509::set_key_usage(WvStringParm values) { set_extension(NID_key_usage, values); } WvString WvX509::get_key_usage() const { return get_extension(NID_key_usage); } void WvX509::set_ext_key_usage(WvStringParm values) { set_extension(NID_ext_key_usage, values); } WvString WvX509::get_ext_key_usage() const { return get_extension(NID_ext_key_usage); } WvString WvX509::get_altsubject() const { return get_extension(NID_subject_alt_name); } bool WvX509::get_basic_constraints(bool &ca, int &pathlen) const { CHECK_CERT_EXISTS_GET("basic constraints", false); BASIC_CONSTRAINTS *constraints = NULL; int i; constraints = static_cast (X509_get_ext_d2i(cert, NID_basic_constraints, &i, NULL)); if (constraints) { ca = constraints->ca; if (constraints->pathlen) { if ((constraints->pathlen->type == V_ASN1_NEG_INTEGER) || !ca) { debug("Path length type not valid when getting basic " "constraints.\n"); BASIC_CONSTRAINTS_free(constraints); pathlen = 0; return false; } pathlen = ASN1_INTEGER_get(constraints->pathlen); } else pathlen = (-1); BASIC_CONSTRAINTS_free(constraints); return true; } debug("Basic constraints extension not present.\n"); return false; } void WvX509::set_basic_constraints(bool ca, int pathlen) { CHECK_CERT_EXISTS_SET("basic constraints"); BASIC_CONSTRAINTS *constraints = BASIC_CONSTRAINTS_new(); constraints->ca = static_cast(ca); if (pathlen != (-1)) { ASN1_INTEGER *i = ASN1_INTEGER_new(); ASN1_INTEGER_set(i, pathlen); constraints->pathlen = i; } X509_EXTENSION *ex = X509V3_EXT_i2d(NID_basic_constraints, 0, constraints); while (int idx = X509_get_ext_by_NID(cert, NID_basic_constraints, 0) >= 0) { debug("Found extension at idx %s\n", idx); X509_EXTENSION *tmpex = X509_delete_ext(cert, idx); X509_EXTENSION_free(tmpex); } X509_add_ext(cert, ex, NID_basic_constraints); X509_EXTENSION_free(ex); BASIC_CONSTRAINTS_free(constraints); } /* * These functions are optional to the API. If OpenSSL doesn't support them, * we simply won't include them here, and apps that need them won't compile. */ #ifdef HAVE_OPENSSL_POLICY_MAPPING bool WvX509::get_policy_constraints(int &require_explicit_policy, int &inhibit_policy_mapping) const { CHECK_CERT_EXISTS_GET("policy constraints", false); POLICY_CONSTRAINTS *constraints = NULL; int i; constraints = static_cast(X509_get_ext_d2i( cert, NID_policy_constraints, &i, NULL)); if (constraints) { if (constraints->requireExplicitPolicy) require_explicit_policy = ASN1_INTEGER_get( constraints->requireExplicitPolicy); else require_explicit_policy = (-1); if (constraints->inhibitPolicyMapping) inhibit_policy_mapping = ASN1_INTEGER_get( constraints->inhibitPolicyMapping); else inhibit_policy_mapping = (-1); POLICY_CONSTRAINTS_free(constraints); return true; } return false; } void WvX509::set_policy_constraints(int require_explicit_policy, int inhibit_policy_mapping) { CHECK_CERT_EXISTS_SET("policy constraints"); POLICY_CONSTRAINTS *constraints = POLICY_CONSTRAINTS_new(); ASN1_INTEGER *i = ASN1_INTEGER_new(); ASN1_INTEGER_set(i, require_explicit_policy); constraints->requireExplicitPolicy = i; i = ASN1_INTEGER_new(); ASN1_INTEGER_set(i, inhibit_policy_mapping); constraints->inhibitPolicyMapping = i; X509_EXTENSION *ex = X509V3_EXT_i2d(NID_policy_constraints, 0, constraints); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); POLICY_CONSTRAINTS_free(constraints); } bool WvX509::get_policy_mapping(PolicyMapList &list) const { CHECK_CERT_EXISTS_GET("policy mapping", false); POLICY_MAPPINGS *mappings = NULL; POLICY_MAPPING *map = NULL; int i; mappings = static_cast(X509_get_ext_d2i( cert, NID_policy_mappings, &i, NULL)); if (!mappings) return false; const int POLICYID_MAXLEN = 80; char tmp1[80]; char tmp2[80]; for(int j = 0; j < sk_POLICY_MAPPING_num(mappings); j++) { map = sk_POLICY_MAPPING_value(mappings, j); OBJ_obj2txt(tmp1, POLICYID_MAXLEN, map->issuerDomainPolicy, true); OBJ_obj2txt(tmp2, POLICYID_MAXLEN, map->subjectDomainPolicy, true); list.append(new PolicyMap(tmp1, tmp2), true); } sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); return true; } void WvX509::set_policy_mapping(PolicyMapList &list) { CHECK_CERT_EXISTS_SET("policy mapping"); POLICY_MAPPINGS *maps = sk_POLICY_MAPPING_new_null(); PolicyMapList::Iter i(list); for (i.rewind(); i.next();) { POLICY_MAPPING *map = POLICY_MAPPING_new(); map->issuerDomainPolicy = OBJ_txt2obj(i().issuer_domain.cstr(), 0); map->subjectDomainPolicy = OBJ_txt2obj(i().subject_domain.cstr(), 0); sk_POLICY_MAPPING_push(maps, map); printf("Push!\n"); } X509_EXTENSION *ex = X509V3_EXT_i2d(NID_policy_mappings, 0, maps); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); } #endif // HAVE_OPENSSL_POLICY_MAPPING static void add_aia(WvStringParm type, WvString identifier, AUTHORITY_INFO_ACCESS *ainfo) { ACCESS_DESCRIPTION *acc = ACCESS_DESCRIPTION_new(); sk_ACCESS_DESCRIPTION_push(ainfo, acc); acc->method = OBJ_txt2obj(type.cstr(), 0); acc->location->type = GEN_URI; acc->location->d.ia5 = M_ASN1_IA5STRING_new(); unsigned char *cident = reinterpret_cast(identifier.edit()); ASN1_STRING_set(acc->location->d.ia5, cident, identifier.len()); } void WvX509::set_aia(WvStringList &ca_urls, WvStringList &responders) { CHECK_CERT_EXISTS_SET("aia"); AUTHORITY_INFO_ACCESS *ainfo = sk_ACCESS_DESCRIPTION_new_null(); WvStringList::Iter i(ca_urls); for (i.rewind(); i.next();) add_aia("caIssuers", i(), ainfo); WvStringList::Iter j(responders); for (j.rewind(); j.next();) add_aia("OCSP", j(), ainfo); X509_EXTENSION *ex = X509V3_EXT_i2d(NID_info_access, 0, ainfo); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); } WvString WvX509::get_aia() const { return get_extension(NID_info_access); } static void parse_stack(WvStringParm ext, WvStringList &list, WvStringParm prefix) { WvStringList stack; stack.split(ext, ";\n"); WvStringList::Iter i(stack); for (i.rewind();i.next();) { WvString stack_entry(*i); if (strstr(stack_entry, prefix)) { WvString uri(stack_entry.edit() + prefix.len()); list.append(uri); } } } void WvX509::get_ocsp(WvStringList &responders) const { parse_stack(get_aia(), responders, "OCSP - URI:"); } void WvX509::get_ca_urls(WvStringList &urls) const { parse_stack(get_aia(), urls, "CA Issuers - URI:"); } void WvX509::get_crl_urls(WvStringList &urls) const { parse_stack(get_crl_dp(), urls, "URI:"); } void WvX509::set_crl_urls(WvStringList &urls) { CHECK_CERT_EXISTS_SET("CRL urls"); STACK_OF(DIST_POINT) *crldp = sk_DIST_POINT_new_null(); WvStringList::Iter i(urls); for (i.rewind(); i.next();) { DIST_POINT *point = DIST_POINT_new(); sk_DIST_POINT_push(crldp, point); GENERAL_NAMES *uris = GENERAL_NAMES_new(); GENERAL_NAME *uri = GENERAL_NAME_new(); uri->type = GEN_URI; uri->d.ia5 = M_ASN1_IA5STRING_new(); unsigned char *cident = reinterpret_cast(i().edit()); ASN1_STRING_set(uri->d.ia5, cident, i().len()); sk_GENERAL_NAME_push(uris, uri); point->distpoint = DIST_POINT_NAME_new(); point->distpoint->name.fullname = uris; point->distpoint->type = 0; } X509_EXTENSION *ex = X509V3_EXT_i2d(NID_crl_distribution_points, 0, crldp); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); } bool WvX509::get_policies(WvStringList &policy_oids) const { CHECK_CERT_EXISTS_GET("policies", false); int critical; CERTIFICATEPOLICIES * policies = static_cast( X509_get_ext_d2i(cert, NID_certificate_policies, &critical, NULL)); if (policies) { for (int i = 0; i < sk_POLICYINFO_num(policies); i++) { POLICYINFO * policy = sk_POLICYINFO_value(policies, i); const int POLICYID_MAXLEN = 80; char policyid[POLICYID_MAXLEN]; OBJ_obj2txt(policyid, POLICYID_MAXLEN, policy->policyid, true); // don't substitute human-readable names policy_oids.append(policyid); } sk_POLICYINFO_pop_free(policies, POLICYINFO_free); return true; } return false; } void WvX509::set_policies(WvStringList &policy_oids) { CHECK_CERT_EXISTS_SET("policies"); STACK_OF(POLICYINFO) *sk_pinfo = sk_POLICYINFO_new_null(); WvStringList::Iter i(policy_oids); for (i.rewind(); i.next();) { ASN1_OBJECT *pobj = OBJ_txt2obj(i(), 0); POLICYINFO *pol = POLICYINFO_new(); pol->policyid = pobj; sk_POLICYINFO_push(sk_pinfo, pol); } #if 0 // this code would let you set URL information to a policy // qualifier POLICYQUALINFO *qual = NULL; WvString url(_url); if (!!url) { pol->qualifiers = sk_POLICYQUALINFO_new_null(); qual = POLICYQUALINFO_new(); qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); qual->d.cpsouri = M_ASN1_IA5STRING_new(); ASN1_STRING_set(qual->d.cpsuri, url.edit(), url.len()); sk_POLICYQUALINFO_push(pol->qualifiers, qual); } #endif X509_EXTENSION *ex = X509V3_EXT_i2d(NID_certificate_policies, 0, sk_pinfo); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); sk_POLICYINFO_pop_free(sk_pinfo, POLICYINFO_free); } WvString WvX509::get_extension(int nid) const { CHECK_CERT_EXISTS_GET("extension", WvString::null); WvString retval = WvString::null; int index = X509_get_ext_by_NID(cert, nid, -1); if (index >= 0) { X509_EXTENSION *ext = X509_get_ext(cert, index); if (ext) { X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); if (!method) { WvDynBuf buf; buf.put(ext->value->data, ext->value->length); retval = buf.getstr(); } else { void *ext_data = NULL; // we NEED to use a temporary pointer for ext_value_data, // as openssl's ASN1_item_d2i will muck around with it, // even though it's const (at least as of version 0.9.8e). // gah. #if OPENSSL_VERSION_NUMBER >= 0x0090800fL const unsigned char * ext_value_data = ext->value->data; #else unsigned char *ext_value_data = ext->value->data; #endif if (method->it) { ext_data = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length, ASN1_ITEM_ptr(method->it)); TRACE("Applied generic conversion!\n"); } else { ext_data = method->d2i(NULL, &ext_value_data, ext->value->length); TRACE("Applied method specific conversion!\n"); } if (method->i2s) { TRACE("String Extension!\n"); char *s = method->i2s(method, ext_data); retval = s; OPENSSL_free(s); } else if (method->i2v) { TRACE("Stack Extension!\n"); CONF_VALUE *val = NULL; STACK_OF(CONF_VALUE) *svals = NULL; svals = method->i2v(method, ext_data, NULL); if (!sk_CONF_VALUE_num(svals)) retval = "EMPTY"; else { WvStringList list; for(int i = 0; i < sk_CONF_VALUE_num(svals); i++) { val = sk_CONF_VALUE_value(svals, i); if (!val->name) list.append(WvString(val->value)); else if (!val->value) list.append(WvString(val->name)); else { WvString pair("%s:%s", val->name, val->value); list.append(pair); } } retval = list.join(";\n"); } sk_CONF_VALUE_pop_free(svals, X509V3_conf_free); } else if (method->i2r) { TRACE("Raw Extension!\n"); WvDynBuf retvalbuf; BIO *bufbio = BIO_new(BIO_s_mem()); BUF_MEM *bm; method->i2r(method, ext_data, bufbio, 0); BIO_get_mem_ptr(bufbio, &bm); retvalbuf.put(bm->data, bm->length); BIO_free(bufbio); retval = retvalbuf.getstr(); } if (method->it) ASN1_item_free((ASN1_VALUE *)ext_data, ASN1_ITEM_ptr(method->it)); else method->ext_free(ext_data); } } } else { TRACE("Extension not present!\n"); } if (!!retval) TRACE("Returning: %s\n", retval); return retval; } void WvX509::set_extension(int nid, WvStringParm _values) { CHECK_CERT_EXISTS_SET("extension"); // first we check to see if the extension already exists, if so we need to // kill it int index = X509_get_ext_by_NID(cert, nid, -1); if (index >= 0) { X509_EXTENSION *ex = X509_delete_ext(cert, index); X509_EXTENSION_free(ex); } // now set the extension WvString values(_values); X509_EXTENSION *ex = NULL; ex = X509V3_EXT_conf_nid(NULL, NULL, nid, values.edit()); X509_add_ext(cert, ex, -1); X509_EXTENSION_free(ex); } bool WvX509::isok() const { return cert; } bool WvX509::operator! () const { return !isok(); } WvString WvX509::errstr() const { if (!cert) return "No certificate."; return WvString::empty; } bool WvX509::verify(WvStringParm original, WvStringParm signature) const { WvDynBuf buf; buf.putstr(original); return verify(buf, signature); } bool WvX509::verify(WvBuf &original, WvStringParm signature) const { unsigned char sig_buf[4096]; size_t sig_size = sizeof(sig_buf); WvBase64Decoder().flushstrmem(signature, sig_buf, &sig_size, true); EVP_PKEY *pk = X509_get_pubkey(cert); if (!pk) return false; /* Verify the signature */ EVP_MD_CTX sig_ctx; EVP_VerifyInit(&sig_ctx, EVP_sha1()); EVP_VerifyUpdate(&sig_ctx, original.peek(0, original.used()), original.used()); int sig_err = EVP_VerifyFinal(&sig_ctx, sig_buf, sig_size, pk); EVP_PKEY_free(pk); EVP_MD_CTX_cleanup(&sig_ctx); // Again, not my fault... if (sig_err != 1) { debug("Verify failed!\n"); return false; } else return true; } static time_t ASN1_TIME_to_time_t(ASN1_TIME *t) { struct tm newtime; char *p = NULL; char d[18]; memset(&d,'\0',sizeof(d)); memset(&newtime,'\0',sizeof newtime); if (t->type == V_ASN1_GENERALIZEDTIME) { // For time values >= 2050, OpenSSL uses // ASN1_GENERALIZEDTIME - which we'll worry about // later. return 0; } p = (char *)t->data; sscanf(p,"%2s%2s%2s%2s%2s%2sZ", d, &d[3], &d[6], &d[9], &d[12], &d[15]); int year = strtol(d, (char **)NULL, 10); if (year < 49) year += 100; else year += 50; newtime.tm_year = year; newtime.tm_mon = strtol(&d[3], (char **)NULL, 10) - 1; newtime.tm_mday = strtol(&d[6], (char **)NULL, 10); newtime.tm_hour = strtol(&d[9], (char **)NULL, 10); newtime.tm_min = strtol(&d[12], (char **)NULL, 10); newtime.tm_sec = strtol(&d[15], (char **)NULL, 10); return mktime(&newtime); } time_t WvX509::get_notvalid_before() const { CHECK_CERT_EXISTS_GET("not valid before", 0); return ASN1_TIME_to_time_t(X509_get_notBefore(cert)); } time_t WvX509::get_notvalid_after() const { CHECK_CERT_EXISTS_GET("not valid after", 0); return ASN1_TIME_to_time_t(X509_get_notAfter(cert)); } WvString WvX509::get_ski() const { CHECK_CERT_EXISTS_GET("ski", WvString::null); return get_extension(NID_subject_key_identifier); } WvString WvX509::get_aki() const { CHECK_CERT_EXISTS_GET("aki", WvString::null); WvStringList aki_list; parse_stack(get_extension(NID_authority_key_identifier), aki_list, "keyid:"); if (aki_list.count()) return aki_list.popstr(); return WvString::null; } WvString WvX509::get_fingerprint(const FprintMode mode) const { CHECK_CERT_EXISTS_GET("fingerprint", WvString::null); /* Default to SHA-1 because OpenSSL does too */ const EVP_MD *digest = EVP_sha1(); if (mode == FingerMD5) digest = EVP_md5(); unsigned char md[EVP_MAX_MD_SIZE]; unsigned int n; if (!X509_digest(cert, digest, md, &n)) { errno = -ENOMEM; debug("get_fingerprint: Out of memory\n"); return WvString::null; } WvDynBuf store; char buf[3]; unsigned int i = 0; do { sprintf(buf, "%02X", md[i]); store.putstr(buf); } while (++i < n && (store.putch(':'), 1)); return store.getstr(); } void WvX509::set_ski() { CHECK_CERT_EXISTS_SET("ski"); ASN1_OCTET_STRING *oct = M_ASN1_OCTET_STRING_new(); ASN1_BIT_STRING *pk = cert->cert_info->key->public_key; unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL); M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen); X509_EXTENSION *ext = X509V3_EXT_i2d(NID_subject_key_identifier, 0, oct); X509_add_ext(cert, ext, -1); X509_EXTENSION_free(ext); M_ASN1_OCTET_STRING_free(oct); } void WvX509::set_aki(const WvX509 &cacert) { CHECK_CERT_EXISTS_SET("aki"); // can't set a meaningful AKI for subordinate certification without the // parent having an SKI ASN1_OCTET_STRING *ikeyid = NULL; X509_EXTENSION *ext; int i = X509_get_ext_by_NID(cacert.cert, NID_subject_key_identifier, -1); if ((i >= 0) && (ext = X509_get_ext(cacert.cert, i))) ikeyid = static_cast(X509V3_EXT_d2i(ext)); if (!ikeyid) return; AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new(); akeyid->issuer = NULL; akeyid->serial = NULL; akeyid->keyid = ikeyid; ext = X509V3_EXT_i2d(NID_authority_key_identifier, 0, akeyid); X509_add_ext(cert, ext, -1); X509_EXTENSION_free(ext); AUTHORITY_KEYID_free(akeyid); } wvstreams-4.6.1/crypto/wvxor.cc0000644000175000001440000000224111036722347015612 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * XOR cryptography abstractions. * Could use this to implement short one time pads. */ #include "wvxor.h" /***** WvXOREncoder *****/ WvXOREncoder::WvXOREncoder(const void *_key, size_t _keylen) : keylen(_keylen), keyoff(0) { key = new unsigned char[keylen]; memcpy(key, _key, keylen); } WvXOREncoder::~WvXOREncoder() { deletev key; } bool WvXOREncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t len; while ((len = inbuf.optgettable()) != 0) { const unsigned char *data = inbuf.get(len); unsigned char *out = outbuf.alloc(len); // FIXME: this loop is SLOW! (believe it or not) while (len-- > 0) { *out++ = (*data++) ^ key[keyoff++]; keyoff %= keylen; } } return true; } /***** WvXORStream *****/ WvXORStream::WvXORStream(WvStream *_cloned, const void *_key, size_t _keysize) : WvEncoderStream(_cloned) { readchain.append(new WvXOREncoder(_key, _keysize), true); writechain.append(new WvXOREncoder(_key, _keysize), true); } wvstreams-4.6.1/crypto/wvoakley.cc0000644000175000001440000000517411036722347016276 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2003 Net Integration Technologies, Inc. * * Oakley authentication for IPSec */ #include "wvoakley.h" /* Group 1 prime */ static unsigned char group1_key[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* Group 2 prime */ static unsigned char group2_key[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; WvOakleyAuth::WvOakleyAuth(int group) { switch (group) { case 1: dh = new WvDiffieHellman(group1_key, sizeof(group1_key), DH_GENERATOR_2); break; case 2: dh = new WvDiffieHellman(group2_key, sizeof(group2_key), DH_GENERATOR_2); break; case 3: case 4: /* We don't support any eliptic curve stuff. */ break; } pub_len = dh->pub_key_len(); } short WvOakleyAuth::public_len() { return pub_len; } short WvOakleyAuth::get_public_key(WvBuf &outbuf, short len) { return dh->get_public_value(outbuf, len); } void WvOakleyAuth::create_secret(WvBuf &_other_pub_key, short len) { other_pub_key.put(_other_pub_key.peek(0, len), len); other_len = len; dh->create_secret(_other_pub_key, len, dh_secret); return; } short WvOakleyAuth::other_pub_len() { return other_len; } short WvOakleyAuth::get_other_public_key(WvBuf &outbuf, short len) { if (len > other_len) len = other_len; outbuf.put(other_pub_key.peek(0, len), len); return len; } wvstreams-4.6.1/crypto/wvdsa.cc0000644000175000001440000000671511036722347015563 0ustar wlachusers/* * Worldvisions Tunnel Vision Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * DSA cryptography abstractions. */ #include #include #include #include "wvsslhacks.h" #include "wvdsa.h" #include "wvhex.h" /***** WvDSAKey *****/ WvDSAKey::WvDSAKey(const WvDSAKey &k) { if (k.prv) init(k.private_str(), true); else init(k.public_str(), false); } WvDSAKey::WvDSAKey(struct dsa_st *_dsa, bool priv) { if (_dsa == NULL) { // assert(_dsa); pub = WvString::null; prv = WvString::null; dsa = NULL; seterr("Initializing with a NULL key.. are you insane?"); return; } dsa = _dsa; pub = hexifypub(dsa); if (priv) prv = hexifyprv(dsa); } WvDSAKey::WvDSAKey(WvStringParm keystr, bool priv) { init(keystr, priv); } WvDSAKey::WvDSAKey(int bits) { dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); DSA_generate_key(dsa); pub = hexifypub(dsa); prv = hexifyprv(dsa); } WvDSAKey::~WvDSAKey() { if (dsa) DSA_free(dsa); } bool WvDSAKey::isok() const { return dsa && !errstring; } void WvDSAKey::init(WvStringParm keystr, bool priv) { // Start out with everything nulled out... dsa = NULL; pub = WvString::null; prv = WvString::null; // unhexify the supplied key WvDynBuf keybuf; if (!WvHexDecoder().flushstrbuf(keystr, keybuf, true) || keybuf.used() == 0) { seterr("DSA key is not a valid hex string"); return; } size_t keylen = keybuf.used(); const unsigned char *key = keybuf.get(keylen); // create the DSA struct if (priv) { dsa = wv_d2i_DSAPrivateKey(NULL, &key, keylen); if (dsa != NULL) { prv = keystr; pub = hexifypub(dsa); } } else { dsa = wv_d2i_DSAPublicKey(NULL, &key, keylen); if (dsa != NULL) { prv = WvString::null; pub = keystr; } } if (dsa == NULL) seterr("DSA key is invalid"); } WvString WvDSAKey::getpem(bool privkey) { FILE *fp = tmpfile(); const EVP_CIPHER *enc; if (!fp) { seterr("Unable to open temporary file!"); return WvString::null; } if (privkey) { enc = EVP_get_cipherbyname("dsa"); PEM_write_DSAPrivateKey(fp, dsa, enc, NULL, 0, NULL, NULL); } else { // We should write out the Public Key, which is the DSA Public // key, as well as the DH generator information. // PEM_write_DSAPublicKey(fp, dsa); } WvDynBuf b; size_t len; rewind(fp); while ((len = fread(b.alloc(1024), 1, 1024, fp)) > 0) b.unalloc(1024 - len); b.unalloc(1024 - len); fclose(fp); return b.getstr(); } WvString WvDSAKey::hexifypub(struct dsa_st *dsa) { WvDynBuf keybuf; assert(dsa); size_t size = i2d_DSAPublicKey(dsa, NULL); unsigned char *key = keybuf.alloc(size); size_t newsize = i2d_DSAPublicKey(dsa, & key); assert(size == newsize); assert(keybuf.used() == size); return WvString(WvHexEncoder().strflushbuf(keybuf, true)); } WvString WvDSAKey::hexifyprv(struct dsa_st *dsa) { WvDynBuf keybuf; assert(dsa); size_t size = i2d_DSAPrivateKey(dsa, NULL); unsigned char *key = keybuf.alloc(size); size_t newsize = i2d_DSAPrivateKey(dsa, & key); assert(size == newsize); return WvString(WvHexEncoder().strflushbuf(keybuf, true)); } wvstreams-4.6.1/crypto/wvdiffiehellman.cc0000644000175000001440000000520311036722347017572 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2003 Net Integration Technologies, Inc. * * Diffie-Hellman shared secret handshake. */ #include "wvautoconf.h" #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif #include #include #include "wvdiffiehellman.h" #include "strutils.h" WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen, BN_ULONG _generator) : generator(_generator), log("Diffie-Hellman", WvLog::Debug) { int problems; int check; { info = DH_new(); info->p = BN_bin2bn(_key, _keylen, NULL); // info->p->top = 0; // info->p->dmax = _keylen * 8 / BN_BITS2; // info->p->neg = 0; // info->p->flags = 0; info->g = BN_new(); BN_set_word(info->g, generator); // info->g->d = &generator; // info->g->top = 0; // info->g->dmax = 1; // info->g->neg = 0; // info->g->flags = 0; } check = BN_mod_word(info->p, 24); DH_check(info, &problems); if (problems & DH_CHECK_P_NOT_PRIME) log(WvLog::Error, "Using a composite number for authentication.\n"); if (problems & DH_CHECK_P_NOT_SAFE_PRIME) log(WvLog::Error,"Using an unsafe prime number for authentication.\n"); if (problems & DH_NOT_SUITABLE_GENERATOR) log(WvLog::Error, "Can you just use 2 instead of %s (%s)!!\n", BN_bn2hex(info->g), check); if (problems & DH_UNABLE_TO_CHECK_GENERATOR) log(WvLog::Notice, "Using a strange argument for diffie-hellman.\n"); DH_generate_key(info); } int WvDiffieHellman::pub_key_len() { return BN_num_bytes(info->pub_key); } int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len) { int key_len = BN_num_bytes(info->pub_key); if (key_len < len) len = key_len; // alloca is stack allocated, don't free it. unsigned char *foo = (unsigned char*)alloca(key_len); BN_bn2bin(info->pub_key, foo); outbuf.put(foo, len); return len; } bool WvDiffieHellman::create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf) { unsigned char *foo = (unsigned char *)alloca(DH_size(info)); log("My public value\n%s\nYour public value\n%s\n",BN_bn2hex(info->pub_key), hexdump_buffer(inbuf.peek(0, in_len), in_len, false)); int len = DH_compute_key (foo, BN_bin2bn(inbuf.get(in_len), in_len, NULL), info); outbuf.put(foo, len); log("Shared secret\n%s\n",hexdump_buffer(outbuf.peek(0, len), len, false)); return true; } wvstreams-4.6.1/wvstreams.supp0000644000175000001440000001076011061256402015537 0ustar wlachusers# valgrind suppressions file for known and unfixable errors caused by # wvstreams' interactions with other libraries. { zlib_deflate_error Memcheck:Cond fun:_tr_flush_block obj:/usr/lib/libz.so* fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_deflate_error_2 Memcheck:Cond obj:/usr/lib/libz.so* fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_deflate_error_3 Memcheck:Cond fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_deflate_error_4 Memcheck:Value4 obj:/usr/lib/libz.so* fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_deflate_error_5 Memcheck:Value4 obj:/usr/lib/libz.so* obj:/usr/lib/libz.so* obj:/usr/lib/libz.so* fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_deflate_error_6 Memcheck:Value4 obj:/usr/lib/libz.so* obj:/usr/lib/libz.so* obj:/usr/lib/libz.so* fun:deflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_inflate_error Memcheck:Value4 obj:/usr/lib/libz.so* fun:inflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_inflate_error_2 Memcheck:Cond obj:/usr/lib/libz.so* fun:inflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { zlib_inflate_error_3 Memcheck:Cond fun:inflate fun:_ZN13WvGzipEncoder7processER9WvBufBaseIhEbb } { stupid_libdl_error Memcheck:Cond fun:_dl_relocate_object fun:dl_open_worker fun:_dl_catch_error fun:__GI__dl_open } { stupid_libdl_error_2 Memcheck:Cond fun:_dl_relocate_object obj:/lib/libc-2.3.*.so fun:_dl_catch_error fun:_dl_open } { stupid_ld_error Memcheck:Cond obj:/lib/ld-2.3.*.so } { stupid_ld_error_2 Memcheck:Cond obj:/lib/ld-2.5*.so } { stupid_ld_error_3 Memcheck:Addr4 obj:/lib/ld-2.5*.so } { stupid_ld_error_4 Memcheck:Cond obj:/lib/ld-2.6*.so } { stupid_ld_error_5 Memcheck:Addr4 obj:/lib/ld-2.6*.so } { stupid_ld_error_6 Memcheck:Cond obj:/lib/ld-2.7*.so } { stupid_ld_error_7 Memcheck:Addr4 obj:/lib/ld-2.7*.so } { stupid_ecard_stuff Memcheck:Leak fun:malloc obj:/usr/lib/evolution/1.4/libicalvcal-evolution.so.0.0.0 fun:lookupStr fun:lookupProp fun:addGroup obj:/usr/lib/evolution/1.4/libicalvcal-evolution.so.0.0.0 fun:mime_parse obj:/usr/lib/evolution/1.4/libicalvcal-evolution.so.0.0.0 fun:e_card_new_with_default_charset fun:e_card_new } { stupid_elist_stuff Memcheck:Leak fun:calloc fun:g_malloc0 fun:g_type_create_instance obj:/usr/lib/libgobject-2.0.* fun:g_object_newv fun:g_object_new_valist fun:e_list_new } { stupid_libc_stuff Memcheck:Leak fun:malloc fun:my_malloc fun:get_or_allocate_specifics_ptr fun:pthread_key_create obj:/lib/libdl-2.3.*.so fun:pthread_once obj:/lib/libdl-2.3.*.so fun:dlvsym fun:__errno_location fun:_IOvfprintf } { stupid_zlib_stuff Memcheck:Cond obj:/usr/lib/libz.so* obj:/usr/lib/libz.so* fun:deflate } { sigaction_bites_my_nuts Memcheck:Param sigaction(act) fun:__libc_sigaction } { more_fun_libcrypto_junk Memcheck:Value4 fun:BF_encrypt } { more_fun_libcrypto_junk_2 Memcheck:Value4 fun:AES_encrypt } { more_fun_licrypto_junk_3 Memcheck:Addr4 fun:AES_cbc_encrypt } { more_fun_licrypto_junk_4 Memcheck:Value4 fun:_x86_AES_encrypt } { WvInterface has a static WvInterfaceDict Memcheck:Leak fun:__builtin_vec_new fun:__t11WvHashTable4Z11WvInterfaceZ8WvStringZt27WvInterfaceDictBaseAccessor2Z11WvInterfaceZ8WvStringz1Z8OpEqCompUi fun:__static_initialization_and_destruction_0 fun:_GLOBAL_.I._15WvInterfaceDict.links } { statfs_has_issues Memcheck:Param statfs64(buf) fun:statfs64 } { popt_is_leaky Memcheck:Leak fun:realloc fun:expandNextArg fun:poptGetNextOpt } { getgrnam_is_leaky Memcheck:Leak fun:malloc obj:/lib/tls/i686/cmov/libc-2.6.1.so fun:__nss_database_lookup obj:* obj:* fun:getgrnam_r fun:getgrnam } { WvHashTableBase_has_issues Memcheck:Cond fun:_ZN15WvHashTableBaseC2Ej } { WvHashTable_confuses_valgrind Memcheck:Leak fun:_Znaj fun:_ZN11WvHashTable* } { UniConfKey_has_a_static_element Memcheck:Leak fun:_Znaj fun:_ZN10UniConfKey13SegmentVectorC1Ei fun:_ZN10UniConfKey5StoreC1EiiRK12WvFastString fun:_Z41__static_initialization_and_destruction_0ii } { libdl_invalid_read Memcheck:Addr4 obj:/lib/ld-2.3.6.so } wvstreams-4.6.1/wvrules-posix.mk0000644000175000001440000000476411077372756016024 0ustar wlachusersifdef _WIN32 LIBWVSTATIC=$(WVSTREAMS_LIB)/libwvstatic.a LIBWVBASE=$(LIBWVSTATIC) LIBWVUTILS=$(LIBWVSTATIC) LIBWVSTREAMS=$(LIBWVSTATIC) LIBUNICONF=$(LIBWVSTATIC) LIBWVDBUS=$(LIBWVSTATIC) $(LIBS_DBUS) LIBWVQT=$(LIBWVSTATIC) LIBWVTEST=$(WVSTREAMS_LIB)/libwvtest.a $(LIBWVUTILS) else LIBWVSTATIC=$(WVSTREAMS_LIB)/libwvstatic.a LIBWVBASE=$(WVSTREAMS_LIB)/libwvbase.so LIBWVUTILS=$(WVSTREAMS_LIB)/libwvutils.so $(LIBWVBASE) LIBWVSTREAMS=$(WVSTREAMS_LIB)/libwvstreams.so $(LIBWVUTILS) LIBUNICONF=$(WVSTREAMS_LIB)/libuniconf.so $(LIBWVSTREAMS) ifneq ("$(with_dbus)", "no") LIBWVDBUS=$(WVSTREAMS_LIB)/libwvdbus.so $(LIBWVSTREAMS) endif ifneq ("$(with_qt)", "no") LIBWVQT=$(WVSTREAMS_LIB)/libwvqt.so $(LIBWVSTREAMS) endif LIBWVTEST=$(WVSTREAMS_LIB)/libwvtest.a $(LIBWVUTILS) endif # # Initial C compilation flags # INCFLAGS=$(addprefix -I,$(WVSTREAMS_INC) $(XPATH)) CPPFLAGS += $(CPPOPTS) CFLAGS += $(COPTS) CXXFLAGS += $(CXXOPTS) LDFLAGS += $(LDOPTS) -L$(WVSTREAMS_LIB) # Default compiler we use for linking WVLINK_CC = $(CXX) ifneq ("$(enable_optimization)", "no") CXXFLAGS+=-O2 CFLAGS+=-O2 endif ifneq ("$(enable_warnings)", "no") CXXFLAGS+=-Wall -Woverloaded-virtual CFLAGS+=-Wall endif DEBUG:=$(filter-out no 0,$(enable_debug)) ifdef DEBUG CPPFLAGS += -ggdb -DDEBUG=1 $(patsubst %,-DDEBUG_%,$(DEBUG)) LDFLAGS += -ggdb else CPPFLAGS += -DDEBUG=0 LDFLAGS += endif define wvlink_ar $(LINK_MSG)set -e; rm -f $1 $(patsubst %.a,%.libs,$1); \ echo $2 $($1-EXTRA) >$(patsubst %.a,%.libs,$1); \ $(AR) q $1 $(filter %.o,$2 $($1-EXTRA)); \ for d in "" $(filter %.libs,$2 $($1-EXTRA)); do \ if [ "$$d" == "" ]; then \ continue; \ fi; \ cd $$(dirname "$$d"); \ for c in $$(cat $$(basename "$$d")); do \ if echo $$c | grep -q "\.list$$"; then \ for i in $$(cat $$c); do \ $(AR) q $(shell pwd)/$1 $$i; \ done; \ else \ $(AR) q $(shell pwd)/$1 $$c; \ fi; \ done; \ cd $(shell pwd); \ done; \ for l in "" $(filter %.list,$2 $($1-EXTRA)); do \ if [ "$$l" == "" ]; then \ continue; \ fi; \ for i in $$(cat $$l); do \ $(AR) q $1 $$(dirname "$$l")/$$i; \ done; \ done; \ $(AR) s $1 endef CC: FORCE @CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" \ $(WVSTREAMS)/gen-cc CC c CXX: FORCE @CC="$(CXX)" CFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" \ $(WVSTREAMS)/gen-cc CXX cc wvlink=$(LINK_MSG)$(WVLINK_CC) $(LDFLAGS) $($1-LDFLAGS) -o $1 $(filter %.o %.a %.so, $2) $($1-LIBS) $(XX_LIBS) $(LDLIBS) $(PRELIBS) $(LIBS) wvstreams-4.6.1/config.sub0000755000175000001440000007577711036722347014611 0ustar wlachusers#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-07-08' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | ms1 \ | msp430 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m32c) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | ms1-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; m32c-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: wvstreams-4.6.1/config.defaults.mk0000644000175000001440000000151011077372756016212 0ustar wlachusersCOMPILER_STANDARD=posix EXEEXT= INSTALL=/usr/bin/install -c INSTALL_DATA=${INSTALL} -m 644 INSTALL_PROGRAM=${INSTALL} INSTALL_SCRIPT=${INSTALL} LN_S=ln -s LN=ln MOC=/usr/bin/moc LIBS_DBUS=-ldbus-1 LIBS_QT=-lqt-mt LIBS_PAM=-lpam LIBS_TCL= prefix=/usr/local datadir=${prefix}/share includedir=${prefix}/include infodir=${prefix}/share/info localstatedir=${prefix}/var mandir=${prefix}/share/man sharedstatedir=${prefix}/com sysconfdir=${prefix}/etc exec_prefix=${prefix} bindir=${exec_prefix}/bin libdir=${exec_prefix}/lib libexecdir=${exec_prefix}/libexec sbindir=${exec_prefix}/sbin enable_debug=yes enable_optimization=no enable_resolver_fork= enable_warnings= enable_testgui= with_dbus= with_openssl=../wvports/openssl/build/openssl with_pam= with_tcl=no with_readline=no with_qt=/usr with_xplc=../wvports/xplc/build/xplc with_zlib= wvstreams-4.6.1/install-sh0000755000175000001440000000421211036722347014602 0ustar wlachusers#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # 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}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" 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;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 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` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 wvstreams-4.6.1/ipstreams/0000755000175000001440000000000011260431126014575 5ustar wlachuserswvstreams-4.6.1/ipstreams/wvurl.cc0000644000175000001440000001150411255004130016257 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvUrl is a simple URL-parsing class with built-in (though still somewhat * inconvenient) DNS resolution. * * See wvurl.h. */ #include "wvurl.h" #include "strutils.h" // A static list of the default ports for each protocol. struct DefaultPort { const char *proto; int port; bool uses_slashes; }; // The protocols must be arranged from longest to shortest because they're // compared with strncmp, so "https://" will also match http. static DefaultPort portmap[] = { { "exchangeits", 7070, false }, { "exchangeit", 6969, false }, { "https", 443, true }, { "http", 80, true }, { "file", 0, true }, { "sip", 5060, false }, { "ftp", 21, true }, { "ldaps", 636, false }, { "ldap", 389, false }, { NULL, 0 } }; // Look up the protocol and return the default port. static int get_default_port(WvString proto) { DefaultPort *p = portmap; for (p = portmap; p->proto != NULL; p++) { if (strncmp(p->proto, proto, strlen(p->proto)) == 0) return p->port; } return -1; } // Look up the protocol and decide whether it uses slashes (http) or not (sip) // A check of rfc2396 shows that the URI standard actually distinguishes // these: 'hierarchical' vs. 'opaque'. static bool protocol_uses_slashes(WvString proto) { DefaultPort *p = portmap; for (p = portmap; p->proto != NULL; p++) { if (strncmp(p->proto, proto, strlen(p->proto)) == 0) return p->uses_slashes; } return false; } // Split up the URL into a hostname, a port, and the rest of it. WvUrl::WvUrl(WvStringParm url) : err("No error") { WvString work(url); char *cptr, *wptr = work.edit(); port = 0; // error condition by default addr = NULL; resolving = true; // deal with extra whitespace. wptr = trim_string(wptr); cptr = wptr + strcspn(wptr, " \t\r\n"); *cptr = 0; // if it's not one of these easy prefixes, give up. Our URL parser is // pretty dumb. if (get_default_port(wptr) < 0) { err = "WvUrl cannot handle the given protocol."; return; } cptr = strchr(wptr, ':'); if (!cptr) { err = "No colon after the protocol."; return; } *cptr = 0; proto = wptr; bool use_slashes = protocol_uses_slashes(proto); wptr = cptr + (use_slashes ? 3 : 1); cptr = strchr(wptr, '@'); if (!cptr) // no user given { user = ""; password = ""; } else { *cptr = 0; char *cptr2 = strchr(wptr, ':'); if (cptr2 && (*(cptr2+1) != 0)) { *cptr2 = 0; password = cptr2 + 1; } else password = ""; user = wptr; wptr = cptr + 1; } cptr = strchr(wptr, '/'); if (!cptr) // no path given file = use_slashes ? "/" : ""; else { file = cptr; *cptr = 0; } cptr = strchr(wptr, ':'); if (!cptr) port = get_default_port(proto); else { port = atoi(cptr+1); *cptr = 0; } hostname = wptr; resolve(); } WvUrl::WvUrl(const WvUrl &url) : err("No error") { addr = NULL; resolving = true; proto = url.proto; user = url.user; password = url.password; hostname = url.hostname; file = url.file; port = url.port; resolve(); } WvUrl::~WvUrl() { if (addr) delete addr; } bool WvUrl::resolve() { const WvIPAddr *ip; int numaddrs; numaddrs = dns.findaddr(0, hostname, &ip); if (!numaddrs) // error condition { err = WvString("Host '%s' could not be found.", hostname); resolving = false; return false; } else if (numaddrs < 0) // still waiting { resolving = true; return false; } else // got at least one address { resolving = false; if (addr) delete addr; addr = new WvIPPortAddr(*ip, port); return true; } } // Print out the URL, using the port name (if it's not 80), and either the // hostname (if we know it) or the address (if we know that instead.) WvUrl::operator WvString () const { if (!isok()) return WvString("(Invalid URL: %s)", err); WvString protostr; if (protocol_uses_slashes(proto)) protostr = WvString("%s://", proto); else protostr = WvString("%s:", proto); WvString userstr(""); if (user && user.len() != 0) { userstr = WvString("%s", user); if (password && password.len() != 0) userstr.append(WvString(":%s@", password)); else userstr.append("@"); } WvString portstr(""); if (port && port != get_default_port(proto)) portstr = WvString(":%s", port); if (hostname) return WvString("%s%s%s%s%s", protostr, userstr, hostname, portstr, file); else if (addr) return WvString("%s%s%s%s%s", protostr, userstr, *addr, portstr, file); else { assert(0); return WvString("(Invalid URL)"); } } wvstreams-4.6.1/ipstreams/tests/0000755000175000001440000000000011260431131015733 5ustar wlachuserswvstreams-4.6.1/ipstreams/tests/listentest.cc0000644000175000001440000000433611036722347020463 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTCPListener test. Listens on a port, and bounces stdin and stdout * between all connections established to it. */ #include "wvtcplistener.h" #include "wvtcp.h" #include "wvistreamlist.h" #include "wvlog.h" static void stream_bounce_to_list(WvStream &s, WvIStreamList *list) { WvIStreamList::Iter out(*list); char *line; while ((line = s.getline()) != NULL) { if (!strncmp(line, "quit", 4)) { s.close(); continue; } for (out.rewind(); out.next(); ) { if (&out() != &s && out->iswritable()) { static_cast(&out())->print("%s> %s\n", s.src() ? (WvString)*s.src() : WvString("stdin"), line); if (s.src()) wvcon->print("Local address of source was %s\n", ((WvTCPConn *)&s)->localaddr()); } } } } static void accept_callback(WvIStreamList &list, IWvStream *_conn) { WvStreamClone *conn = new WvStreamClone(_conn); conn->setcallback(wv::bind(stream_bounce_to_list, wv::ref(*conn), &list)); list.append(conn, true, "WvTCPConn"); } int main(int argc, char **argv) { { WvLog log("testlisten"), err = log.split(WvLog::Error); WvIStreamList l; WvTCPListener sock(WvIPPortAddr(argc==2 ? argv[1] : "0.0.0.0:0")); wvcon->setcallback(wv::bind(stream_bounce_to_list, wv::ref(*wvcon), &l)); sock.onaccept(wv::bind(accept_callback, wv::ref(l), _1)); log("Listening on port %s\n", *sock.src()); l.append(&sock, false, "socket"); l.append(wvcon, false, "wvcon"); while (sock.isok() && wvcon->isok()) { if (l.select(-1)) l.callback(); } if (!sock.isok() && sock.geterr()) err("%s\n", strerror(sock.geterr())); if (!wvcon->isok() && wvcon->geterr()) err("%s\n", strerror(wvcon->geterr())); } // all variables should now be freed #if DEBUG fprintf(stderr, "File descriptors still open: "); bool found = false; for (int count = 0; count < 255; count++) { int dupfd = dup(count); if (dupfd >= 0) { fprintf(stderr, "#%d ", count); found = true; close(dupfd); } } if (!found) fprintf(stderr, "none.\n"); else fprintf(stderr, "\n"); #endif return 0; } wvstreams-4.6.1/ipstreams/tests/udglistentest.cc0000644000175000001440000000163111036722347021156 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * WvUnixDGListener test. Creates a Unix Domain socket on /tmp/fuzzy or * whatever you give it on the command line, prints anything it receives to * stdout. */ #include "wvunixdgsocket.h" #include "wvlog.h" #include "wvistreamlist.h" #define DEFAULT "/tmp/fuzzy" int main(int argc, char **argv ) { WvLog log(("unixdatagramlisten"), WvLog::Debug1); WvString filename; if (argc == 2) filename = argv[1]; else filename = DEFAULT; WvUnixDGListener sock(filename, 0777); sock.autoforward(*wvout); log("Listening on %s\n", filename); WvIStreamList l; l.append(&sock, false, "socket"); l.append(wvcon, false, "wvcon"); while (sock.isok() && wvout->isok()) { if (l.select(-1)) l.callback(); } return 0; } wvstreams-4.6.1/ipstreams/tests/ip2test.cc0000644000175000001440000000644111036722347017656 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UDP test program. I don't think this works... */ #include "wvistreamlist.h" #include "wvlog.h" #include "wvipraw.h" #include "wvhashtable.h" #include DeclareWvList(WvInPlaceBuf); class WvIPRawListener; class WvIPRawConn : public WvStream { friend class WvIPRawListener; public: WvIPRawConn(WvIPRawListener *_parent, const WvIPAddr &_remaddr); WvIPAddr remaddr; protected: WvIPRawListener *parent; time_t last_receive; WvInPlaceBufList buflist; virtual bool isok() const; virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); void push(const void *buf, size_t size); }; DeclareWvDict(WvIPRawConn, WvIPAddr, remaddr); class WvIPRawListener : public WvIPRawStream { friend class WvIPRawConn; WvIPRawConnDict connlist; public: WvIPRawListener(const WvIPAddr &_localaddr); virtual void execute(); }; WvIPRawConn::WvIPRawConn(WvIPRawListener *_parent, const WvIPAddr &_remaddr) : remaddr(_remaddr) { parent = _parent; time(&last_receive); } bool WvIPRawConn::isok() const { return parent->connlist[remaddr] == this; } size_t WvIPRawConn::uread(void *buf, size_t size) { if (!buflist.count()) return 0; WvInPlaceBufList::Iter i(buflist); i.rewind(); i.next(); WvInPlaceBuf &b = *i; if (b.used() < size) size = b.used(); memcpy(buf, b.get(size), size); i.unlink(); return size; } size_t WvIPRawConn::uwrite(const void *buf, size_t size) { parent->setdest(remaddr); return parent->write(buf, size); } void WvIPRawConn::push(const void *buf, size_t size) { time(&last_receive); WvInPlaceBuf *b = new WvInPlaceBuf(size); b->put(buf, size); buflist.append(b, true); } WvIPRawListener::WvIPRawListener(const WvIPAddr &_localaddr) : WvIPRawStream(_localaddr, WvIPAddr()), connlist(7) { } void WvIPRawListener::execute() { WvIPRawStream::execute(); unsigned char buf[2048]; // larger than an expected UDP packet size_t len; while (select(0)) { len = read(buf, sizeof(buf)); if (!len) continue; WvIPRawConn *conn = connlist[*(WvIPAddr *)src()]; if (!conn) { conn = new WvIPRawConn(this, *(WvIPAddr *)src()); connlist.add(conn, true); } conn->push(buf, len); } } int main(int argc, char **argv) { WvLog err("ip2test", WvLog::Error); WvIPAddr localaddr(argc > 1 ? argv[1] : "0.0.0.0"); WvIPRawListener sock(localaddr); err(WvLog::Info, "Local address is %s.\n", localaddr); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); #if 0 // not done yet while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } #endif if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; } wvstreams-4.6.1/ipstreams/tests/wvstreams.cc0000644000175000001440000000370411036722347020316 0ustar wlachusers#include "wvistreamlist.h" #include "wvlog.h" #include "pwvstream.h" #include "wvstreamclone.h" #include "wvlinkerhack.h" #include WV_LINK_TO(WvConStream); WV_LINK_TO(WvTCPConn); volatile bool want_to_die = false; static void signalhandler(int sig) { fprintf(stderr, "Caught signal %d. Exiting...\n", sig); want_to_die = true; signal(sig, SIG_DFL); } static void bounce_to_list(IWvStream *in, WvIStreamList *list) { char buf[4096]; size_t len; len = in->read(buf, sizeof(buf)); WvIStreamList::Iter i(*list); for (i.rewind(); i.next(); ) { if (in != i.ptr()) { // you might think this assumes IWvStream has a buffer; but in // fact, we already know that everything in the list is a // WvStreamClone, and WvStreamClone *does* have an output // buffer, so this is safe. i->write(buf, len); } } } static void died(WvLog &log, WvStringParm name, IWvStream *s) { if (s->geterr()) log("%s: %s\n", name, s->errstr()); } static void add(WvLog &log, WvIStreamList &list, const char *_mon) { WvString mon(_mon); if (mon == "-") mon = "stdio"; log("Creating stream: '%s'\n", mon); PWvStream s(mon); if (!s->isok()) died(log, _mon, s.addRef()); else { s->setcallback(wv::bind(bounce_to_list, s.get(), &list)); s->setclosecallback(wv::bind(died, log, _mon, s.addRef())); } list.append(s.addRef(), true, _mon); } int main(int argc, char **argv) { WvIStreamList list; WvLog log(argv[0], WvLog::Debug); signal(SIGTERM, signalhandler); signal(SIGINT, signalhandler); if (argc <= 1) { fprintf(stderr, "Usage: %s [stream2 [stream3...]]\n", argv[0]); return 1; } if (argc == 2) // talking to just one stream means send it to stdio add(log, list, "-"); for (int count = 1; count < argc; count++) add(log, list, argv[count]); while (!want_to_die && list.count() >= 2) list.runonce(); } wvstreams-4.6.1/ipstreams/tests/resolvertest.cc0000644000175000001440000000236111036722347021022 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvResolver test program. Tries to look up two host names given on the * command line. */ #include "wvresolver.h" #include "wvlog.h" void test(WvResolver &dns, int argc, char **argv) { WvLog log("resolvertest", WvLog::Info); const WvIPAddr *addr; int res1, res2; const char *n1 = argc > 1 ? argv[1] : "www"; const char *n2 = argc > 2 ? argv[2] : "www.google.com"; log("Using [1]='%s', [2]='%s'\n", n1, n2); res1 = res2 = -1; while (res1 < 0 || res2 < 0) { if (res1 < 0) { res1 = dns.findaddr(100, n1, &addr); if (res1 > 0) log.print("Found address for 1: %s\n", *addr); else if (res1 < 0) log.print("[1] "); else log(WvLog::Error, "1 not in DNS.\n"); } if (res2 < 0) { res2 = dns.findaddr(100, n2, &addr); if (res2 > 0) log.print("Found address for 2: %s\n", *addr); else if (res2 < 0) log.print("[2] "); else log(WvLog::Error, "2 not in DNS.\n"); } } } int main(int argc, char **argv) { { WvResolver dns; test(dns, argc, argv); test(dns, argc, argv); } { WvResolver dns; test(dns, argc, argv); } return 0; } wvstreams-4.6.1/ipstreams/tests/wvaddrcomptest.cc0000644000175000001440000000373711036722347021337 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvAddr comparison test program. * */ #include "wvaddr.h" #include "assert.h" void test1(WvIPAddr& justip1, WvIPAddr& justip2, WvIPAddr& ipnet1, WvIPAddr& ipnet2, WvIPAddr& ipnet3, WvIPAddr& ipport1, WvIPAddr& ipport2, WvIPAddr& ipport3) { assert (justip1 == ipnet1 && ipnet2 == justip2 && justip1 == justip1 && ipnet2 == ipnet2 && ipnet1 != ipnet2 && justip1 != justip2 && justip2 == ipport3 && ipport3 == justip2 && ipport3 != ipport2 && ipport3 == ipport3); }; void test2(WvAddr& string, WvAddr& justip1, WvAddr& justip2, WvAddr& ipnet1, WvAddr& ipnet2, WvAddr& ipnet3, WvAddr& ipport1, WvAddr& ipport2, WvAddr& ipport3) { assert (justip1 == ipnet1 && ipnet2 == justip2 && justip1 == justip1 && ipnet2 == ipnet2 && ipnet1 != ipnet2 && justip1 != justip2 && justip2 == ipport3 && ipport3 == justip2 && ipport3 != ipport2 && ipport3 == ipport3 && string != justip1 && justip1 != string && string == string); }; int main() { free(malloc(1)); WvEncap tmp; WvStringAddr string("1.2.3.4", tmp); WvIPAddr justip1("1.2.3.4"); WvIPAddr justip2("7.2.3.4"); WvIPNet ipnet1("1.2.3.4", 24); WvIPNet ipnet2("7.2.3.4", 24); WvIPNet ipnet3("7.2.3.4", 32); WvIPNet ipport1("1.2.3.4", 75); WvIPNet ipport2("7.2.3.4", 75); WvIPNet ipport3("7.2.3.4", 57); test1(justip1, justip2, ipnet1, ipnet2, ipnet3, ipport1, ipport2, ipport3); test2(string, justip1, justip2, ipnet1, ipnet2, ipnet3, ipport1, ipport2, ipport3); assert (justip1 == ipnet1 && ipnet2 == justip2 && justip1 == justip1 && ipnet2 == ipnet2 && ipnet1 != ipnet2 && justip1 != justip2 && justip2 == ipport3 && ipport3 == justip2 && ipport3 != ipport2 && ipport3 == ipport3 && string != justip1 && justip1 != string && string == string); return 0; } wvstreams-4.6.1/ipstreams/tests/unixdgtest.cc0000644000175000001440000000207111036722347020455 0ustar wlachusers/* * Worldvisions Weaver Software: Copyright (C) 1997-2004 Net Integration * Technologies, Inc. * * WvUnixDGConn test. Outputs to a unix datagram socket on /tmp/fuzzy or * whatever you give it on the command line. Note that the destination socket * must exist beforehand. */ #include "wvunixdgsocket.h" #include "wvlog.h" #include "wvistreamlist.h" #define DEFAULT "/tmp/fuzzy" int main(int argc, char **argv) { WvLog err("unixdgtest", WvLog::Error); WvString filename; if (argc == 2) filename = argv[1]; else filename = DEFAULT; WvUnixDGConn sock(filename); wvcon->autoforward(sock); sock.autoforward(*wvcon); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); while (wvcon->isok() && sock.isok()) { if (l.select(-1)) l.callback(); } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", wvcon->errstr()); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", sock.errstr()); return 0; } wvstreams-4.6.1/ipstreams/tests/componenttest.cc0000644000175000001440000000305311036722347021162 0ustar wlachusers#include "wvmoniker.h" #include "wvistreamlist.h" #include "wvstreamclone.h" #include static void httpget(WvStream &input, WvStream &output) { static int countdown = 6; if (input.alarm_was_ticking) { if (!--countdown) { wvcon->print("...sending to TCP stream.\n"); input.print("GET / HTTP/1.0\r\n\r\n"); } else wvcon->print("[%s]", countdown); } WvStream::autoforward_callback(input, output); input.alarm(1000); } int main() { IWvStream *con = wvcon; // get streams from a component IWvStream *ssl = wvcreate("ssl:tcp:192.168.12.1:995"); IWvStream *tcp2 = wvcreate("tcp:192.168.12.1:80"); // add handy WvStreams-style functionality by cloning them WvStreamClone a((con->addRef(), con)); WvStreamClone b(ssl); WvStreamClone c(tcp2); // make them do something useful a.autoforward(b); b.autoforward(a); c.setcallback(wv::bind(httpget, wv::ref(c), wv::ref(a))); c.alarm(1*1000); // create a list of them (in fact, we could use a WvStreamList here...) // -- but we want to get rid of WvStreamLists and move over to WvIStreamList WvIStreamList l; WvIStreamList::globallist.append(&a, false, "a"); l.append(&b, false, "b"); l.append(&c, false, "c"); while (a.isok() && b.isok() && c.isok()) { if (l.select(-1)) l.callback(); } if (b.geterr()) wvcon->print("tcp1: %s\n", b.errstr()); if (c.geterr()) wvcon->print("tcp2: %s\n", c.errstr()); return 0; } wvstreams-4.6.1/ipstreams/tests/udp2test.cc0000644000175000001440000000642211036722347020035 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UDP test program. I don't think this works... */ #include "wvistreamlist.h" #include "wvlog.h" #include "wvudp.h" #include "wvhashtable.h" #include DeclareWvList(WvInPlaceBuf); class WvUDPListener; class WvUDPConn : public WvStream { friend class WvUDPListener; public: WvUDPConn(WvUDPListener *_parent, const WvIPPortAddr &_remaddr); WvIPPortAddr remaddr; protected: WvUDPListener *parent; time_t last_receive; WvInPlaceBufList buflist; virtual bool isok() const; virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); void push(const void *buf, size_t size); }; DeclareWvDict(WvUDPConn, WvIPPortAddr, remaddr); class WvUDPListener : public WvUDPStream { friend class WvUDPConn; WvUDPConnDict connlist; public: WvUDPListener(const WvIPPortAddr &_localaddr); virtual void execute(); }; WvUDPConn::WvUDPConn(WvUDPListener *_parent, const WvIPPortAddr &_remaddr) : remaddr(_remaddr) { parent = _parent; time(&last_receive); } bool WvUDPConn::isok() const { return parent->connlist[remaddr] == this; } size_t WvUDPConn::uread(void *buf, size_t size) { if (!buflist.count()) return 0; WvInPlaceBufList::Iter i(buflist); i.rewind(); i.next(); WvInPlaceBuf &b = *i; if (b.used() < size) size = b.used(); memcpy(buf, b.get(size), size); i.unlink(); return size; } size_t WvUDPConn::uwrite(const void *buf, size_t size) { parent->setdest(remaddr); return parent->write(buf, size); } void WvUDPConn::push(const void *buf, size_t size) { time(&last_receive); WvInPlaceBuf *b = new WvInPlaceBuf(size); b->put(buf, size); buflist.append(b, true); } WvUDPListener::WvUDPListener(const WvIPPortAddr &_localaddr) : WvUDPStream(_localaddr, WvIPPortAddr()), connlist(7) { } void WvUDPListener::execute() { WvUDPStream::execute(); unsigned char buf[2048]; // larger than an expected UDP packet size_t len; while (select(0)) { len = read(buf, sizeof(buf)); if (!len) continue; WvUDPConn *conn = connlist[*(WvIPPortAddr *)src()]; if (!conn) { conn = new WvUDPConn(this, *(WvIPPortAddr *)src()); connlist.add(conn, true); } conn->push(buf, len); } } int main(int argc, char **argv) { WvLog err("udptest", WvLog::Error); WvIPPortAddr localaddr(argc > 1 ? argv[1] : "0.0.0.0:2222"); WvUDPListener sock(localaddr); err(WvLog::Info, "Local address is %s.\n", localaddr); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); #if 0 // not done yet while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } #endif if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; } wvstreams-4.6.1/ipstreams/tests/unixtest.cc0000644000175000001440000000155111036722347020144 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvUnixConn test. Creates a Unix Domain socket on /tmp/fuzzy or whatever * you give it on the command line. */ #include "wvunixsocket.h" #include "wvistreamlist.h" #include "wvlog.h" int main(int argc, char **argv) { WvLog err("unixtest", WvLog::Error); WvUnixConn sock(argc==2 ? argv[1] : "/tmp/fuzzy"); wvcon->autoforward(sock); sock.autoforward(*wvcon); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); while (wvcon->isok() && sock.isok()) { if (l.select(-1)) l.callback(); } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", wvcon->errstr()); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", sock.errstr()); return 0; } wvstreams-4.6.1/ipstreams/tests/wsd.cc0000644000175000001440000001242611202637334017055 0ustar wlachusers#include "wvfdstream.h" #include "wvistreamlist.h" #include "wvstrutils.h" #include "wvunixsocket.h" #include #include #ifndef MACOS // The version of READLINE shipped with MacOS is brain damaged. class WvReadLineStream : public WvStream { static WvReadLineStream *me; WvStream *base; WvString prompt; WvDynBuf line_buf; WvStringList commands; virtual size_t uread(void *_buf, size_t count) { size_t result = 0; char *buf = (char *)_buf; while (count > 0 && line_buf.used() > 0) { size_t chunk = line_buf.optgettable(); if (chunk > count) chunk = count; memcpy(buf, line_buf.get(chunk), chunk); count -= chunk; buf += chunk; result += chunk; } return result; } virtual size_t uwrite(const void *_buf, size_t count) { const char *buf = (const char *)_buf; for (size_t i=0; iline_buf.put(str, len); me->line_buf.putch('\n'); add_history(str); } static int readline_getc(FILE *) { char ch; assert(me->base->read(&ch, 1) == 1); return ch; } static char *readline_command_completion_function(const char *text, int state) { static int skip = 0; if (state == 0) skip = 0; int my_skip = skip; size_t len = strlen(text); WvStringList::Iter i(me->commands); for (i.rewind(); i.next(); ) { if (my_skip-- > 0) continue; ++skip; if (i->len() >= len && strncmp(*i, text, len) == 0) return strdup(*i); } return NULL; } virtual void pre_select(SelectInfo &si) { if (si.wants.readable && line_buf.used() > 0) si.msec_timeout = 0; base->pre_select(si); } virtual bool post_select(SelectInfo &si) { bool now = false; if (si.wants.readable && line_buf.used() > 0) now = true; while (base->isreadable()) rl_callback_read_char(); return base->post_select(si) || now; } public: WvReadLineStream(WvStream *_base, WvStringParm _prompt) { base = _base; prompt = _prompt; assert(!me); me = this; set_wsname("readline on %s", base->wsname()); rl_already_prompted = 1; rl_completion_entry_function = readline_command_completion_function; rl_callback_handler_install(prompt, readline_callback); rl_getc_function = readline_getc; } ~WvReadLineStream() { rl_getc_function = NULL; rl_callback_handler_remove(); me = NULL; } virtual bool isok() const { return WvStream::isok() && base->isok(); } void display_prompt() { base->print("%s", prompt); rl_already_prompted = 1; } void set_commands(const WvStringList &_commands) { commands.zap(); WvStringList::Iter i(_commands); for (i.rewind(); i.next(); ) commands.append(*i); } const char *wstype() const { return "WvReadLineStream"; } }; WvReadLineStream *WvReadLineStream::me = NULL; void remote_cb(WvStream &remote, WvReadLineStream &local) { const char *line = remote.getline(); if (line == NULL) return; WvStringList words; wvtcl_decode(words, line); WvString first = words.popstr(); bool last_line = !!first && first != "-"; if (last_line) local.print("%s ", first); local.print("%s\n", words.join(" ")); if (last_line) local.display_prompt(); if (words.popstr() == "Commands availible:") local.set_commands(words); } void local_cb(WvReadLineStream &local, WvStream &remote) { const char *line = local.getline(); if (line == NULL) return; if (strcmp(line, "quit") == 0) remote.close(); remote.print("%s\n", line); } int main(int argc, char **argv) { WvReadLineStream readlinestream(wvcon, "> "); const char *sockname = "/tmp/weaver.wsd"; if (argc >= 2) sockname = argv[1]; WvUnixConn *s = new WvUnixConn(sockname); if (!s->isok()) { wverr->print("Failed to connect to %s: %s\n", sockname, s->errstr()); return 1; } s->set_wsname("%s", sockname); s->print("help\n"); s->setcallback(wv::bind(remote_cb, wv::ref(*s), wv::ref(readlinestream))); WvIStreamList::globallist.append(s, true, "wvstreams debugger client"); readlinestream.setcallback(wv::bind(local_cb, wv::ref(readlinestream), wv::ref(*s))); WvIStreamList::globallist.append(&readlinestream, false, "wvstreams debugger readline"); while (s->isok() && readlinestream.isok()) WvIStreamList::globallist.runonce(); return 0; } #endif // Apple brain damaged Readline.wvstreams-4.6.1/ipstreams/tests/component2test.cc0000644000175000001440000000201211036722347021236 0ustar wlachusers#include "wvmoniker.h" #include "wvistreamlist.h" #include "wvstreamclone.h" #include "wvlog.h" #include "wvlogrcv.h" #include int main() { WvLogConsole rcv(2, WvLog::Debug2); // get streams from a component IWvStream *url1 = wvcreate("http://mai/"); IWvStream *url2 = wvcreate("https://mai/~apenwarr/"); // add handy WvStreams-style functionality by cloning them WvStreamClone a(url1); WvStreamClone b(url2); // make them do something useful WvLog l1("log1", WvLog::Info); WvLog l2("log2", WvLog::Info); a.autoforward(l1); b.autoforward(l2); // create a list of them (in fact, we could use a WvStreamList here...) WvIStreamList l; l.append(&a, false, "a"); l.append(&b, false, "b"); while (a.isok() || b.isok()) { if (l.select(-1)) l.callback(); } if (a.geterr()) wvcon->print("url1: %s\n", a.errstr()); if (b.geterr()) wvcon->print("url2: %s\n", b.errstr()); return 0; } wvstreams-4.6.1/ipstreams/tests/ulistentest.cc0000644000175000001440000000405711036722347020650 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #include "wvunixsocket.h" #include "wvunixlistener.h" #include "wvistreamlist.h" #include "wvlog.h" static void stream_bounce_to_list(WvStream *in, WvIStreamList *list, WvStringParm localaddr) { WvIStreamList::Iter out(*list); char *line; while ((line = in->getline()) != NULL) { if (!strncmp(line, "quit", 4)) { in->close(); continue; } for (out.rewind(); out.next(); ) { if (&out() != in && out->iswritable()) { static_cast(&out())->print( "%s> %s\n", in->src() ? (WvString)*in->src() : WvString("stdin"), line); if (localaddr) wvcon->print("Local address of source was %s\n", localaddr); } } } } static void accept_callback(WvIStreamList *list, IWvStream *_s) { WvStreamClone *s = new WvStreamClone(_s); s->setcallback(wv::bind(stream_bounce_to_list, s, list, ((WvUnixConn *)_s)->localaddr())); list->append(s, true, "WvUnixConn"); } int main(int argc, char **argv) { { WvLog log("testlisten"), err = log.split(WvLog::Error); WvIStreamList l; WvUnixListener sock(argc==2 ? argv[1] : "/tmp/fuzzy", 0777); wvin->setcallback(wv::bind(stream_bounce_to_list, wvin, &l, NULL)); sock.onaccept(wv::bind(accept_callback, &l, _1)); log("Listening on port %s\n", *sock.src()); l.append(&sock, false, "socket"); l.append(wvin, false, "wvin"); while (sock.isok() && wvin->isok()) { if (l.select(-1)) l.callback(); } if (!sock.isok() && sock.geterr()) err("%s\n", strerror(sock.geterr())); } // all variables should now be freed #if DEBUG fprintf(stderr, "File descriptors still open: "); bool found = false; for (int count = 0; count < 255; count++) { int dupfd = dup(count); if (dupfd >= 0) { fprintf(stderr, "#%d ", count); found = true; close(dupfd); } } if (!found) fprintf(stderr, "none.\n"); else fprintf(stderr, "\n"); #endif return 0; } wvstreams-4.6.1/ipstreams/tests/iptest.cc0000644000175000001440000000225411036722347017572 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * WvIPRawStream test. Waits for data. */ #include #include "wvistreamlist.h" #include "wvlog.h" #include "wvipraw.h" int main(int argc, char **argv) { WvLog err("iptest", WvLog::Error); WvIPAddr nothing; WvIPAddr remaddr(argc > 1 ? argv[1] : "127.0.0.1"); WvIPRawStream sock(nothing, remaddr, IPPROTO_ESP); sock.enable_broadcasts(); err(WvLog::Info, "Local address is %s.\n", *sock.local()); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; } wvstreams-4.6.1/ipstreams/tests/simpleconntest.cc0000644000175000001440000000615411036722347021334 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * simpleconn is a very simple program that forwards data between an * arbitrary set of given files (which are usually devices, named pipes, * etc). If a file is named '-', it refers to stdin/stdout. */ #include "wvfile.h" #include "wvistreamlist.h" #include "wvtcplistener.h" #include "wvtcp.h" #include "wvlog.h" #include static void bouncer(WvStream *input, WvIStreamList *list) { WvIStreamList::Iter i(*list); char buf[1024]; size_t len; if (!input->select(0, true, false, false)) return; len = input->read(buf, sizeof(buf)); if (!len) return; for (i.rewind(); i.next(); ) { IWvStream &out = i(); if (input == &out) continue; if (!out.isok()) continue; //delay_output wasn't really useful, and isn't in IWvStream //out.delay_output(true); out.write(buf, len); } } static void accept_callback(WvIStreamList *list, IWvStream *_conn) { WvStreamClone *conn = new WvStreamClone(_conn); conn->setcallback(wv::bind(bouncer, conn, list)); list->append(conn, true, "WvTCPConn"); } int main(int argc, char **argv) { WvIStreamList biglist, l; int count; char *cptr; WvLog log("simpleconn", WvLog::Info); signal( SIGPIPE, SIG_IGN ); if (argc < 2) { fprintf(stderr, "Usage: %s file [file...]\n" " Passes data between the given files/devices/etc. " "If a filename is\n" " '-', it refers to stdin/stdout.\n", argv[0]); return 1; } biglist.append(&l, false, "list"); for (count = 1; count < argc; count++) { WvStream *f; if (!strcmp(argv[count], "-")) { log("File %s is stdin/stdout\n", count); f = wvcon; l.append(f, false, "wvcon"); f->setcallback(wv::bind(bouncer, f, &l)); } else if (!strncasecmp(argv[count], "tcp:", 4)) { // TCP connection of some kind cptr = argv[count] + 4; if (strchr(cptr, ':')) // an additional colon? client mode. { log("File %s is a TCP client\n", count); f = new WvTCPConn(WvIPPortAddr(cptr)); l.append(f, true, "TCP client"); f->setcallback(wv::bind(bouncer, f, &l)); } else // server mode { log("File %s is a TCP server\n", count); WvTCPListener *listen = new WvTCPListener(WvIPPortAddr("", atoi(cptr))); listen->onaccept(wv::bind(accept_callback, &l, _1)); biglist.append(listen, true, "TCP server"); } } else { log("File %s is a file (%s)\n", count, argv[count]); f = new WvFile(argv[count], O_RDWR); if (!f->isok()) { WVRELEASE(f); f = new WvFile(argv[count], O_RDONLY); if (!f->isok()) { fprintf(stderr, "%s: %s\n", argv[count], f->errstr().cstr()); return 1; } } l.append(f, true, "file"); f->setcallback(wv::bind(bouncer, f, &l)); } } // continue as long as there is more than one open client, or a server while (l.count() >= 2 || (biglist.count() - 1 >= 1 && l.count() >= 1)) { if (biglist.select(1000)) biglist.callback(); } return 0; } wvstreams-4.6.1/ipstreams/tests/urltest.cc0000644000175000001440000000177711077124114017766 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * URL parsing test. */ #include "wvurl.h" #include "wvstream.h" const char *urls[] = { "http://www.test.test", "http://www.test.test:100", "http://www.test.test:80", "sip://www.test.test", "sip://www.test.test:80", "sip:www.test.test", "test of a bad proto", "test://www.test.test:100", "http", "http: but no slashes", "ftp://ftp.test.test", "ftp://monkey@ftp.test.test", "ftp://monkey:banana@ftp.test.test/file", NULL }; int main() { const char **s; for (s = urls; *s != NULL; s++) { WvUrl url(*s); WvUrl url2(url); wvcon->print("%s -> %s\n", *s, url2); wvcon->print("proto: %s, host: %s, port:%s, file: %s, user: %s, password: %s\n", url2.getproto(), url2.gethost(), url2.getport(), url2.getfile(), url2.getuser(), url2.getpassword()); wvcon->print("\n"); } } wvstreams-4.6.1/ipstreams/tests/xplctest.cc0000644000175000001440000000306211077364544020134 0ustar wlachusers#include "wvxplc.h" #include #include #include #include #include #include class Hello : public IObject { IMPLEMENT_IOBJECT(Hello); public: Hello() { printf("Hello!\n"); } virtual ~Hello() { printf("Goodbye!\n"); } }; UUID_MAP_BEGIN(Hello) UUID_MAP_ENTRY(IObject) UUID_MAP_END class HelloFactory : public IMoniker { IMPLEMENT_IOBJECT(HelloFactory); public: virtual IObject *resolve(const char *s) { return new Hello; } virtual ~HelloFactory() {} }; UUID_MAP_BEGIN(HelloFactory) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IMoniker) UUID_MAP_END static const UUID _hellouuid = {0x414a69c6, 0x3c9e, 0x49f7, {0xab, 0x08, 0xe5, 0x5c, 0x7b, 0x6c, 0x23, 0x99}}; int main() { fprintf(stderr, "Starting...\n"); XPLC xplc; IServiceManager *servmgr = XPLC_getServiceManager(); assert(servmgr); IStaticServiceHandler *handler = mutate( servmgr->getObject(XPLC_staticServiceHandler)); assert(handler); handler->addObject(_hellouuid, new HelloFactory); IMonikerService *monikers = mutate( servmgr->getObject(XPLC_monikers)); assert(monikers); monikers->registerObject("hello", _hellouuid); fprintf(stderr, "About to create...\n"); IObject *obj = xplc.create("hello:"); assert(obj); WVRELEASE(obj); fprintf(stderr, "Done.\n"); return 0; } wvstreams-4.6.1/ipstreams/tests/contseltest.cc0000644000175000001440000000336611036722347020636 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStream test using the new WvTask support. This is in ipstreams * because there are more fun and stressful streams to test here. */ #include "wvtcplistener.h" #include "wvistreamlist.h" #include "wvlog.h" #include "strutils.h" #include "wvcont.h" #include "wvstreamclone.h" static void *stream_call(WvStream& s) { char *line; static int sc_count = 0; int mynum = ++sc_count, count = 0; WvLog log(WvString("log%s", mynum), WvLog::Info); while (s.isok()) { if ((line = s.getline()) != NULL) { line = trim_string(line); s.print("%s/%s: You said: '%s'\n", mynum, count, line); log("#%s: You said: '%s'\n", count, line); } else { log("#%s: Tick.\n", count); s.print("!"); } count++; s.continue_select(100*mynum); } return 0; } static void setupcont_call(WvIStreamList *list, IWvStream *_conn) { WvStreamClone *conn = new WvStreamClone(_conn); conn->setcallback(WvCont(wv::bind(&stream_call, wv::ref(*conn)))); list->append(conn, true, "WvTCPConn"); } int main() { WvLog log("conttest"), err = log.split(WvLog::Error); WvIStreamList l; WvTCPListener listen(WvIPPortAddr("0.0.0.0:1129")); listen.onaccept(wv::bind(setupcont_call, &l, _1)); wvcon->setcallback(WvCont(wv::bind(&stream_call, wv::ref(*wvcon)))); log("Listening on port %s\n", *listen.src()); l.append(&listen, false, "listener"); l.append(wvcon, false, "wvcon"); while (listen.isok() && wvcon->isok()) { log("main loop\n"); if (l.select(10000)) l.callback(); } if (!listen.isok() && listen.geterr()) err("%s\n", listen.errstr()); return 0; } wvstreams-4.6.1/ipstreams/tests/tcptest.cc0000644000175000001440000000167511036722347017756 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTCPConn test. Telnets to your local SMTP port, or any other port given * on the command line. */ #include "wvtcp.h" #include "wvistreamlist.h" #include "wvlog.h" int main(int argc, char **argv) { WvLog err("tcptest", WvLog::Error); err(WvLog::Debug1, "tcptest starting.\n"); WvTCPConn sock(WvString(argc==2 ? argv[1] : "127.0.0.1:25")); wvcon->autoforward(sock); sock.autoforward(*wvcon); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); while (wvcon->isok() && sock.isok()) { if (l.select(-1)) l.callback(); } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", wvcon->errstr()); if (!sock.isok() && sock.geterr()) err("socket: %s\n", sock.errstr()); err(WvLog::Debug1, "tcptest exiting.\n"); return 0; } wvstreams-4.6.1/ipstreams/tests/udptest.cc0000644000175000001440000000232111036722347017745 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvUDPStream test. Waits for data on port 19. */ #include "wvistreamlist.h" #include "wvlog.h" #include "wvudp.h" int main(int argc, char **argv) { WvLog err("udptest", WvLog::Error); WvIPPortAddr nothing; WvIPPortAddr remaddr(argc > 1 ? argv[1] : "127.0.0.1:19"); WvUDPStream sock(nothing, nothing); sock.enable_broadcasts(); err(WvLog::Info, " Local address is %s.\n", *sock.local()); err(WvLog::Info, "Remote address is %s.\n", remaddr); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; } wvstreams-4.6.1/ipstreams/wvresolver.cc0000644000175000001440000001717011036722347017341 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * DNS name resolver with support for background lookups. */ #include "wvresolver.h" #include "wvloopback.h" #include "wvaddr.h" #include "wvtcp.h" #include #include #include #ifdef _WIN32 #define WVRESOLVER_SKIP_FORK typedef int pid_t; #define kill(a,b) #define waitpid(a,b,c) (0) #define alarm(a) #include "streams.h" #else #include "wvautoconf.h" #include "wvfork.h" #include #include #endif class WvResolverHost { public: WvString name; WvIPAddr *addr; WvIPAddrList addrlist; bool done, negative; pid_t pid; WvLoopback *loop; time_t last_tried; WvResolverHost(WvStringParm _name) : name(_name) { init(); addr = NULL; } ~WvResolverHost() { WVRELEASE(loop); #ifndef WVRESOLVER_SKIP_FORK if (pid && pid != -1) { kill(pid, SIGKILL); pid_t rv; // In case a signal is in the process of being delivered... while ((rv = waitpid(pid, NULL, 0)) != pid) if (rv == -1 && errno != EINTR) break; } #endif } protected: WvResolverHost() { init(); } void init() { done = negative = false; pid = 0; loop = NULL; last_tried = time(NULL); } }; class WvResolverAddr : public WvResolverHost { public: WvResolverAddr(WvIPAddr *_addr) { addr = _addr; } }; // static members of WvResolver int WvResolver::numresolvers = 0; WvResolverHostDict *WvResolver::hostmap = NULL; WvResolverAddrDict *WvResolver::addrmap = NULL; // function that runs in a child task static void namelookup(const char *name, WvLoopback *loop) { struct hostent *he; // wait up to one minute... alarm(60); for (int count = 0; count < 10; count++) { he = gethostbyname(name); if (he) { char **addr = he->h_addr_list; while (*addr != NULL) { loop->print("%s ", WvIPAddr((unsigned char *)(*addr))); addr++; } loop->print("\n"); alarm(0); return; } // not found (yet?) if (h_errno != TRY_AGAIN) { alarm(0); return; // not found; blank output } // avoid spinning in a tight loop. // // sleep() is documented to possibly mess with the alarm(), so we // have to make sure to reset the alarm here. That's a shame, // because otherwise it would timeout nicely after 60 seconds // overall, not 60 seconds per request. sleep(1); alarm(60); } } WvResolver::WvResolver() { numresolvers++; if (!hostmap) hostmap = new WvResolverHostDict(10); if (!addrmap) addrmap = new WvResolverAddrDict(10); } WvResolver::~WvResolver() { numresolvers--; if (numresolvers <= 0 && hostmap && addrmap) { delete hostmap; delete addrmap; hostmap = NULL; addrmap = NULL; } } // returns >0 on success, 0 on not found, -1 on timeout // If addr==NULL, this just tests to see if the name exists. int WvResolver::findaddr(int msec_timeout, WvStringParm name, WvIPAddr const **addr, WvIPAddrList *addrlist) { WvResolverHost *host; time_t now = time(NULL); int res = 0; host = (*hostmap)[name]; if (host) { // refresh successes after 5 minutes, retry failures every 1 minute if ((host->done && host->last_tried + 60*5 < now) || (!host->done && host->last_tried + 60 < now)) { // expired from the cache. Force a repeat lookup below... hostmap->remove(host); host = NULL; } else if (host->done) { // entry exists, is marked done, and hasn't expired yet. Return // the cached value. if (addr) *addr = host->addr; if (addrlist) { WvIPAddrList::Iter i(host->addrlist); for (i.rewind(); i.next(); ) { addrlist->append(i.ptr(), false); res++; } } else res = 1; return res; } else if (host->negative) { // the entry is in the cache, but the response was negative: // the name doesn't exist. return 0; } // if we get here, 'host' either exists (still in progress) // or is NULL (need to start again). } if (!host) { // nothing matches this hostname in the cache. Create a new entry, // and start a new lookup. host = new WvResolverHost(name); hostmap->add(host, true); host->loop = new WvLoopback(); #ifdef WVRESOLVER_SKIP_FORK // background name resolution doesn't work when debugging with gdb! namelookup(name, host->loop); #else // fork a subprocess so we don't block while doing the DNS lookup. // close everything but host->loop in the subprocess. host->pid = wvfork(host->loop->getrfd(), host->loop->getwfd()); if (!host->pid) { // child process host->loop->noread(); namelookup(name, host->loop); _exit(1); } #endif // parent process host->loop->nowrite(); } #ifndef WVRESOLVER_SKIP_FORK // if we get here, we are the parent task waiting for the child. do { if (waitpid(host->pid, NULL, WNOHANG) == host->pid) host->pid = 0; if (!host->loop->select(msec_timeout < 0 ? 100 : msec_timeout, true, false)) { if (host->pid) { if (msec_timeout >= 0) return -1; // timeout, but still trying } else { // the child is dead. Clean up our stream, too. WVRELEASE(host->loop); host->loop = NULL; host->negative = true; return 0; // exited while doing search } } else break; } while (host->pid && msec_timeout < 0); // repeat if unlimited timeout! #endif // data coming in! char *line; do { line = host->loop->blocking_getline(-1); } while (!line && host->loop->isok()); if (line && line[0] != 0) { res = 1; WvIPAddr *resolvedaddr; char *p; p = strtok(line, " \n"); resolvedaddr = new WvIPAddr(p); host->addr = resolvedaddr; host->addrlist.append(resolvedaddr, true); if (addr) *addr = host->addr; if (addrlist) addrlist->append(host->addr, false); do { p = strtok(NULL, " \n"); if (p) { res++; resolvedaddr = new WvIPAddr(p); host->addrlist.append(resolvedaddr, true); if (addrlist) addrlist->append(resolvedaddr, false); } } while (p); host->done = true; } else host->negative = true; if (host->pid && waitpid(host->pid, NULL, 0) == host->pid) host->pid = 0; WVRELEASE(host->loop); host->loop = NULL; // Return as many addresses as we find. return host->negative ? 0 : res; } void WvResolver::clearhost(WvStringParm hostname) { WvResolverHost *host = (*hostmap)[hostname]; if (host) hostmap->remove(host); } void WvResolver::pre_select(WvStringParm hostname, WvStream::SelectInfo &si) { WvResolverHost *host = (*hostmap)[hostname]; if (host) { if (host->loop) host->loop->xpre_select(si, WvStream::SelectRequest(true, false, false)); else si.msec_timeout = 0; // already ready } } bool WvResolver::post_select(WvStringParm hostname, WvStream::SelectInfo &si) { WvResolverHost *host = (*hostmap)[hostname]; if (host) { if (host->loop) return host->loop->xpost_select(si, WvStream::SelectRequest(true, false, false)); else return true; // already ready } return false; } wvstreams-4.6.1/ipstreams/t/0000755000175000001440000000000011260431126015040 5ustar wlachuserswvstreams-4.6.1/ipstreams/t/wvunixsocket.t.cc0000644000175000001440000000265311077124114020372 0ustar wlachusers#include "wvtest.h" #include "wvtimeutils.h" #include "wvunixsocket.h" #include "wvunixlistener.h" #include "wvstring.h" #include #include #include #include #include #include WVTEST_MAIN("non-blocking connect BUGZID:10714") { WvString uds("/tmp/wvtest.wvunixsocket.%s", getpid()); pid_t pid = fork(); if (pid == 0) { // child: server // // Create listening socket but do not accept connections WvUnixListener l(uds, 0600); wverr->print("Server: intentially hanging\n"); pause(); } else if (pid > 0) { // parent: client struct stat st; while (stat(uds, &st) != 0) { wverr->print("Client: waiting for %s to appear\n", uds); wvdelay(100); } wverr->print("Client: connect()ing many times\n"); int i; for (i=0; i<200; ++i) WvUnixConn s(uds); wverr->print("WvUnixConn::WvUnixConn doesn't hang when executing many " "times"); wvdelay(100); kill(pid, SIGTERM); // In case a signal is in the process of being delivered... pid_t rv; while ((rv = waitpid(pid, NULL, 0)) != pid) if (rv == -1 && errno != EINTR) break; WVPASSEQ(rv, pid); } else WVFAIL("fork() failed"); unlink(uds); } wvstreams-4.6.1/ipstreams/t/wvlistener.t.cc0000644000175000001440000000207511077124114020021 0ustar wlachusers#include "wvlistener.h" #include "wvtest.h" #include "wvtcp.h" #include "wvtcplistener.h" #include "wvistreamlist.h" class XListener : public WvListener { public: WvTCPListener *l; XListener(const WvIPPortAddr &_listenport) : WvListener(l = new WvTCPListener(_listenport)) { } IWvStream *accept() { return l->accept(); } }; static IWvStream *mystream; static void acceptor(IWvStream *s) { mystream = s; } WVTEST_MAIN("wvlistener") { XListener l(""); const WvAddr *listenport = l.src(); printf("Listening on %s\n", ((WvString)*listenport).cstr()); l.onaccept(acceptor); WvIStreamList::globallist.append(&l, false, "tcp listener"); WvTCPConn tcp(*listenport); WvIStreamList::globallist.append(&tcp, false, "tcp connection"); while (tcp.isok() && !mystream) WvIStreamList::globallist.runonce(-1); WVPASS(tcp.isok()); WVPASS(mystream); if (mystream) { WVPASS(mystream->isok()); mystream->write("text!\n", 6); WVPASSEQ(tcp.getline(-1), "text!"); delete mystream; } } wvstreams-4.6.1/ipstreams/t/wvtcp.t.cc0000644000175000001440000000501211036722347016763 0ustar wlachusers#include "wvtcp.h" #include "wvtcplistener.h" #include "wvtest.h" #include WVTEST_MAIN("tcp connection") { WvTCPListener listen("0.0.0.0:0"); WVPASS(listen.isok()); WvIPPortAddr port(*listen.src()); //wvcon->print("Local port is '%s'\n", port); WvTCPConn tcp(port); WVPASS(1); tcp.write("foo\n"); WVPASS(2); listen.runonce(0); WVPASS(3); tcp.runonce(0); WVPASS(4); tcp.runonce(0); WVPASS(5); tcp.runonce(0); tcp.runonce(0); WVPASS(6); listen.runonce(100); WVPASS(7); IWvStream *_in = listen.accept(); WVPASS(8); WVPASS(_in); if (!_in) return; // forget it... WVPASS(_in->isok()); WvStreamClone in(_in); WVPASS(in.isok()); tcp.runonce(100); tcp.runonce(100); tcp.runonce(100); WVPASS(in.isreadable()); WvString line = in.blocking_getline(100); WVPASSEQ(line, "foo"); } WVTEST_MAIN("connection refused 1") { // hopefully nobody has a service here. If we get connection refused as // expected, this test should *not* time out. But a bug that happened // at least once in WvTCPConn causes a timeout in this test. WvTCPConn tcp(WvString("0.0.0.0:105")); printf("ok: %d\n", tcp.isok()); tcp.runonce(-1); printf("ok: %d\n", tcp.isok()); tcp.runonce(-1); printf("ok: %d\n", tcp.isok()); tcp.runonce(-1); printf("ok: %d\n", tcp.isok()); WVFAIL(tcp.isok()); } WVTEST_MAIN("connection refused 2") { char buf[1024]; size_t len; WvTCPListener listen("0.0.0.0:0"); WVPASS(listen.isok()); WvIPPortAddr port(*listen.src()); // WvIPPortAddr port("127.0.0.1:11223"); // WvIPPortAddr port("192.168.12.100:11223"); //wvcon->print("Local port is '%s'\n", port); listen.close(); listen.runonce(0); WVFAIL(listen.isok()); WVPASSEQ(listen.geterr(), 0); WvTCPConn tcp(port); tcp.runonce(10000); tcp.runonce(10000); tcp.runonce(10000); tcp.runonce(10000); WVPASS(tcp.isconnected()); // even if error, we're past connection phase WVFAIL(tcp.isok()); WVPASSEQ(tcp.geterr(), ECONNREFUSED); printf("Error string is '%s'\n", tcp.errstr().cstr()); len = tcp.read(buf, sizeof(buf)); WVPASSEQ(len, 0); WVFAIL(tcp.isok()); WVPASSEQ(tcp.geterr(), ECONNREFUSED); printf("Error string is '%s'\n", tcp.errstr().cstr()); tcp.write("foo\n"); WVFAIL(tcp.isok()); WVPASSEQ(tcp.geterr(), ECONNREFUSED); printf("Error string is '%s'\n", tcp.errstr().cstr()); } wvstreams-4.6.1/ipstreams/t/wvunixdgsocket.t.cc0000644000175000001440000003265511036722347020721 0ustar wlachusers#include "wvtest.h" #include "wvunixdgsocket.h" #include "wvhex.h" WVTEST_MAIN("embarrassingly simple unixdgsockets test") { int fd; WvString testfile = "/tmp/wvunixdgtestXXXXXX"; if ((fd = mkstemp(testfile.edit())) == (-1)) return; close(fd); WvUnixDGListener in(testfile); WvUnixDGConn out(testfile); WVPASS(out.iswritable()); WvString t("test"); out.write(t); WVPASS(in.isreadable()); WvDynBuf b; unsigned int len = in.read(b, t.len()); WVPASS(len == t.len()); WVPASS(t == b.getstr(t.len())); } WVTEST_MAIN("fire random binary data through unixdgsocket") { // autofoward works in 1024 byte long chunks so use a stupidly long string // of sample data to be extra sure. WvString tstdata = "87abfa498c441b081a0ee95c786d0add68dfd1e5453d92a3f8f32767e3cb" "1907817b5c35b306e6e5876b31a35e46719d7eba83e3dab8740135b57a7b" "1ac68bb8277902803e43ca6c3b98b21c1747a4da9032985bac9398506f78" "c586f8e434a50b3640b51d956a33a6fb0308c3defc500c67342bd93ea6da" "95a134a310ee343fff46cbfc72341829ba4d9a0c0c239df711a96c2ba3f2" "33b0b727786fa5c24f35214fc96cc23b6ed4b88578324e97745575824199" "8ae655d8f207e138643b2c846afcabd865fad8a1d97a1d4f44969ac4a863" "c29cf752104d52e6837c2f066ba987ec52d5c8292d5a80540d8100c844ac" "371a21b3f8072397a876e3a31d78706382a7cf78cefb97ba676cf3fea222" "b44fba80dd9bd58fd68da933cfcbc21c542914f17d8d995c65517aa99a07" "37a1c2b95a6d6d8bef080e13367a9193ab63c3ba4c3831df5ec75b45366f" "c7c3fcced401b5d1513495bae1f73d8e2760860518e0d6d60d1629d55abc" "946c6040650b846af72fdc70280fc1c86a452a8dbbe283d153c2b3f5dd45" "b5ae91d1047151314159ebc6b7b1dc4499b8b9558ac723ded8a1286f06eb" "f9f5b9ab3db6867d6086af51a1438761c4015982f993cc87c47b5230b8cc" "1caf13f86349f8a7ada39648942ed4f43f08f6b491471990567742295ec8" "c3961495ce7c4dbbf06f4da86561f742154fdebfe75bda99b027ffc4e1c9" "47d9fb5fe37f96a8b7263ab7a3058b8223bfa43d4724b138f30c01407d86" "c29845c5408208756133afb5711ae573249315f5812979d2e6e96e8d081d" "4e886da36ce0e6287ce9f2439a24acb3c7a9874fa5bf1783a1545de9fe53" "476cd14f0497e3e5a28b3e1fa0c547596553625f514cbd19a7e725769cdf" "e4a553719729efd37e164f188d5c24b4fff37f68351e54a5bfc8d783839c" "43f34b40552ec5fdcd233027b18129e6e0977cd32ab1044a9a5214d49c90" "08b0a2966502f14fbc14c53b9d58bb4b20d7e3ec41dd30e74d1d46eb8fb5" "f2d9afa721bed40910529a50d6215263851b8c15ec97d3f49cf5c231f04e" "7a9691d7f5257e101f89672994358b9c4fc3126a79df964d60aa30e45245" "919c08d6144e447fc80bac951e8051051845f3ad99cf890ad866496e692e" "b34d3c021729323fed3664ce2d66827682dbc4abe01d9973ba499862945a" "a0185bd5481908cf09a440cda8df9f80ddd24a0ebf899c4926b7bafdd05e" "8cf36f91605223411f32478cea6b1a4cce317a46a66dd5e5b499e747c332" "2788fe8bfed7d225973dbed6b98039fe16e51f1c2aecc538227bb2526dba" "f0cd9976a750e943bd0ccf8d63cc5baf1bcae9489e0baa92e3a1cd2ce817" "3688808303812d888c4be2fc994d619b267cbca6e8fe9d243600fa5ebd1c" "323f10088a4f78320571b6c0716846db26e1c28b6a16cb7dfcf9a243bca4" "d493acdd02784409ce6c4622ce605a831d57cd8fcc1ca27dfd646d8cfdba" "1474e355b43166ad9d3baaa5110c9e627640df40cc6e85581e58c133babc" "1bd6d28413d3e1095d2d481e405c8bf75fbb02fb4733ec2d93d348250fe5" "7e764a5e4fe8439b49effa0a6ecb05332e15696b5bb984bc04d1a2683712" "ce8bed95bd59c23aeb25d5ea51e0e471c7c8af4f9c7d7ebe14a9e3aead6e" "924a38eddfa8668bb706e173f7c833058edbe585be8b653f323c138aed73" "64b6ce9c7b24a65a657287c52dd20d03ef147335bd5b800bbce74157e6db" "e1cf4fdff7daa084bcc9e1b2b7fd9d85572644869909cefe28656b8a1fc3" "98c072260624e3c3c25cb4574b498055ba02da7ea3166d4f1e52ba46ba65" "155dd4e89a217ae0494090bf9fd7085effc67a997009f3a3480442277f66" "cc10d03f8988a5d656ac0ea63d2b112ceee0a2ac8af1f4708aa81b1d09bd" "55bbbaf1b2caf26ad2bc1f8b53cd22adf10536f3e94dfe30eba856e2a0fb" "6069d7bf90df338acd42868e2a4bc6406c7e0630f83ddfd13bdac07f2d36" "f82064d8b7fac17086257ef4efe926d94fced9af43dcd03d08bf3b6fccef" "20073ee54f2c9604b2bcf7f8027f8290826456d17166c3817fc143d122d9" "81fc22754f3289eae12473083b8ab33c0abe70ffd2b8b68f749cfdcaf2e8" "c5ef8fc9cb21ae8e7ed40b84c2d88ddbda381747250e7712a7c5390f702a" "e82a822149c6c343db7d48a5fe46a0af08c523239fa9ea57d6e1a897bf70" "e35ac84cb5590e97b4005609a51339fd8c98081eb925d17063ad85475ce1" "515d46d5dd3a914417694305d877a520fd9551f33109a79cde26b8fdc3e3" "2b64fe32ffd0284777d36fc312fb495b96a05a744c81b5c74de379f7e73b" "da6a5ec69226747be0e030563385ad216daeb71a9244c4e69783b6e242bc" "266ffc89a8e73a54f7d3ac8b400f91842dafaab93d46330bfeab8cac328b" "07cbe2ffd0c9bae070b3c065c06e14cbeb9efcdaf4718f189999b89ff20d" "ba46dd3987edde47c122dffa01f6c164c388acb98c1ef6bf2f7874f729f0" "4e38a43a54d9533536364fc1b620436a858aae56b1890006d402d223184e" "9c9798a4ff29bc3473bd27ecb8a91b9a108fd17ddce1c51550f6cb5e9a83" "0c3a4e0ae4e2aee8933017e2c679eaf614a48ab4f5310980d2926e4457d0" "ab15bfe7e9a88038be1b803bf74d42235b2b908b4ebacabb71716e676124" "5299e6d201e9029862418a96aadd8ca1e5706383d44c21428fc4a392b23f" "91439f88764b51f020a6a7aa1370b888e1521cbe0f0e8a0ad0c03c7945b0" "3c0e0731cff586cd24b8cbb9f0c778e7e338fe224bd35b7edd2632826f4f" "b78a9e80780ee7618308a4d6d557372b9e6e0c551aa3b9276dd085346330" "8a9c3e3f8b686d32997a5cc1c6d842b11704322295d9548460f9f1111b3a" "209095fcc47f97c371c2d52edb98b88d37bc6cf5fa16f0f04a69f08cdda6" "0360b38bc7316764b9574dc2429910aa8c9426f624c07cca9e813f1cddee" "0ec1334b8aa89a6644e37e05f223e216d28bd195e87be478eab294c58b50" "991072a7b8559255c03bb1815920058d750577c39a9eff7ffa124a6925a3" "eba11637eafc5e41e2083d73523bac0e213961f5c90d1603f65752a1bbe2" "c4429e778245ceb2f215488a6ec7fae9d2244a5582eb1e7f99363d3193ec" "fd738aca11679dff1cb998d964bd11aaaba049cf3e8275fa45f8a9962124" "a352d0d1d0b38269715a4879d42269bc83c523cd28b964916c858aa998f5" "679c176b1776861977d91e1914b241bdcc72971e8491c4408c2dedfc0aad" "99f29d0deaec8cc4d22c861db52731b47479c3bb48b8dad15eed7aacaf7b" "a90edb6ac31ee4fadd065f0f02de1a5d74e80278affb89cb66c0a1e0e2e5" "bc5744e129593b8aa92956f5a79ee98b81e95605b13bcdc4bfc8e7a0b2a0" "b4f47351b23628f42d41ba7b3689fad660181cf5a54e634ae4001818b324" "088e66b21da1109c27ebc1d15b64c330e8c8ee5669b8b5dcf0a072a927b2" "0f969a62d4feabe0e7139c8da57a327f88503462f45d57afccad4c8aa92f" "3a29ab58afdf03e8a226ab46bd0a20587a70544f8c4dcc82fbd29413809d" "4fbb04c7b10e8f7010e065750fb9fdbd42dcb077b09af5cff6b55ef48a11" "15eb9ab3fad2d6b8d3c42929db40b2ff5431c95295dbb3cc658f0aae81c8" "dedaf354a9c1256576334f887c4405b2e2a16d24523c7310d1d6e1883165" "b5cb92948b86676e06967c6f337925d579e62a92a863478fd2c41248a7ec" "cf76013402a4c5643effb7675be4b1005512617cab15f67c67e0b925ce35" "d57239a72a0fd24476eb326a05126e1753ed0c2dca1f128aff76e508def0" "c206e0d20bc337accee8bdfde7c435cd3b3164afc5f4051ebb48f86794ea" "a171269f55d524611bd76e0d0c4f21214779a621ade3c0b66d5112731fbc" "0a74a8bf4568504fab6bb1d47bd85c76d09dec0f4f63b0cd040b5c981728" "c49292bc5cb4537185a99f0aeaedf87138ddf72ad621d7d18229a5603d14" "ede2d602951c98dd996d7ed87bc636ad477f6327f30d184cba7e05b04069" "dd8069516a23202b628b5f67aa662b8b040673c0a97507ee24185c1fceed" "0ac77f097bb6f87f555885c054df13ca3e5d172257bd2505e32aed5098f9" "b841f722832f0ea8bb53a2b805d93c4e6a7adb6f9b7e1258bfd139026548" "c3ae867b82d569fa8da6b9968ba36c0038c27f488073c09d062fadf78f23" "755281911f60a6714d4d9bcaed08c03b6001772cf4c8cb678ea82f81364d" "eb6c790e58a4b40b795103118bd541108a3fe04c829391afd0570025e0de" "d2d5024669028fc99b7860a10f3177c3650091ee198f84c8a911115dda8f" "8a2282cbd7e78399fb9744ff06d585a2486805790629aca772e8ee30107e" "396be551c4625fffd64436c88f70e25685baf5a1459ebeb69405216662ef" "53524fe633a2ef43172c6ca66d9a8dfcf37aed42ce232ff08bb62984fb8c" "a94cbdc8518a4df96e127f4335338143df9bdbea4e8422a9cd3fb1637f38" "db37edf26d891b8b00ed99c8bb74ed95105616154df117d0df6f71ae1b32" "9f8c0871a559478160845143d710bbdf12e489cfa694bcc4e0719890415c" "9ad1cab875179aaeede6a6fc3b8eed3e2da7f025110d80667a5c00a5025a" "058a4932f5395cca1317d4ae496c59facaf914a30667363146efbb6ec5f5" "8fbceb958d0f717b206c8a54609e8e3b8b5f242bc6b0b18f7cdbfb055d40" "c0198e49d35abf2a2a63ce573236b3b85125830b175498be2ab02e8de4ed" "833e872e8f35c124601e8c90abbfb5cf0521d2e2ffd326e4b58d30a57a00" "33e7a6e43066060b63ae0f43a0fc486ea332c5015789a67c629943872059" "bdd571851ce15dcc8cc28bd251147a129e72c3973203251504601f272b1b" "486667b2629861d89771680f0ffd4e27e4961ce84db93568f8b3bb6aa702" "e29a6d0ea6eebdf2b347786d83689003a87418f555f9b06452f3d9e37138" "c9ee0033917154b9e667e065339d9d82375e57601aea5e113b6971c3b7ef" "33a8e42af5c6462e4034e2c8647b628f7fd29ae0e8683338da92a1cf2e1a" "0e7e2f594921d9ca419ed0749d3d357dc7aab8bd0393c8c72f0b3f541bd8" "783b6cbb98e6444c217297e810cef4da9063f1892dae8ea1be5b36169439" "b0803f74030e6635a5cc98ac5bd3a94c940417c86b5335496508d35f53b7" "9b723d4d073092bc7f086c24343f30efcabe0bd915bea8ec35b2856eb72e" "805c38405902e0d271983b79bc8c964c13a89f6262d47aa9339132d97556" "c9508922ac9eb7651021240485ac0fd07f907b412e14fa81a5cb5b449376" "110e12857aa4f2f7b7ac30b422dcd7a8e6d7ddf5e4a2b99dd6b0a51c5257" "7874db37e14222b52a97753b75ae807ed4bb16b8e03348d2d7558c8c8f59" "3e78ccdd813ea7886ee926e2f853c23a5bd4af50055cec7317da2f76afca" "c0c68a6835f63b88a7971234d4ff0b4285d57a207074bd41991d0f8707cd" "eaa990860c540bad47cda6845c4615dc3ea2f8d9a923efcd214699b2d445" "d7b18081dbaf6bc3be759ae35084e36dc857e0481342f4cd18205655008e" "8f8cd404c476bc47c90d79818098e7a520369162f01efbcee636b8e3af83" "a786fd2bfafcffe0579662fb02d38b25a064677c37aa7f967a9ee2848f33" "a055dccdb05e16ecb6b2e75e171e1462746df8070faed5355d6c7393383d" "50f8abb3b1e4b975071131d3196456ebba5d69364d02fac56830f63b13a2" "d2f1ebed21590fc912e382f2f7d9843e56750e16f7e56564dfed027da35a" "eb31bfd729ab0ee11a511b2a0acb132f1c93d3480984d82c8d2eb9720abe" "a9ec68f92256685dbdc2b6728b488dda6252c04c2484a13ee06c16d8e8c5" "2cad0aa03a2e762a4451c543edd834f5a9f88c546ec2aed8d724396fe356" "4efe7301e31693f7059e4607a3bb8c7891351d47583048f73bc48f1a8b2a" "8211aca0d551389cab77781dd63409f0bbf03e4f8476c8079faa484f1d75" "e4270fbd93db0f4033b11483b84ddcc4a409b0a2aff4286b8f92311e21a1" "032fdc156febd943a9e7aacffc2e96cb0d26b6b7ac0bf77322913675b08d" "5e5de79da8dbb13ec4977339e42cc4ab6cafb0028b8406c3a9e4b867a04c" "4ccdd7e7accbc9ecfd9dc82ea11dcfb98bc0457eecd03aed3b8d54662bb4" "e2d5dee57c4b136447117511ff5375ecc777e4a02e893ccb1ccbaaa7c895" "848174e2335502de2e851986bebfc3c8dc73568aedd8854b11164b3d3fe7" "311ac19fe76e28402031b50e127ae015c7c9ee01eca7c8e67988febc7ab9" "7631086ed26d333737670db36b8f80ef139e751162ff3e19ed1f97b14ce6" "2d25c7dfad31850de5036df38f8f0f5132e3f1b2dad4da9f7a98174b531c" "c7e383a4b9bbf927e0e014111ee439dcd0453766fff1686de14992afd0cb" "1cb31686e5ded202119d85e6cf0f59f5accd00852eda2cdb5a19533a6d61" "75aa97d3d651feca7d5d271c624d5939b3e1107a7c469481354b7f50334f" "6ef6a1776900433f9d02c810c34bb0f9b5ef6629a03eb2c0006d78ac5e4f" "f304ab50f8fb6e3cce70359a225f17afb890cf2b275fc8788596991b14d7" "3cb297e17b3a28b440f57cc3c0c0a12468027b20770a1a87a1c1fb85a31c" "112260a8db240b7910873e4bcb0a604c94f0d55448382b99485b140c4549" "cac20a123ce4c967ac9c0c37547360277f9d3b16b6d99b9bd46e03aa6ab9" "cef2835b9ff1c84d13080009e74f17551673469a5b3faf5884556ed8a055" "f10a2ff7172f4e0860487cbdc6423b7d2cbcf6a118fbbc027ceb80a91e1b" "fa438cd9150f600d719a180e429f482f45f2b43fe303541b2c8d3d73eb58" "b59e1486a00b7769ba7ab427e911b7739abeb21d082491bbc61cba993ac5" "1ffc24b87f22c2ceb635c38111ee82098b99b931025945b33196d185f472" "8b6f7a6e8f8809c4fa9ba1bff917204749ceaa8907aa9f82ebda057c012d" "42f1e993a7bce23470abb65292a85b9d0b3e96b38d0116c8d2ce73805ba2" "cf63cb1fdf2117838e50c8ea2f3a991c3fefe57b893c3f0d02b87ececcbd" "a8151c1fad655a6832d2637fe3d3b7af21b19c07a8b3c03d87d37f8e360e" "2ffe2b7bcb627bf928e4e13721bfe13bfb53d73973dd2e7fcbf878251209" "f1c69295f3ef3cf918339d976a30631d3f46382455fc1be936bc8cfd4298" "f9ae5ebd052a6fd8e02c497fcf7bd106a45f63b23c20a3ed1eb4fb9bba18" "907a84d1ffbe64a93b4c09841e5cecafe7027c20"; int tstlen = tstdata.len() / 2; unsigned char outbuf[tstlen]; unhexify(outbuf, tstdata); int fd; WvString testfile = "/tmp/wvunixdgtestXXXXXX"; if ((fd = mkstemp(testfile.edit())) == (-1)) return; close(fd); WvUnixDGListener in(testfile); WvUnixDGConn out(testfile); WVPASS(out.iswritable()); out.write(outbuf, tstlen); // Is there something to read now? WVPASS(in.isreadable()); WvDynBuf b; int len = in.read(b, tstlen); WVPASS(len == tstlen); // walk through the buffers to make sure input matches output. const unsigned char* inbuf = b.get(tstlen); bool success = true; for (int i = 0; i < tstlen; i++) { if (inbuf[i] != outbuf[i]) { success = false; break; } } WVPASS(success); } wvstreams-4.6.1/ipstreams/wvipraw.cc0000644000175000001440000000515711036722347016624 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvIPRawStream can send and receive packets on a connectionless IP socket. * See wvipraw.h for details. */ #include "wvipraw.h" #include #include #ifdef ISDARWIN # define socklen_t int #endif WvIPRawStream::WvIPRawStream(const WvIPAddr &_local, const WvIPAddr &_rem, int ip_protocol) : localaddr(_local), remaddr(_rem) { int x = 1; setfd(socket(PF_INET, SOCK_RAW, ip_protocol)); if (getfd() < 0 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0) { seterr(errno); return; } set_close_on_exec(true); set_nonblock(true); struct sockaddr *sa = _local.sockaddr(); if (bind(getfd(), sa, _local.sockaddr_len())) { delete sa; seterr(errno); return; } delete sa; struct sockaddr_in nsa; socklen_t nsalen = sizeof(nsa); if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0) { seterr(errno); return; } localaddr = WvIPAddr((sockaddr*)&nsa); if (WvIPAddr(_rem) != WvIPAddr()) { struct sockaddr *sa = _rem.sockaddr(); if (connect(getfd(), sa, _rem.sockaddr_len())) { delete sa; seterr(errno); return; } delete sa; } } WvIPRawStream::~WvIPRawStream() { } const WvAddr *WvIPRawStream::src() const { return &remaddr; } const WvAddr *WvIPRawStream::local() const { return &localaddr; } size_t WvIPRawStream::uread(void *buf, size_t count) { if (!isok() || !buf || !count) return 0; struct sockaddr_in from; socklen_t fromlen = sizeof(from); int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen); if (in >= 0) remaddr = WvIPAddr((sockaddr *)&from); // errors in IP are ignored return in < 0 ? 0 : in; } size_t WvIPRawStream::uwrite(const void *buf, size_t count) { if (!isok() || !buf || !count) return 0; struct sockaddr *to = remaddr.sockaddr(); size_t tolen = remaddr.sockaddr_len(); int out; out = sendto(getfd(), buf, count, 0, to, tolen); if (out < 0 && errno == EACCES) // permission denied seterr(EACCES); free(to); // errors in UDP are ignored // pretend that the write always succeeds even if the kernel // complains since we don't want datagrams backing up in the // buffer and forming merged datagrams as a result return out < 0 ? 0 : out; } void WvIPRawStream::enable_broadcasts() { int value = 1; if (!isok()) return; setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); } wvstreams-4.6.1/ipstreams/wvlistener.cc0000644000175000001440000000430311044160724017311 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A base implementation for "listeners", streams that spawn other streams * from (presumably) incoming connections. */ #include "wvlistener.h" #include "wvistreamlist.h" #include "wvaddr.h" #include "wvmoniker.h" UUID_MAP_BEGIN(WvListener) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IWvStream) UUID_MAP_ENTRY(IWvListener) UUID_MAP_END IWvListener *IWvListener::create(WvString moniker, IObject *obj) { IWvListener *l = wvcreate(moniker, obj); if (!l) { l = new WvNullListener(); l->seterr_both(EINVAL, "Unknown moniker '%s'", moniker); } return l; } WvListener::WvListener(IWvStream *_cloned) { cloned = _cloned; wrapper = 0; } WvListener::~WvListener() { if (cloned) WVRELEASE(cloned); WvIStreamList::globallist.unlink(this); } static IWvStream *wrapper_runner(IWvListenerWrapper wrapper, IWvStream *s) { return wrapper(s); } void WvListener::addwrap(IWvListenerWrapper _wrapper) { // What the heck is this, you ask? // The idea is that we can support multiple layers of wrappers by // creating recursive callbacks. When we add a wrapper and one already // exists, we want to create a new one to essentially do newer(older(s)) // ...but only when it finally gets called. if (wrapper) wrapper = wv::bind(&wrapper_runner, _wrapper, _1); else wrapper = _wrapper; } void WvListener::callback() { if (acceptor) { IWvStream *s = accept(); if (s) acceptor(s); } } IWvStream *WvListener::wrap(IWvStream *s) { if (wrapper && s) return wrapper(s); else return s; } IWvListenerCallback WvListener::onaccept(IWvListenerCallback _cb) { IWvListenerCallback old = acceptor; acceptor = _cb; return old; } void WvListener::runonce(time_t msec_delay) { callback(); } static WvStringAddr nulladdr("ERROR", WvEncap::Unknown); const WvAddr *WvNullListener::src() const { return &nulladdr; } WvString WvListener::getattr(WvStringParm name) const { WvString ret = attrs.get(name); if (ret.isnull() && cloned) return cloned->getattr(name); return ret; } wvstreams-4.6.1/ipstreams/wvunixdgsocket.cc0000644000175000001440000000736011202637334020203 0ustar wlachusers#include "wvunixdgsocket.h" #ifdef MACOS #include #include #endif WvUnixDGSocket::WvUnixDGSocket(WvStringParm filename, bool _server, int perms) : socketfile(filename) { // log(WvLog::Debug2, "Starting up %s!\n", filename); server = _server; backoff = 10; bufsize = 0; // open a datagram unix domain socket setfd(socket(PF_UNIX, SOCK_DGRAM, 0)); // if we don't have a file desciptor, something is wrong. if (getfd() < 0) { seterr("No Socket available."); return; } // set non-blocking mode fcntl(getfd(), F_SETFL, O_RDWR|O_NONBLOCK); WvUnixAddr uaddr(socketfile); // Let this file be reusable, since we're going to own this anyway // The business with the int x is just Unix stupidities.. *sigh* int x = 1; setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (server) { // Fix it so that there can't be another process on this file unlink(socketfile); // Actually bind to the address we set up above. sockaddr *addr = uaddr.sockaddr(); if (bind(getfd(), (sockaddr *)addr, uaddr.sockaddr_len())) { seterr("Bind to %s failed: %s", socketfile, strerror(errno)); close(); } delete addr; chmod(socketfile, perms); } else { // we're the client, so we connect to someone else's socket sockaddr *addr = uaddr.sockaddr(); if (connect(getfd(), (sockaddr *)addr, uaddr.sockaddr_len())) { seterr("Connect to %s failed: %s", socketfile, strerror(errno)); close(); } delete addr; } drain(); } WvUnixDGSocket::~WvUnixDGSocket() { // log(WvLog::Debug2, "Destroying: %s\n", socketfile); close(); if (server) unlink(socketfile); } size_t WvUnixDGSocket::uwrite(const void *buf, size_t count) { size_t ret = bufs.isempty() ? WvFDStream::uwrite(buf, count) : 0; if (ret < count) { WvDynBuf *b = new WvDynBuf; b->put(buf, count); bufs.append(b, true); bufsize += count; } return count; } void WvUnixDGSocket::pre_select(SelectInfo &si) { SelectRequest oldwant = si.wants; if (!bufs.isempty()) { // stupid unix domain sockets seem to return true when selecting // for write EVEN IF write() RETURNS -EAGAIN! Just shoot me. // // To deal with this, we set an alarm() in post_select() if we // couldn't write everything we wanted. While the alarm is set, // we don't try to flush our output buffer. if (alarm_remaining() <= 0) si.wants.writable = true; else if (si.msec_timeout < 0 || si.msec_timeout > alarm_remaining()) si.msec_timeout = alarm_remaining(); } WvFDStream::pre_select(si); si.wants = oldwant; } bool WvUnixDGSocket::post_select(SelectInfo &si) { SelectRequest oldwant = si.wants; if (!bufs.isempty()) si.wants.writable = true; bool sure = WvFDStream::post_select(si); si.wants = oldwant; if (sure) { // try flushing previous bufs WvBufList::Iter i(bufs); for (i.rewind(); i.next(); ) { int used = i->used(); int retval = WvFDStream::uwrite(i->get(used), used); if (retval < used) { i->unget(used); alarm(backoff *= 2); if (backoff > 1000) backoff = 1000; break; // can't continue } else { bufsize -= used; i.xunlink(); // done with that one backoff = 10; } } } return sure; } wvstreams-4.6.1/ipstreams/wvstreamsdebuggerserver.cc0000644000175000001440000001204211077124114022074 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #include "wvstreamsdebuggerserver.h" #include "wvunixsocket.h" #include "wvtcplistener.h" #include "wvunixlistener.h" void WvStreamsDebuggerServer::Connection::choose_salt() { const int salt_size = 8; const int salt_alphabet_size = 26+26+10; const char salt_chars[salt_alphabet_size+1] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; salt.setsize(salt_size+1); for (int i=0; iset_wsname("wsd listener on %s", unix_addr); unix_listener->onaccept( wv::bind(&WvStreamsDebuggerServer::unix_listener_cb, this, _1)); unix_listener->setclosecallback( wv::bind(&WvStreamsDebuggerServer::unix_listener_close_cb, this)); streams.append(unix_listener, true, "debugger unix listener"); log("Listening on %s\n", unix_addr); } #endif if (tcp_addr != WvIPPortAddr()) { tcp_listener = new WvTCPListener(tcp_addr); tcp_listener->set_wsname("wsd listener on %s", tcp_addr); tcp_listener->onaccept( wv::bind(&WvStreamsDebuggerServer::tcp_listener_cb, this, _1)); tcp_listener->setclosecallback( wv::bind(&WvStreamsDebuggerServer::tcp_listener_close_cb, this)); streams.append(tcp_listener, true, "debugger tcp listener"); log("Listening on %s\n", tcp_addr); } } WvStreamsDebuggerServer::~WvStreamsDebuggerServer() { WvIStreamList::globallist.unlink(&streams); } #ifndef _WIN32 void WvStreamsDebuggerServer::unix_listener_cb(IWvStream *unix_conn) { log("Accepted connection from %s\n", *unix_conn->src()); Connection *conn = new Connection(unix_conn); conn->setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(*conn))); streams.append(conn, true, "debugger unix connection"); } void WvStreamsDebuggerServer::unix_listener_close_cb() { log("Listener on %s closing\n", *unix_listener->src()); } #endif void WvStreamsDebuggerServer::tcp_listener_cb(IWvStream *tcp_conn) { log("Accepted connection from %s\n", *tcp_conn->src()); Connection *conn = new Connection(tcp_conn); conn->setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(*conn))); streams.append(conn, true, "debugger tcp connection"); } void WvStreamsDebuggerServer::tcp_listener_close_cb() { log("Listener on %s closing\n", *tcp_listener->src()); } void WvStreamsDebuggerServer::auth_request_cb(Connection &s) { s.choose_salt(); s.send("AUTH", s.salt); s.setcallback(wv::bind(&WvStreamsDebuggerServer::auth_response_cb, this, wv::ref(s))); } void WvStreamsDebuggerServer::auth_response_cb(Connection &s) { const char *line = s.getline(); if (line == NULL) return; WvStringList args; wvtcl_decode(args, line); WvString username = args.popstr(); WvString encoded_salted_password = args.popstr(); if (!auth_cb || !username || !encoded_salted_password || !auth_cb(username, s.salt, encoded_salted_password)) { s.send("ERROR", "Authentication failure"); s.setcallback(wv::bind(&WvStreamsDebuggerServer::auth_request_cb, this, wv::ref(s))); } else { s.send("OK", "Authenticated"); s.setcallback(wv::bind(&WvStreamsDebuggerServer::ready_cb, this, wv::ref(s))); } } void WvStreamsDebuggerServer::ready_cb(Connection &s) { const char *line = s.getline(); if (line == NULL) return; WvStringList args; wvtcl_decode(args, line); WvString cmd = args.popstr(); if (!cmd) { s.send("ERROR", "Empty command"); return; } WvString result = s.debugger.run(cmd, args, wv::bind(&Connection::result_cb, &s, _1, _2)); if (!!result) s.send("ERROR", result); else s.send("OK", "Command successful"); } wvstreams-4.6.1/ipstreams/wvtcp.cc0000644000175000001440000002363411203076462016264 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStream-based TCP connection class. */ #include "wvtcplistener.h" #include "wvtcp.h" #include "wvistreamlist.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #include #ifdef _WIN32 #define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e) #define getsockopt(a,b,c,d,e) getsockopt(a,b,c,(char *)d, e) #undef errno #define errno GetLastError() #define EWOULDBLOCK WSAEWOULDBLOCK #define EINPROGRESS WSAEINPROGRESS #define EISCONN WSAEISCONN #define EALREADY WSAEALREADY #undef EINVAL #define EINVAL WSAEINVAL #define SOL_TCP IPPROTO_TCP #define SOL_IP IPPROTO_IP #define FORCE_NONZERO 1 #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NETDB_H # include #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IP_H # if HAVE_NETINET_IN_SYSTM_H # include # endif # include #endif #if HAVE_NETINET_TCP_H # include #endif #ifndef FORCE_NONZERO #define FORCE_NONZERO 0 #endif #ifdef SOLARIS #define SOL_TCP 6 #define SOL_IP 0 #endif #ifdef MACOS #define SOL_TCP 6 #define SOL_IP 0 #endif WV_LINK(WvTCPConn); WV_LINK(WvTCPListener); static IWvStream *creator(WvStringParm s, IObject*) { return new WvTCPConn(s); } static WvMoniker reg("tcp", creator); static IWvListener *listener(WvStringParm s, IObject *) { WvConstStringBuffer b(s); WvString hostport = wvtcl_getword(b); WvString wrapper = b.getstr(); IWvListener *l = new WvTCPListener(hostport); if (l && !!wrapper) l->addwrap(wv::bind(&IWvStream::create, wrapper, _1)); return l; } static WvMoniker lreg("tcp", listener); WvTCPConn::WvTCPConn(const WvIPPortAddr &_remaddr) { remaddr = (_remaddr.is_zero() && FORCE_NONZERO) ? WvIPPortAddr("127.0.0.1", _remaddr.port) : _remaddr; resolved = true; connected = false; incoming = false; do_connect(); } WvTCPConn::WvTCPConn(int _fd, const WvIPPortAddr &_remaddr) : WvFDStream(_fd) { remaddr = (_remaddr.is_zero() && FORCE_NONZERO) ? WvIPPortAddr("127.0.0.1", _remaddr.port) : _remaddr; resolved = true; connected = true; incoming = true; nice_tcpopts(); } WvTCPConn::WvTCPConn(WvStringParm _hostname, uint16_t _port) : hostname(_hostname) { struct servent* serv; char *hnstr = hostname.edit(), *cptr; cptr = strchr(hnstr, ':'); if (!cptr) cptr = strchr(hnstr, '\t'); if (!cptr) cptr = strchr(hnstr, ' '); if (cptr) { *cptr++ = 0; serv = getservbyname(cptr, NULL); remaddr.port = serv ? ntohs(serv->s_port) : atoi(cptr); } if (_port) remaddr.port = _port; resolved = connected = false; incoming = false; WvIPAddr x(hostname); if (x != WvIPAddr()) { remaddr = WvIPPortAddr(x, remaddr.port); resolved = true; do_connect(); } else check_resolver(); } WvTCPConn::~WvTCPConn() { // nothing to do } // Set a few "nice" options on our socket... (read/write, non-blocking, // keepalive) void WvTCPConn::nice_tcpopts() { set_close_on_exec(true); set_nonblock(true); int value = 1; setsockopt(getfd(), SOL_SOCKET, SO_KEEPALIVE, &value, sizeof(value)); low_delay(); } void WvTCPConn::low_delay() { int value; value = 1; setsockopt(getfd(), SOL_TCP, TCP_NODELAY, &value, sizeof(value)); #ifndef _WIN32 value = IPTOS_LOWDELAY; setsockopt(getfd(), SOL_IP, IP_TOS, &value, sizeof(value)); #endif } void WvTCPConn::debug_mode() { int value = 0; setsockopt(getfd(), SOL_SOCKET, SO_KEEPALIVE, &value, sizeof(value)); } void WvTCPConn::do_connect() { if (getfd() < 0) { int rwfd = socket(PF_INET, SOCK_STREAM, 0); if (rwfd < 0) { seterr(errno); return; } setfd(rwfd); nice_tcpopts(); } #ifndef _WIN32 WvIPPortAddr newaddr(remaddr); #else // Win32 doesn't like to connect to 0.0.0.0:port; it means "any address // on the local machine", so let's just force localhost WvIPAddr zero; WvIPPortAddr newaddr(WvIPAddr(remaddr)==zero ? WvIPAddr("127.0.0.1") : remaddr, remaddr.port); #endif sockaddr *sa = newaddr.sockaddr(); int ret = connect(getfd(), sa, newaddr.sockaddr_len()), err = errno; assert(ret <= 0); if (ret == 0 || (ret < 0 && err == EISCONN)) connected = true; else if (ret < 0 && err != EINPROGRESS && err != EWOULDBLOCK && err != EAGAIN && err != EALREADY && err != EINVAL /* apparently winsock 1.1 might do this */) { connected = true; // "connection phase" is ended, anyway seterr(err); } delete sa; } void WvTCPConn::check_resolver() { const WvIPAddr *ipr; int dnsres = dns.findaddr(0, hostname, &ipr); if (dnsres == 0) { // error resolving! resolved = true; seterr(WvString("Unknown host \"%s\"", hostname)); } else if (dnsres > 0) { // fprintf(stderr, "%p: resolver succeeded!\n", this); remaddr = WvIPPortAddr(*ipr, remaddr.port); resolved = true; do_connect(); } } #ifndef SO_ORIGINAL_DST # define SO_ORIGINAL_DST 80 #endif WvIPPortAddr WvTCPConn::localaddr() { sockaddr_in sin; socklen_t sl = sizeof(sin); if (!isok()) return WvIPPortAddr(); if ( #ifndef _WIN32 // getsockopt() with SO_ORIGINAL_DST is for transproxy of incoming // connections. For outgoing (and for windows) use just use good // old getsockname(). (!incoming || getsockopt(getfd(), SOL_IP, SO_ORIGINAL_DST, (char*)&sin, &sl) < 0) && #endif getsockname(getfd(), (sockaddr *)&sin, &sl)) { return WvIPPortAddr(); } return WvIPPortAddr(&sin); } const WvIPPortAddr *WvTCPConn::src() const { return &remaddr; } void WvTCPConn::pre_select(SelectInfo &si) { if (!resolved) dns.pre_select(hostname, si); if (resolved) { bool oldw = si.wants.writable; if (!isconnected()) { si.wants.writable = true; #ifdef _WIN32 // WINSOCK INSANITY ALERT! // // In Unix, you detect the success OR failure of a non-blocking // connect() by select()ing with the socket in the write set. // HOWEVER, in Windows, you detect the success of connect() by // select()ing with the socket in the write set, and the // failure of connect() by select()ing with the socket in the // exception set! si.wants.isexception = true; #endif } WvFDStream::pre_select(si); si.wants.writable = oldw; return; } } bool WvTCPConn::post_select(SelectInfo &si) { bool result = false; if (!resolved) { if (dns.post_select(hostname, si)) { check_resolver(); if (!isok()) return true; // oops, failed to resolve the name! } } else { result = WvFDStream::post_select(si); if (result && !connected) { // the manual for connect() says just re-calling connect() later // will return either EISCONN or the error code from the previous // failed connection attempt. However, in *some* OSes (like // Windows, at least) a failed connection attempt resets the // socket back to "connectable" state, so every connect() call // will just restart the background connecting process and we'll // never get a result out. Thus, we *first* check SO_ERROR. If // that returns no error, then maybe the socket is connected, or // maybe they just didn't feel like giving us our error yet. // Only then, call connect() to look for EISCONN or another error. int conn_res = -1; socklen_t res_size = sizeof(conn_res); if (getsockopt(getfd(), SOL_SOCKET, SO_ERROR, &conn_res, &res_size)) { // getsockopt failed seterr(errno); connected = true; // not in connecting phase anymore } else if (conn_res != 0) { // connect failed seterr(conn_res); connected = true; // not in connecting phase anymore } else { // connect succeeded! Double check by re-calling connect(). do_connect(); } } } return result; } bool WvTCPConn::isok() const { return !resolved || WvFDStream::isok(); } size_t WvTCPConn::uwrite(const void *buf, size_t count) { if (connected) return WvFDStream::uwrite(buf, count); else return 0; // can't write yet; let them enqueue it instead } WvTCPListener::WvTCPListener(const WvIPPortAddr &_listenport) : WvListener(new WvFdStream(socket(PF_INET, SOCK_STREAM, 0))) { WvFdStream *fds = (WvFdStream *)cloned; listenport = _listenport; sockaddr *sa = listenport.sockaddr(); int x = 1; fds->set_close_on_exec(true); fds->set_nonblock(true); if (getfd() < 0 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) || bind(getfd(), sa, listenport.sockaddr_len()) || listen(getfd(), 5)) { seterr(errno); return; } if (listenport.port == 0) // auto-select a port number { socklen_t namelen = listenport.sockaddr_len(); if (getsockname(getfd(), sa, &namelen) != 0) seterr(errno); else listenport = WvIPPortAddr((sockaddr_in *)sa); } delete sa; } WvTCPListener::~WvTCPListener() { close(); } IWvStream *WvTCPListener::accept() { struct sockaddr_in sin; socklen_t len = sizeof(sin); if (!isok()) return NULL; int newfd = ::accept(getfd(), (struct sockaddr *)&sin, &len); if (newfd >= 0) return wrap(new WvTCPConn(newfd, WvIPPortAddr(&sin))); else if (errno == EAGAIN || errno == EINTR) return NULL; // this listener is doing weird stuff else { seterr(errno); return NULL; } } void WvTCPListener::accept_callback(WvIStreamList *list, wv::function cb, IWvStream *_conn) { WvStreamClone *conn = new WvStreamClone(_conn); conn->setcallback(wv::bind(cb, conn)); list->append(conn, true, "WvTCPConn"); } const WvIPPortAddr *WvTCPListener::src() const { return &listenport; } wvstreams-4.6.1/ipstreams/wvudp.cc0000644000175000001440000000563411036722347016272 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvUDPStream can send and receive packets on a connectionless UDP socket. * See wvudp.h for details. */ #include "wvudp.h" #ifndef WIN32 #include #else #define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e) #define recvfrom(a,b,c,d,e,f) recvfrom(a, (char *) b, c, d, e, f) #define sendto(a,b,c,d,e,f) sendto(a,(const char*) b,c,d,e,f) #undef errno #define errno GetLastError() #endif #include #ifdef ISDARWIN # define socklen_t int #endif WvUDPStream::WvUDPStream(const WvIPPortAddr &_local, const WvIPPortAddr &_rem) : localaddr(), remaddr(_rem) { int x = 1; setfd(socket(PF_INET, SOCK_DGRAM, 0)); if (getfd() < 0 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0) { seterr(errno); return; } set_close_on_exec(true); set_nonblock(true); struct sockaddr *sa = _local.sockaddr(); if (bind(getfd(), sa, _local.sockaddr_len())) { delete sa; seterr(errno); return; } delete sa; struct sockaddr_in nsa; socklen_t nsalen = sizeof(nsa); if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0) { seterr(errno); return; } localaddr = WvIPPortAddr(&nsa); if (WvIPAddr(_rem) != WvIPAddr()) { struct sockaddr *sa = _rem.sockaddr(); if (connect(getfd(), sa, _rem.sockaddr_len())) { delete sa; seterr(errno); return; } delete sa; } } WvUDPStream::~WvUDPStream() { } const WvAddr *WvUDPStream::src() const { return &remaddr; } const WvAddr *WvUDPStream::local() const { return &localaddr; } size_t WvUDPStream::uread(void *buf, size_t count) { if (!isok() || !buf || !count) return 0; struct sockaddr_in from; socklen_t fromlen = sizeof(from); int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen); if (in >= 0) remaddr = WvIPPortAddr(&from); // errors in UDP are ignored return in < 0 ? 0 : in; } size_t WvUDPStream::uwrite(const void *buf, size_t count) { if (!isok() || !buf || !count) return 0; // pretend everything worked if there is nowhere to send data if (remaddr.is_zero()) return count; struct sockaddr *to = remaddr.sockaddr(); size_t tolen = remaddr.sockaddr_len(); int out; out = sendto(getfd(), buf, count, 0, to, tolen); if (out < 0 && errno == EACCES) // permission denied seterr(EACCES); delete to; // errors in UDP are ignored // pretend that the write always succeeds even if the kernel // complains since we don't want datagrams backing up in the // buffer and forming merged datagrams as a result return out < 0 ? 0 : out; } void WvUDPStream::enable_broadcasts() { int value = 1; if (!isok()) return; setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); } wvstreams-4.6.1/ipstreams/wvunixsocket.cc0000644000175000001440000001256411203076445017673 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStream-based Unix domain socket connection class. See wvunixsocket.h. */ #include "wvistreamlist.h" #include "wvunixlistener.h" #include "wvunixsocket.h" #include "wvstringmask.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #if HAVE_ERRNO_H # include #endif #include #if HAVE_SYS_TYPES_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_SYS_STAT_H # include #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NETDB_H # include #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IP_H # if HAVE_NETINET_IN_SYSTM_H # include # endif # include #endif #if HAVE_NETINET_TCP_H # include #endif #include #include WV_LINK(WvUnixConn); WV_LINK(WvUnixListener); static IWvStream *creator(WvStringParm s, IObject*) { return new WvUnixConn(s); } static WvMoniker reg("unix", creator); static IWvListener *listener(WvStringParm s, IObject *) { WvConstStringBuffer b(s); WvString path = wvtcl_getword(b); WvString wrapper = b.getstr(); IWvListener *l = new WvUnixListener(path, 0777); if (l && !!wrapper) l->addwrap(wv::bind(&IWvStream::create, wrapper, _1)); return l; } static IWvListener *modelistener(WvStringParm s, IObject *) { WvConstStringBuffer b(s); // strtoul knows how to interpret octal if it starts with '0' int mode = strtoul(wvtcl_getword(b, WvStringMask(":")), NULL, 0); if (b.peekch() == ':') b.get(1); WvString path = wvtcl_getword(b); WvString wrapper = b.getstr(); IWvListener *l = new WvUnixListener(path, mode); if (l && !!wrapper) l->addwrap(wv::bind(&IWvStream::create, wrapper, _1)); return l; } static WvMoniker lreg("unix", listener); static WvMoniker lmodereg("unixmode", modelistener); WvUnixConn::WvUnixConn(int _fd, const WvUnixAddr &_addr) : WvFDStream(_fd), addr(_addr) { // all is well and we're connected. set_nonblock(true); set_close_on_exec(true); } WvUnixConn::WvUnixConn(const WvUnixAddr &_addr) : addr(_addr) { setfd(socket(PF_UNIX, SOCK_STREAM, 0)); if (getfd() < 0) { seterr(errno); return; } // Make the socket non-blocking and close-on-exec. fcntl(getfd(), F_SETFD, FD_CLOEXEC); fcntl(getfd(), F_SETFL, O_RDWR|O_NONBLOCK); sockaddr *sa = addr.sockaddr(); if (connect(getfd(), sa, addr.sockaddr_len()) < 0) seterr(errno); delete sa; // all is well and we're connected. set_nonblock(true); set_close_on_exec(true); } WvUnixConn::~WvUnixConn() { // we don't want to delete the socket file here; that's a job for the // listener class. // close the socket close(); } const WvUnixAddr *WvUnixConn::src() const { return &addr; } WvUnixListener::WvUnixListener(const WvUnixAddr &_addr, int create_mode) : WvListener(new WvFdStream(socket(PF_UNIX, SOCK_STREAM, 0))), addr(_addr) { WvFdStream *fds = (WvFdStream *)cloned; mode_t oldmask; bound_okay = false; if (getfd() < 0) { // error inherited from substream return; } fds->set_close_on_exec(true); fds->set_nonblock(true); sockaddr *sa = addr.sockaddr(); size_t salen = addr.sockaddr_len(); if (connect(getfd(), sa, salen) == 0) // successful connect?! seterr(EADDRINUSE); // someone is using this already! else { // unfortunately we have to change the umask here to make the // create_mode work, because bind() doesn't take extra arguments // like open() does. However, we don't actually want to _cancel_ // the effects of umask, only add to them; so the original umask is // or'ed into ~create_mode. This way it acts like open(). oldmask = umask(0777); // really just reading the old umask here umask(oldmask | ((~create_mode) & 0777)); ::unlink(WvString(addr)); if (bind(getfd(), sa, salen) || listen(getfd(), 50)) seterr(errno); else bound_okay = true; umask(oldmask); } delete sa; } WvUnixListener::~WvUnixListener() { close(); } void WvUnixListener::close() { // delete the socket _before_ closing it. Unix will keep // existing connections around anyway (if any), but if it's idle, then // we never have an existing not-in-use socket inode. if (bound_okay) { WvString filename(addr); ::unlink(filename); } WvListener::close(); } IWvStream *WvUnixListener::accept() { struct sockaddr_un saun; socklen_t len = sizeof(saun); if (!isok()) return NULL; int newfd = ::accept(getfd(), (struct sockaddr *)&saun, &len); if (newfd >= 0) return wrap(new WvUnixConn(newfd, addr)); else if (errno == EAGAIN || errno == EINTR) return NULL; // this listener is doing weird stuff else { seterr(errno); return NULL; } } void WvUnixListener::accept_callback(WvIStreamList *list, wv::function cb, IWvStream *_conn) { WvStreamClone *conn = new WvStreamClone(_conn); conn->setcallback(wv::bind(cb, conn)); list->append(conn, true, "WvUnixConn"); } const WvUnixAddr *WvUnixListener::src() const { return &addr; } wvstreams-4.6.1/ipstreams/wvaddr.cc0000644000175000001440000004012211253746065016407 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Device-independent and device-specific hardware/protocol address * classes that can store themselves efficiently as well as create a * printable string version of themselves. */ #ifndef _WIN32 #include #include #include #ifdef MACOS #include #endif #include #endif #include "wvaddr.h" #include #ifndef ARPHRD_IPSEC // From ipsec_tunnel #define ARPHRD_IPSEC 31 #endif // workaround for functions called sockaddr() -- oops. typedef struct sockaddr sockaddr_bin; /* A list of Linux ARPHRD_* types, one for each element of CapType. */ int WvEncap::extypes[] = { #ifdef _WIN32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 #else // hardware encapsulation 0, // Unknown ARPHRD_LOOPBACK, 0, // Ethertap ARPHRD_ETHER, ARPHRD_ARCNET, ARPHRD_SLIP, ARPHRD_CSLIP, ARPHRD_PPP, ARPHRD_IPSEC, // protocol encapsulation AF_INET, // IPv4 AF_UNIX // Unix domain socket #endif }; /* Printable strings corresponding to each element of CapType */ const char WvEncap::strings[][20] = { // hardware encapsulation "Unknown", "Loopback", "Ethertap", "Ethernet", "ARCnet", "SLIP", "CSLIP", "PPP", "IPsec", // protocol encapsulation "IP", // IPv4 "Unix", // Unix domain socket }; /* Figure out the CapType corresponding to a Linux ARPHRD_* type or * sockaddr sa_family type. */ WvEncap::WvEncap(int extype) { for (int count=0; count < NUM_ENCAP_TYPES; count++) { if (extype == extypes[count]) { cap = (CapType)count; return; } } cap = Unknown; } /* Find the hash value of a WvAddr, for use with WvHashTable */ unsigned WvHash(const WvAddr &addr) { return addr.WvHash(); } /* Create an object of the appropriate WvAddr-derived class based on the * address and type stored in 'addr'. */ WvAddr *WvAddr::gen(struct sockaddr *addr) { WvEncap encap(addr->sa_family); switch (encap.cap) { case WvEncap::Loopback: return new WvStringAddr("Loopback", WvEncap::Loopback); case WvEncap::IPv4: return new WvIPPortAddr((sockaddr_in *)addr); #ifndef _WIN32 case WvEncap::ARCnet: return new WvARCnetAddr(addr); case WvEncap::Ethertap: case WvEncap::Ethernet: return new WvEtherAddr(addr); case WvEncap::IPsec: return new WvStringAddr("IPsec", WvEncap::IPsec); #endif default: return new WvStringAddr("Unknown", WvEncap::Unknown); } } bool WvAddr::isbroadcast() const { return false; // default is no support for broadcasts } const unsigned char *WvAddr::rawdata() const { return NULL; } size_t WvAddr::rawdata_len() const { return 0; } unsigned WvAddr::WvHash() const { unsigned hash = 0; const unsigned char *cptr, *raw = rawdata(); int len = rawdata_len(), width; if (!raw || !len) return 0; width = (sizeof(hash)*8 / len) + 1; for (cptr = raw; len; len--) hash = (hash << width) ^ *(cptr++); return hash; } bool WvAddr::comparator(const WvAddr *a2, bool first_pass) const { if (type() != a2->type()) return false; const unsigned char *raw1, *raw2; size_t len; len = rawdata_len(); if (len != a2->rawdata_len()) return false; raw1 = rawdata(); raw2 = a2->rawdata(); if (!raw1 && !raw2) return true; if (!raw1 || !raw2) return false; return !memcmp(raw1, raw2, len); } WvStringAddr::WvStringAddr(WvStringParm s, const WvEncap &_cap) : addr(s), cap(_cap) { } WvStringAddr::WvStringAddr(const struct sockaddr *_addr) : addr((char *)_addr->sa_data), cap(_addr->sa_family) { } WvStringAddr::~WvStringAddr() { // nothing to do } WvEncap WvStringAddr::encap() const { return cap; } const unsigned char *WvStringAddr::rawdata() const { return (const unsigned char *)(const char *)addr; } size_t WvStringAddr::rawdata_len() const { return strlen(addr); } sockaddr_bin *WvStringAddr::sockaddr() const { sockaddr_bin *sa = new sockaddr_bin; memset(sa, 0, sizeof(*sa)); strncpy(sa->sa_data, addr, sizeof(sa->sa_data)); return sa; } size_t WvStringAddr::sockaddr_len() const { return sizeof(sockaddr_bin); } WvString WvStringAddr::printable() const { return addr; } #ifndef _WIN32 /* create a WvEtherAddr from a printable string in the format: * AA:BB:CC:DD:EE:FF (six hex numbers, separated by colons) */ void WvEtherAddr::string_init(char const string[]) { char *endptr = NULL; unsigned char *cptr = binaddr; memset(binaddr, 0, ETHER_ADDR_LEN); for (unsigned int count=0; count < ETHER_ADDR_LEN; count++) { *cptr++ = strtoul(endptr ? endptr : string, &endptr, 16); if (!endptr || !*endptr || endptr==string) break; endptr++; } } WvEtherAddr::~WvEtherAddr() { // nothing to do } /* Generate a printable version of an ethernet address. */ WvString WvEtherAddr::printable() const { char s[ETHER_ADDR_LEN*3], *cptr = s; for (unsigned int count = 0; count < ETHER_ADDR_LEN; count++) { if (cptr > s) *cptr++ = ':'; sprintf(cptr, "%02X", binaddr[count]); cptr += 2; } *cptr = 0; return WvString("%s", s); // create a dynamic WvString } WvEncap WvEtherAddr::encap() const { return WvEncap(WvEncap::Ethernet); } // FF:FF:FF:FF:FF:FF is the ethernet broadcast address. bool WvEtherAddr::isbroadcast() const { for (unsigned int count = 0; count < ETHER_ADDR_LEN; count++) if (binaddr[count] != 0xFF) return false; return true; } const unsigned char *WvEtherAddr::rawdata() const { return binaddr; } size_t WvEtherAddr::rawdata_len() const { return ETHER_ADDR_LEN; } sockaddr_bin *WvEtherAddr::sockaddr() const { sockaddr_bin *sa = new sockaddr_bin; memset(sa, 0, sizeof(*sa)); sa->sa_family = ARPHRD_ETHER; memcpy(sa->sa_data, binaddr, ETHER_ADDR_LEN); return sa; } size_t WvEtherAddr::sockaddr_len() const { return sizeof(sockaddr_bin); } WvARCnetAddr::~WvARCnetAddr() { // nothing to do } WvString WvARCnetAddr::printable() const { WvString s(" "); sprintf(s.edit(), "%02X", binaddr); return s; } WvEncap WvARCnetAddr::encap() const { return WvEncap(WvEncap::ARCnet); } const unsigned char *WvARCnetAddr::rawdata() const { return &binaddr; } size_t WvARCnetAddr::rawdata_len() const { return 1; } sockaddr_bin *WvARCnetAddr::sockaddr() const { sockaddr_bin *sa = new sockaddr_bin; memset(sa, 0, sizeof(*sa)); sa->sa_family = ARPHRD_ARCNET; sa->sa_data[0] = binaddr; return sa; } size_t WvARCnetAddr::sockaddr_len() const { return sizeof(sockaddr_bin); } #endif //_WIN32 /* create an IP address from a dotted-quad string. We don't support * gethostname()-style lookups here, because they happen only synchronously. * Streams that need hostname lookups will have to do it themselves. */ void WvIPAddr::string_init(const char string[]) { const char *iptr, *nptr; unsigned char *cptr = binaddr; memset(binaddr, 0, 4); nptr = string; for (int count=0; count < 4 && nptr; count++) { iptr = nptr; nptr = strchr(iptr, '.'); if (nptr) nptr++; *cptr++ = strtol(iptr, NULL, 10); if (!nptr) break; } } WvIPAddr::~WvIPAddr() { // nothing to do } bool WvIPAddr::comparator(const WvAddr *a2, bool first_pass) const { if (a2->type() == WVIPADDR) return !memcmp(binaddr, ((WvIPAddr *)a2)->binaddr, sizeof(binaddr)); else if (first_pass) return a2->comparator(this, false); else { const unsigned char *raw1, *raw2; size_t len; len = rawdata_len(); if (len != a2->rawdata_len()) return false; raw1 = rawdata(); raw2 = a2->rawdata(); if (!raw1 && !raw2) return true; if (!raw1 || !raw2) return false; return !memcmp(raw1, raw2, len); } } /* Generate a printable version of an IP address. */ WvString WvIPAddr::printable() const { return WvString("%s.%s.%s.%s", binaddr[0], binaddr[1], binaddr[2], binaddr[3]); } /* AND two IP addresses together (handle netmasks) */ WvIPAddr WvIPAddr::operator& (const WvIPAddr &a2) const { unsigned char obin[4]; for (int count=0; count<4; count++) obin[count] = binaddr[count] & a2.binaddr[count]; return WvIPAddr(obin); } /* OR two IP addresses together (for broadcasts, etc) */ WvIPAddr WvIPAddr::operator| (const WvIPAddr &a2) const { unsigned char obin[4]; for (int count=0; count<4; count++) obin[count] = binaddr[count] | a2.binaddr[count]; return WvIPAddr(obin); } /* XOR two IP addresses together (for binary operations) */ WvIPAddr WvIPAddr::operator^ (const WvIPAddr &a2) const { unsigned char obin[4]; for (int count=0; count<4; count++) obin[count] = binaddr[count] ^ a2.binaddr[count]; return WvIPAddr(obin); } /* invert all the bits of an IP address (for useful binary operations) */ WvIPAddr WvIPAddr::operator~ () const { unsigned char obin[4]; for (int count=0; count<4; count++) obin[count] = ~binaddr[count]; return WvIPAddr(obin); } /* add an integer value to an IP address: * eg. 192.168.42.255 + 1 == 192.168.43.0 */ WvIPAddr WvIPAddr::operator+ (int n) const { uint32_t newad = htonl(ntohl(addr()) + n); return WvIPAddr((unsigned char *)&newad); } WvIPAddr WvIPAddr::operator- (int n) const { uint32_t newad = htonl(ntohl(addr()) - n); return WvIPAddr((unsigned char *)&newad); } WvEncap WvIPAddr::encap() const { return WvEncap(WvEncap::IPv4); } const unsigned char *WvIPAddr::rawdata() const { return binaddr; } size_t WvIPAddr::rawdata_len() const { return 4; } /* Generate a struct sockaddr (suitable for sendto()) from this IP * address. Don't forget to delete it after you're done! */ sockaddr_bin *WvIPAddr::sockaddr() const { sockaddr_in *sin = new sockaddr_in; memset(sin, 0, sizeof(*sin)); sin->sin_family = AF_INET; sin->sin_addr.s_addr = addr(); sin->sin_port = 0; return (sockaddr_bin *)sin; } size_t WvIPAddr::sockaddr_len() const { return sizeof(sockaddr_in); } WvIPNet::WvIPNet() { } WvIPNet::WvIPNet(const WvIPNet &_net) : WvIPAddr(_net), mask(_net.netmask()) { } // If the netmask is not specified, it will default to all 1's. void WvIPNet::string_init(const char string[]) { const char *maskptr; int bits; uint32_t imask; maskptr = strchr(string, '/'); if (!maskptr) { mask = WvIPAddr("255.255.255.255"); return; } maskptr++; if (strchr(maskptr, '.')) mask = WvIPAddr(maskptr); else { bits = atoi(maskptr); if (bits > 0) imask = htonl(~(((uint32_t)1 << (32-bits)) - 1)); // see below else imask = 0; mask = WvIPAddr((unsigned char *)&imask); } } WvIPNet::WvIPNet(const WvIPAddr &base, const WvIPAddr &_mask) : WvIPAddr(base), mask(_mask) { } WvIPNet::WvIPNet(const WvIPAddr &base, int bits) : WvIPAddr(base) { uint32_t imask; if (bits > 0) // <<32 is a bad idea! imask = htonl(~(((uint32_t)1 << (32-bits)) - 1)); else imask = 0; mask = WvIPAddr((unsigned char *)&imask); } WvIPNet::~WvIPNet() { // nothing to do } WvString WvIPNet::printable() const { if (bits() < 32) return WvString("%s/%s", network(), bits()); else return WvIPAddr::printable(); } unsigned WvIPNet::WvHash() const { return WvIPAddr::WvHash() + mask.WvHash(); } bool WvIPNet::comparator(const WvAddr *a2, bool first_pass) const { if (a2->type() == WVIPNET) return WvIPAddr::comparator(a2, false) && mask == ((WvIPNet *)a2)->mask; else if (first_pass) return a2->comparator(this, false); else return WvIPAddr::comparator(a2, false); } void WvIPNet::include(const WvIPNet &addr) { mask = mask & addr.mask & ~(*this ^ addr); } bool WvIPNet::includes(const WvIPNet &addr) const { return (addr.base() & netmask()) == network() && (addr.netmask() & netmask()) == netmask(); } int WvIPNet::bits() const { int bits = 0; uint32_t val = ntohl(mask.addr()); do { bits += val >> 31; } while ((val <<= 1) & (1 << 31)); return bits; } void WvIPNet::normalize() { if (bits() > 0) { uint32_t val = htonl(~(((uint32_t)1 << (32-bits())) - 1)); mask = WvIPAddr((unsigned char *)&val); } else mask = WvIPAddr(); // empty netmask } WvIPPortAddr::WvIPPortAddr() { port = 0; } WvIPPortAddr::WvIPPortAddr(const WvIPAddr &_ipaddr, uint16_t _port) : WvIPAddr(_ipaddr) { port = _port; } static bool all_digits(const char *s) { for (; *s; s++) if (!isdigit((unsigned char)*s)) return false; return true; } // If no port is specified (after a ':' or a space or a tab) it defaults to 0. void WvIPPortAddr::string_init(const char string[]) { // special case for an all-numeric string: it must be just a port, // with default address 0.0.0.0. if (all_digits(string)) { *this = WvIPAddr(); port = atoi(string); return; } const char *cptr = strchr(string, ':'); if (!cptr) cptr = strchr(string, ' '); if (!cptr) cptr = strchr(string, '\t'); // avoid calling getservbyname() if we can avoid it, since it's really // slow and people like to create WvIPPortAddr objects really often. if (cptr && strcmp(cptr+1, "0")) { port = atoi(cptr+1); if (!port) { struct servent *serv = getservbyname(cptr+1, NULL); if (serv) port = ntohs(serv->s_port); } } else port = 0; } WvIPPortAddr::WvIPPortAddr(uint16_t _port) : WvIPAddr("0.0.0.0") { port = _port; } WvIPPortAddr::WvIPPortAddr(const char string[], uint16_t _port) : WvIPAddr(string) { port = _port; } WvIPPortAddr::~WvIPPortAddr() { // nothing to do } /* Generate a printable version of an IP+Port Address. */ WvString WvIPPortAddr::printable() const { return WvString("%s:%s", WvIPAddr::printable(), WvString(port)); } /* Generate a struct sockaddr (suitable for sendto()) from this IP+Port * address. Don't forget to delete it after you're done! */ sockaddr_bin *WvIPPortAddr::sockaddr() const { sockaddr_in *sin = (sockaddr_in *)WvIPAddr::sockaddr(); sin->sin_port = htons(port); return (sockaddr_bin *)sin; } unsigned WvIPPortAddr::WvHash() const { return WvIPAddr::WvHash() + port; } bool WvIPPortAddr::comparator(const WvAddr *a2, bool first_pass) const { if (a2->type() == WVIPPORTADDR) return WvIPAddr::comparator(a2, false) && port == ((WvIPPortAddr *)a2)->port; else if (first_pass) return a2->comparator(this, false); else return WvIPAddr::comparator(a2, false); } #ifndef _WIN32 WvUnixAddr::WvUnixAddr(const char *_sockname) : sockname(_sockname) { if (!sockname) sockname = "/"; } WvUnixAddr::WvUnixAddr(WvStringParm _sockname) : sockname(_sockname) { if (!sockname) sockname = "/"; } WvUnixAddr::WvUnixAddr(const WvUnixAddr &_addr) : sockname(_addr.sockname) { // nothing else needed } WvUnixAddr::~WvUnixAddr() { // nothing special } WvString WvUnixAddr::printable() const { return sockname; } WvEncap WvUnixAddr::encap() const { return WvEncap::Unix; } /* don't forget to delete the returned object when you're done! */ sockaddr_bin *WvUnixAddr::sockaddr() const { sockaddr_un *addr = new sockaddr_un; memset(addr, 0, sizeof(*addr)); addr->sun_family = AF_UNIX; size_t max = strlen(sockname); if (max > sizeof(addr->sun_path) - 2) // appease valgrind max = sizeof(addr->sun_path) - 2; strncpy(addr->sun_path, sockname, max); if (addr->sun_path[0] == '@') // user wants an "abstract" socket addr->sun_path[0] = 0; // leading byte should be nul return (sockaddr_bin *)addr; } size_t WvUnixAddr::sockaddr_len() const { sockaddr_un *fake; size_t max = sizeof(fake->sun_path); size_t val = strlen(sockname); if (val > max) val = max; return sizeof(fake->sun_family) + val; } const unsigned char *WvUnixAddr::rawdata() const { return (const unsigned char *)(const char *)sockname; } size_t WvUnixAddr::rawdata_len() const { return strlen(sockname); } #endif // _WIN32 wvstreams-4.6.1/utils/0000755000175000001440000000000011260431126013726 5ustar wlachuserswvstreams-4.6.1/utils/wvserialize.cc0000644000175000001440000000063311036722347016614 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Code to serialize and deserialize objects to/from WvBufs. * See wvserialize.h. */ #include "wvserialize.h" template <> WvString _wv_deserialize(WvBuf &buf) { unsigned int len = buf.strchr('\0'); if (buf.used() < len) return WvString(); else return (const char *)buf.get(len); } wvstreams-4.6.1/utils/wvtr1.cc0000644000175000001440000000074011036722347015332 0ustar wlachusers#include "wvtr1.h" /* If we're not using TR1, we must be using Boost. */ #if !defined(HAVE_TR1_FUNCTIONAL) && defined(HAVE_BOOST_THROW_EXCEPTION_HPP) #include #include "wvcrash.h" #ifdef BOOST_NO_EXCEPTIONS /* std::tr1::function does this when operator() is called on an empty * object. This is a bit heavy-handed, but it's all I can think of for * now. */ void boost::throw_exception(std::exception const &e) { std::abort(); } #endif #endif wvstreams-4.6.1/utils/wvmatrix.cc0000644000175000001440000000256711036722347016141 0ustar wlachusers#include "wvmatrix.h" WvMatrix::WvMatrix(const int _m, const int _n, const int *_data) : m(_m), n(_n) { if (!m || !n) { data = NULL; return; } data = new int[m * n]; if (_data) memcpy(data, _data, m * n * sizeof(int)); else for (int i = 0; i < m * n; i++) data[i] = 0; } WvMatrix::~WvMatrix() { delete[] data; } WvMatrix::WvMatrix(const WvMatrix& mx) : m(mx.m), n(mx.n) { data = new int[m * n]; memcpy(data, mx.data, m * n * sizeof(int)); } WvMatrix& WvMatrix::operator= (const WvMatrix& mx) { delete[] data; data = new int[m * n]; m = mx.m; n = mx.n; memcpy(data, mx.data, m * n * sizeof(int)); return *this; } WvMatrix WvMatrix::operator+ (const WvMatrix &rhs) const { WvMatrix res(rhs); if (m != rhs.m || n != rhs.n) return res; for (int i = 0; i < m * n; i++) res.data[i] += data[i]; return res; } WvMatrix WvMatrix::operator* (const WvMatrix &rhs) const { WvMatrix res(m, rhs.n); if (n != rhs.m) return res; int c; for (int i = 0; i < res.m; i++) for (int j = 0; j < res.n; j++) { c = 0; for (int k = 0; k < n; k++) c += (*this)(i, k) * rhs(k, j); res(i, j) = c; } return res; } WvString WvMatrix::printable() { WvString res("{%s", data[0]); for (int i = 1; i < m * n; i++) res.append(", %s", data[i]); return res; } wvstreams-4.6.1/utils/wvsorter.cc0000644000175000001440000000071611036722347016145 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * An iterator that can sort anything that has an Iter subclass with the * right member functions. * * See wvsorter.h. */ #include "wvsorter.h" WvSorterBase::CompareFunc *WvSorterBase::actual_compare; int WvSorterBase::magic_compare(const void *_a, const void *_b) { void *a = *(void **)_a, *b = *(void **)_b; return actual_compare(a, b); } wvstreams-4.6.1/utils/wvsubproc.cc0000644000175000001440000002132111036722347016277 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for reliably starting/stopping subprocesses. See * wvsubproc.h. */ #include "wvsubproc.h" #include "wvtimeutils.h" #include #include #include #include #include #include #include #include #include "wvfork.h" void WvSubProc::init() { pid = -1; memlimit = -1; running = false; estatus = 0; } WvSubProc::~WvSubProc() { // we need to kill the process here, or else we could leave // zombies lying around... stop(100); } int WvSubProc::_startv(const char cmd[], const char * const *argv) { int waitfd = -1; pid = fork(&waitfd); //fprintf(stderr, "pid for '%s' is %d\n", cmd, pid); if (!pid) // child process { // unblock the parent. close(waitfd); #ifdef RLIMIT_AS // Set memory limit, if applicable if (memlimit > 0) { struct rlimit rlim; memset(&rlim, 0, sizeof(rlim)); rlim.rlim_cur = memlimit * 1024 * 1024; rlim.rlim_max = memlimit * 1024 * 1024; setrlimit(RLIMIT_AS, &rlim); } #endif // run the subprocess. execvp(cmd, (char * const *)argv); // if we get this far, just make sure we exit, not return. // The code 242 should be somewhat recognizable by the calling // process so we know something is up. _exit(242); } else if (pid > 0) // parent process running = true; else if (pid < 0) return pid; return 0; // ok } void WvSubProc::prepare(const char cmd[], ...) { va_list ap; va_start(ap, cmd); preparev(cmd, ap); va_end(ap); } void WvSubProc::preparev(const char cmd[], va_list ap) { const char *argptr; // remember the command so start_again() will work last_cmd = cmd; last_args.zap(); while ((argptr = va_arg(ap, const char *)) != NULL) last_args.append(new WvString(argptr), true); } void WvSubProc::preparev(const char cmd[], const char * const *argv) { const char * const *argptr; // remember the command so start_again() will work last_cmd = cmd; last_args.zap(); for (argptr = argv; argptr && *argptr; argptr++) last_args.append(new WvString(*argptr), true); } void WvSubProc::preparev(const char cmd[], WvStringList &args) { last_cmd = cmd; last_args.zap(); WvStringList::Iter i(args); for (i.rewind(); i.next(); ) last_args.append(new WvString(*i), true); } int WvSubProc::start(const char cmd[], ...) { va_list ap; va_start(ap, cmd); preparev(cmd, ap); va_end(ap); return start_again(); } int WvSubProc::startv(const char cmd[], const char * const *argv) { preparev(cmd, argv); return start_again(); } int WvSubProc::start_again() { int retval; const char **argptr; assert(!!last_cmd); // create a new argv array from our stored values const char **argv = new const char*[last_args.count() + 1]; WvStringList::Iter i(last_args); for (argptr = argv, i.rewind(); i.next(); argptr++) *argptr = *i; *argptr = NULL; // run the program retval = _startv(last_cmd, argv); // clean up deletev argv; return retval; } int WvSubProc::fork(int *waitfd) { static WvString ldpreload, ldlibrary; running = false; estatus = 0; pid = wvfork_start(waitfd); if (!pid) { // child process // set the process group of this process, so "negative" kill // will kill everything in the whole session, not just the // main process. setpgid(0,0); // set up any extra environment variables WvStringList::Iter i(env); for (i.rewind(); i.next(); ) { WvStringList words; words.splitstrict(*i, "="); WvString name = words.popstr(); WvString value = words.join("="); if (name == "LD_LIBRARY_PATH" && getenv("LD_LIBRARY_PATH")) { if (!!value) { // don't override - merge! ldlibrary = WvString("%s=%s:%s", name, value, getenv("LD_LIBRARY_PATH")); putenv(ldlibrary.edit()); } } else if (name == "LD_PRELOAD" && getenv("LD_PRELOAD")) { if (!!value) { // don't override - merge! ldpreload = WvString("%s=%s:%s", name, value, getenv("LD_PRELOAD")); putenv(ldpreload.edit()); } } else if (!value) { // no equals or setting to empty string? // then we must want to unset it! // This is evil, but this is the most simple unsetenv(name); } else putenv(i->edit()); } } else if (pid > 0) { // parent process running = true; } else if (pid < 0) return -errno; return pid; } pid_t WvSubProc::pidfile_pid() { if (!!pidfile) { // unfortunately, we don't have WvFile in basic wvutils... char buf[1024]; pid_t p = -1; FILE *file = fopen(pidfile, "r"); memset(buf, 0, sizeof(buf)); if (file && fread(buf, 1, sizeof(buf), file) > 0) p = atoi(buf); if (file) fclose(file); if (p <= 0) p = -1; return p; } return -1; } void WvSubProc::kill(int sig) { assert(!running || pid > 0 || !old_pids.isempty()); if (pid > 0) { // if the process group has disappeared, kill the main process // instead. assert(pid != 1); // make sure we don't kill -1 if (::kill(-pid, sig) < 0 && errno == ESRCH) kill_primary(sig); } // kill leftover subprocesses too. pid_tList::Iter i(old_pids); for (i.rewind(); i.next(); ) { pid_t subpid = *i; assert(subpid != 1 && subpid != -1); // make sure we don't kill -1 if (::kill(-subpid, sig) < 0 && errno == ESRCH) ::kill(subpid, sig); } } void WvSubProc::kill_primary(int sig) { assert(!running || pid > 0 || !old_pids.isempty()); if (running && pid > 0) ::kill(pid, sig); } void WvSubProc::stop(time_t msec_delay, bool kill_children) { wait(0); if (running) { if (kill_children) kill(SIGTERM); else kill_primary(SIGTERM); wait(msec_delay, kill_children); } if (running) { if (kill_children) kill(SIGKILL); else kill_primary(SIGKILL); wait(-1, kill_children); } } void WvSubProc::wait(time_t msec_delay, bool wait_children) { bool xrunning; int status; pid_t dead_pid; struct timeval tv1, tv2; struct timezone tz; assert(!running || pid > 0 || !old_pids.isempty()); // running might be false if the parent process is dead and you called // wait(x, false) before. However, if we're now doing wait(x, true), // we want to keep going until the children are dead too. xrunning = (running || (wait_children && !old_pids.isempty())); if (!xrunning) return; gettimeofday(&tv1, &tz); tv2 = tv1; do { if (pid > 0) { // waiting on a process group is unfortunately useless // since you can only get notifications for your direct // descendants. We have to "kill" with a zero signal instead // to try to detect whether they've died or not. dead_pid = waitpid(pid, &status, (msec_delay >= 0) ? WNOHANG : 0); //fprintf(stderr, "%ld: dead_pid=%d; pid=%d\n", // msecdiff(tv2, tv1), dead_pid, pid); if (dead_pid == pid || (dead_pid < 0 && (errno == ECHILD || errno == ESRCH))) { // the main process is dead - save its status. estatus = status; old_pids.append(new pid_t(pid), true); pid_t p2 = pidfile_pid(); if (pid != p2) pid = p2; else pid = -1; } else if (dead_pid < 0) perror("WvSubProc::waitpid"); } // no need to do this next part if the primary subproc isn't dead yet if (pid < 0) { pid_tList::Iter i(old_pids); for (i.rewind(); i.next(); ) { pid_t subpid = *i; // if the subproc is our direct descendant, we'll be able // to kill it forever if it's a zombie. Sigh. waitpid() // on it just in case. waitpid(subpid, NULL, WNOHANG); if (::kill(-subpid, 0) && errno == ESRCH) i.xunlink(); } // if the primary is dead _and_ we either don't care about // children or all our children are dead, then the subproc // isn't actually running. if (!wait_children || old_pids.isempty()) xrunning = false; } // wait a while, so we're not spinning _too_ fast in a loop if (xrunning && msec_delay != 0) usleep(50*1000); gettimeofday(&tv2, &tz); } while (xrunning && msec_delay && (msec_delay < 0 || msecdiff(tv2, tv1) < msec_delay)); if (!xrunning) running = false; } wvstreams-4.6.1/utils/wvstringlist.cc0000644000175000001440000000276111036722347017033 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Some helper functions for WvStringList. * * This is blatantly block-copied from WvStringTable, but I don't care! Hah! * (I just know I'm going to regret this someday...) */ #include "wvstringlist.h" #include "strutils.h" WvString WvStringList::join(const char *joinchars) const { return ::strcoll_join(*this, joinchars); } void WvStringList::split(WvStringParm s, const char *splitchars, int limit) { return ::strcoll_split(*this, s, splitchars, limit); } void WvStringList::splitstrict(WvStringParm s, const char *splitchars, int limit) { return ::strcoll_splitstrict(*this, s, splitchars, limit); } void WvStringList::fill(const char * const *array) { while (array && *array) { append(new WvString(*array), true); array++; } } void WvStringList::append(WvStringParm str) { WvStringListBase::append(new WvString(str), true); } void WvStringList::append(WvString *strp, bool autofree, char *id) { WvStringListBase::append(strp, autofree, id); } // get the first string in the list, or an empty string if the list is empty. // Removes the returned string from the list. WvString WvStringList::popstr() { if (isempty()) return ""; WvString s = *first(); unlink_first(); return s; } #ifndef _WIN32 void WvStringList::split(WvStringParm s, const WvRegex ®ex, int limit) { return ::strcoll_split(*this, s, regex, limit); } #endif wvstreams-4.6.1/utils/wvstring.cc0000644000175000001440000002751711036722347016145 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of a simple and efficient printable-string class. Most * of the class is actually inlined and can be found in wvstring.h. */ #include "wvstring.h" #include #include WvStringBuf WvFastString::nullbuf = { 0, 1 }; const WvFastString WvFastString::null; const WvString WvString::empty(""); // always a handy function static inline int _max(int x, int y) { return x>y ? x : y; } void WvFastString::setsize(size_t i) { unlink(); newbuf(i); } WvFastString::WvFastString() { link(&nullbuf, NULL); } WvFastString::WvFastString(const WvFastString &s) { link(s.buf, s.str); } WvFastString::WvFastString(const WvString &s) { link(s.buf, s.str); } void WvFastString::construct(const char *_str) { // just copy the pointer - no need to allocate memory! str = (char *)_str; // I promise not to change anything! buf = NULL; } WvFastString::WvFastString(const char *_str) { construct(_str); } void WvString::copy_constructor(const WvFastString &s) { unlink(); // WvFastString has already been created by now if (!s.buf) { link(&nullbuf, s.str); unique(); } else link(s.buf, s.str); // already in a nice, safe WvStreamBuf } WvFastString WvFastString::offset(size_t i) const { WvFastString retval(*this); size_t l = retval.len(); retval.str += (i < l ? i : l); return retval; } WvString::WvString(const char *_str) { unlink(); // WvFastString has already been created by now construct(_str); } // This function returns the NULL of a reversed string representation // for unsigned integers template inline static char *wv_uitoar(char *begin, T i) { if (!begin) return NULL; char *end = begin; if (i == 0) *end++ = '0'; else { while (i > 0) { switch (i % 10) { case 0: *end++ = '0'; break; case 1: *end++ = '1'; break; case 2: *end++ = '2'; break; case 3: *end++ = '3'; break; case 4: *end++ = '4'; break; case 5: *end++ = '5'; break; case 6: *end++ = '6'; break; case 7: *end++ = '7'; break; case 8: *end++ = '8'; break; case 9: *end++ = '9'; break; default: ; } i /= 10; } } *end = '\0'; return end; } // This function returns the NULL of a reversed string representation // for signed integers template inline static char *wv_itoar(char *begin, T i) { if (!begin) return NULL; bool negative = false; if (i < 0) { negative = true; i = -i; } char *end = wv_uitoar(begin, i); if (negative) { *end++ = '-'; *end = '\0'; } return end; } inline static void wv_strrev(char *begin, char *end) { if (!begin && !end) return; --end; while (begin < end) { *begin ^= *end; *end ^= *begin; *begin ^= *end; ++begin; --end; } } // NOTE: make sure that 32 bytes is big enough for your longest int. // This is true up to at least 64 bits. WvFastString::WvFastString(short i) { newbuf(32); wv_strrev(str, wv_itoar(str, i)); } WvFastString::WvFastString(unsigned short i) { newbuf(32); wv_strrev(str, wv_uitoar(str, i)); } WvFastString::WvFastString(int i) { newbuf(32); wv_strrev(str, wv_itoar(str, i)); } WvFastString::WvFastString(unsigned int i) { newbuf(32); wv_strrev(str, wv_uitoar(str, i)); } WvFastString::WvFastString(long i) { newbuf(32); wv_strrev(str, wv_itoar(str, i)); } WvFastString::WvFastString(unsigned long i) { newbuf(32); wv_strrev(str, wv_uitoar(str, i)); } WvFastString::WvFastString(long long i) { newbuf(32); wv_strrev(str, wv_itoar(str, i)); } WvFastString::WvFastString(unsigned long long i) { newbuf(32); wv_strrev(str, wv_uitoar(str, i)); } WvFastString::WvFastString(double i) { newbuf(32); sprintf(str, "%g", i); } WvFastString::~WvFastString() { unlink(); } void WvFastString::unlink() { if (buf && ! --buf->links) { free(buf); buf = NULL; } } void WvFastString::link(WvStringBuf *_buf, const char *_str) { buf = _buf; if (buf) buf->links++; str = (char *)_str; // I promise not to change it without asking! } WvStringBuf *WvFastString::alloc(size_t size) { WvStringBuf *abuf = (WvStringBuf *)malloc( (WVSTRINGBUF_SIZE(buf) + size + WVSTRING_EXTRA) | 3); abuf->links = 0; abuf->size = size; return abuf; } WvString &WvString::append(WvStringParm s) { if (s) { if (*this) *this = WvString("%s%s", *this, s); else *this = s; } return *this; } size_t WvFastString::len() const { return str ? strlen(str) : 0; } void WvFastString::newbuf(size_t size) { buf = alloc(size); buf->links = 1; str = buf->data; } // If the string is linked to more than once, we need to make our own copy // of it. If it was linked to only once, then it's already "unique". WvString &WvString::unique() { if (!is_unique() && str) { WvStringBuf *newb = alloc(len() + 1); memcpy(newb->data, str, newb->size); unlink(); link(newb, newb->data); } return *this; } bool WvString::is_unique() const { return (buf->links <= 1); } WvFastString &WvFastString::operator= (const WvFastString &s2) { if (s2.buf == buf && s2.str == str) return *this; // no change else { unlink(); link(s2.buf, s2.str); } return *this; } WvString &WvString::operator= (int i) { unlink(); newbuf(32); sprintf(str, "%d", i); return *this; } WvString &WvString::operator= (const WvFastString &s2) { if (s2.str == str && (!s2.buf || s2.buf == buf)) return *this; // no change else if (!s2.buf) { // We have a string, and we're about to free() it. if (str && buf && buf->links == 1) { // Set buf->size, if we don't already know it. if (buf->size == 0) buf->size = strlen(str); if (str < s2.str && s2.str <= (str + buf->size)) { // If the two strings overlap, we'll just need to // shift s2.str over to here. memmove(buf->data, s2.str, buf->size); return *this; } } // assigning from a non-copied string - copy data if needed. unlink(); link(&nullbuf, s2.str); unique(); } else { // just a normal string link unlink(); link(s2.buf, s2.str); } return *this; } // string comparison bool WvFastString::operator== (WvStringParm s2) const { return (str==s2.str) || (str && s2.str && !strcmp(str, s2.str)); } bool WvFastString::operator!= (WvStringParm s2) const { return (str!=s2.str) && (!str || !s2.str || strcmp(str, s2.str)); } bool WvFastString::operator< (WvStringParm s2) const { if (str == s2.str) return false; if (str == 0) return true; if (s2.str == 0) return false; return strcmp(str, s2.str) < 0; } bool WvFastString::operator== (const char *s2) const { return (str==s2) || (str && s2 && !strcmp(str, s2)); } bool WvFastString::operator!= (const char *s2) const { return (str!=s2) && (!str || !s2 || strcmp(str, s2)); } bool WvFastString::operator< (const char *s2) const { if (str == s2) return false; if (str == 0) return true; if (s2 == 0) return false; return strcmp(str, s2) < 0; } // not operator is 'true' if string is empty bool WvFastString::operator! () const { return !str || !str[0]; } /** * parse a 'percent' operator from a format string. For example: * cptr out: zeropad justify maxlen argnum return pointer * "%s" false 0 0 0 "s" * "%-15s" false -15 0 0 "s" * "%15.5s" false 15 5 0 "s" * "%015.5s" true 15 5 0 "s" * "%15$2s" false 15 0 2 "s" * and so on. On entry, cptr should _always_ point at a percent '%' char. * argnum is the argument number. */ static const char *pparse(const char *cptr, bool &zeropad, int &justify, int &maxlen, int &argnum) { assert(*cptr == '%'); cptr++; zeropad = (*cptr == '0'); justify = atoi(cptr); for (; *cptr && *cptr!='.' && *cptr!='%' && *cptr!='$' && !isalpha(*cptr); cptr++) ; if (!*cptr) return cptr; if (*cptr == '.') maxlen = atoi(cptr+1); else maxlen = 0; for (; *cptr && *cptr!='%' && *cptr!='$' && !isalpha(*cptr); cptr++) ; if (!*cptr) return cptr; if (*cptr == '$') argnum = atoi(cptr+1); else argnum = 0; for (; *cptr && *cptr!='%' && !isalpha(*cptr); cptr++) ; return cptr; } /** * Accept a printf-like format specifier (but more limited) and an array * of WvStrings, and render them into another WvString. For example: * WvString x[] = {"foo", "blue", 1234}; * WvString ret = WvString::do_format("%s%10.2s%-10s", x); * * The 'ret' string will be: "foo bl1234 " * Note that only '%s' is supported, though integers can be rendered * automatically into WvStrings. %d, %f, etc are not allowed! * * This function is usually called from some other function which allocates * the array automatically. * * %$ns (n > 0) is also supported for internationalization purposes. e.g. * ("%$2s is arg2, and %$1s ia arg1", arg1, arg2) */ void WvFastString::do_format(WvFastString &output, const char *format, const WvFastString * const *argv) { static const char blank[] = "(nil)"; const WvFastString * const *argptr = argv; const WvFastString * const *argP; const char *iptr = format, *arg; char *optr; int total = 0, aplen, ladd, justify, maxlen, argnum; bool zeropad; // count the number of bytes we'll need while (*iptr) { if (*iptr != '%') { total++; iptr++; continue; } // otherwise, iptr is at a percent expression argnum=0; iptr = pparse(iptr, zeropad, justify, maxlen, argnum); if (*iptr == '%') // literal percent { total++; iptr++; continue; } assert(*iptr == 's' || *iptr == 'c'); if (*iptr == 's') { argP = (argnum > 0 ) ? (argv + argnum -1): argptr; if (!*argP || !(**argP).cstr()) arg = blank; else arg = (**argP).cstr(); ladd = _max(abs(justify), strlen(arg)); if (maxlen && maxlen < ladd) ladd = maxlen; total += ladd; if ( argnum <= 0 ) argptr++; iptr++; continue; } if (*iptr++ == 'c') { if (argnum <= 0) argptr++; total++; } } output.setsize(total + 1); // actually render the final string iptr = format; optr = output.str; argptr = argv; while (*iptr) { if (*iptr != '%') { *optr++ = *iptr++; continue; } // otherwise, iptr is at a "percent expression" argnum=0; iptr = pparse(iptr, zeropad, justify, maxlen, argnum); if (*iptr == '%') { *optr++ = *iptr++; continue; } if (*iptr == 's') { argP = (argnum > 0 ) ? (argv + argnum -1): argptr; if (!*argP || !(**argP).cstr()) arg = blank; else arg = (**argP).cstr(); aplen = strlen(arg); if (maxlen && maxlen < aplen) aplen = maxlen; if (justify > aplen) { if (zeropad) memset(optr, '0', justify-aplen); else memset(optr, ' ', justify-aplen); optr += justify-aplen; } strncpy(optr, arg, aplen); optr += aplen; if (justify < 0 && -justify > aplen) { if (zeropad) memset(optr, '0', -justify-aplen); else memset(optr, ' ', -justify-aplen); optr += -justify - aplen; } if ( argnum <= 0 ) argptr++; iptr++; continue; } if (*iptr++ == 'c') { argP = (argnum > 0 ) ? (argv + argnum -1): argptr++; if (!*argP || !(**argP)) arg = " "; else arg = (**argP); *optr++ = (char)atoi(arg); } } *optr = 0; } wvstreams-4.6.1/utils/wvcont.cc0000644000175000001440000001436711036722347015601 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvCont provides "continuations", which are apparently also known as * semi-coroutines. See wvcont.h for more details. */ #include "wvcont.h" #include "wvtask.h" #include "wvlinklist.h" #include // private data that doesn't need to be in the header struct WvCont::Data { int links; // the refcount of this Data object int mydepth; // this task's depth in the call stack bool finishing; // true if we're trying to terminate this task ASAP // (generally because WvCont is being destroyed) size_t stacksize; WvTaskMan *taskman; WvTask *task; WvContCallback cb; // the callback we want to call inside our WvTask void *ret; void *p1; Data(const WvContCallback &_cb, size_t _stacksize) : cb(_cb) { links = 1; finishing = false; stacksize = _stacksize; mydepth = 0; taskman = WvTaskMan::get(); task = NULL; report(); if (data_list == NULL) data_list = new DataList; data_list->append(this, false); } ~Data(); void link() { links++; report(); } void unlink() { links--; report(); if (!links) delete this; } void report() { /* printf("%p: links=%d\n", this, links); */ } }; WvCont::Data *WvCont::curdata = NULL; int WvCont::taskdepth = 0; WvCont::DataList *WvCont::data_list = NULL; WvCont::WvCont(const WvCont &cb) { static bool first = true; if (first) { first = false; WvStreamsDebugger::add_command("conts", 0, debugger_conts_run_cb, 0); } data = cb.data; data->link(); } WvCont::WvCont(const WvContCallback &cb, unsigned long _stacksize) { data = new Data(cb, (size_t)_stacksize); } WvCont::WvCont(Data *data) { this->data = data; data->link(); } WvCont::~WvCont() { if (data->links == 1) // I'm the last link, and it's not currently running { data->finishing = true; data->p1 = NULL; // don't re-pass invalid data while (data->task && data->task->isrunning()) call(); } data->unlink(); } WvCont::Data::~Data() { assert(!links); if (task) task->recycle(); taskman->unlink(); //printf("%p: deleting\n", this); report(); data_list->unlink(this); if (data_list->isempty()) { delete data_list; data_list = NULL; } } static inline const char *Yes_No(bool val) { return val? "Yes": "No"; } WvString WvCont::debugger_conts_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *) { const char *format = "%5s%s%5s%s%9s%s%10s%s%7s%s%s"; WvStringList result; result.append(format, "Links", "-", "Depth", "-", "Finishing", "-", "Stack Size", "-", "Task ID", "-", "Task Name------"); result_cb(cmd, result); if (!data_list) return WvString::null; DataList::Iter i(*data_list); for (i.rewind(); i.next(); ) { result.zap(); result.append(format, i->links, " ", i->mydepth, " ", Yes_No(i->finishing), " ", i->stacksize, " ", i->task? WvString(i->task->get_tid()): WvString("n/a"), " ", i->task? i->task->get_name(): WvString("n/a")); result_cb(cmd, result); } return WvString::null; } // note: assumes data->task is already running! void *WvCont::_call(Data *data) { Data *olddata = curdata; curdata = data; data->link(); // don't delete this context while it's running! // enforce the call stack. If we didn't do this, a yield() five calls // deep would return to the very top, rather to the second-innermost // context. // // Note that this implementation has the interesting side-effect of // short-circuiting recursion (a calls b, b calls c, c calls a), since // calling 'a' if it's already running means the same as "yield all the // way back to a", and this loop enforces one-level-at-a-time yielding. // // Because that behaviour is probably undesirable, we make 'mydepth' into // a member variable instead of just putting it on the stack. This is // only needed so that we can have the assert(). assert(!data->mydepth); data->mydepth = ++taskdepth; do { assert(data->task); do { data->taskman->run(*data->task); if (data->links == 1) { data->finishing = true; // make WvCont::isok() false data->p1 = NULL; // don't re-pass invalid data } } while (data->finishing && data->task && data->task->isrunning()); assert(data->links); } while (taskdepth > data->mydepth); assert(taskdepth == data->mydepth); taskdepth--; data->mydepth = 0; void *ret = data->ret; data->unlink(); curdata = olddata; return ret; } void *WvCont::operator() (void *p1) { data->ret = reinterpret_cast(-42); if (!data->task) data->task = data->taskman->start("wvcont", bouncer, data, data->stacksize); else if (!data->task->isrunning()) data->task->start("wvcont+", bouncer, data); assert(data->task); data->p1 = p1; return call(); } WvCont WvCont::current() { assert(curdata); assert(curdata->task == curdata->taskman->whoami()); assert(isok()); // this assertion is a bit aggressive... return WvCont(curdata); } void *WvCont::yield(void *ret) { assert(curdata); assert(curdata->task == curdata->taskman->whoami()); // this assertion is a bit aggressive, but on purpose; a callback that // does yield() instead of returning when its context should be dying // is pretty badly behaved. assert(isok()); curdata->ret = ret; curdata->taskman->yield(); return curdata->p1; } bool WvCont::isok() { // if we're not using WvCont, it's not okay to yield if (!curdata) return false; assert(curdata->task == curdata->taskman->whoami()); return !curdata->finishing; } void WvCont::bouncer(void *userdata) { Data *data = (Data *)userdata; // DON'T BE FOOLED! // all yield() calls stay inside the inner function; our return value // is only for the final run after data->cb() returns. data->ret = data->cb(data->p1); } wvstreams-4.6.1/utils/tests/0000755000175000001440000000000011260431131015064 5ustar wlachuserswvstreams-4.6.1/utils/tests/stresshashtest.cc0000644000175000001440000000434111202637334020475 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvHashTable stress tester. Adds a lot of elements to the table and * looks them up, iterates through them, etc. This requires lots of memory. * */ #include "wvhashtable.h" #include "wvstring.h" #include #include #ifndef MACOS # include #else # include #endif struct Intstr { int i; WvString s; Intstr(int _i, WvStringParm _s) { i = _i; s = _s; } }; DeclareWvDict(Intstr, WvString, s); const unsigned size = 1000, elems = 10000; int main() { //free(malloc(1)); // enable electric fence IntstrDict d(size); unsigned count, total; for (count = 0; count < elems; count++) { if (elems > 100 && !(count % (elems/20))) { printf("\rAdding %d%%", count / (elems/100)); fflush(stdout); } d.add(new Intstr(count, count), true); } printf("\rAdded: total %d (should be %d)\n", d.count(), elems); total = 0; for (count = 0; count < d.numslots; count++) { WvLink *head = &d.wvslots[count].head; if (!head->next) total++; } printf("%d of %d empty slots in the table.\n", total, d.numslots); printf("Avg chain length: %d (best %d)\n", elems / (d.numslots - total), elems / d.numslots); printf("Removing..."); fflush(stdout); for (count = 0; count < elems; count += 5) { assert(d[count]); d.remove(d[count]); } printf("\rRemoved. New count: %d (should be %d)\n", d.count(), elems - elems/5); IntstrDict::Iter i(d); total = d.count(); count = 0; for (i.rewind(); i.next(); ) { if (total > 20 && !(count % (total/20))) { printf("\rIterate %d%%", count / (total/100)); fflush(stdout); } assert(i->s == WvString(i->i)); count++; } printf("\rIterator okay.\n"); for (count = 0; count < total; count++) { if (total > 100 && !(count % (total/20))) { printf("\rSlow Iterate %d%%", count / (total/100)); fflush(stdout); } assert(!(count%5) || (d[count] && d[count]->s == WvString(d[count]->i))); } printf("\rOne-by-one iterator okay.\n"); return 0; } wvstreams-4.6.1/utils/tests/urlencodetest.cc0000644000175000001440000000054511077367676020313 0ustar wlachusers#include int main(int argc, char *argv[]) { const char *input = "http://www.free_email-account.com/~ponyman/mail.pl?name=\'to|\\|Y |)4|\\|Z4\'&pass=$!J83*p&folder=1N8()><"; for (int i=0; i<100000; i++) { if ((i % 100000) == 0) { printf("Done: %i\n", i); } url_encode(input); } } wvstreams-4.6.1/utils/tests/monikertest.cc0000644000175000001440000000305711077364544017767 0ustar wlachusers#include "wvmoniker.h" #include "wvmonikerregistry.h" #include class ITest : public IObject { public: virtual void f() = 0; virtual ~ITest() {} }; DEFINE_IID(ITest, {0xcd3239a7, 0x0ea1, 0x4e1a, {0xba, 0x08, 0xb8, 0x5e, 0xe4, 0xda, 0xad, 0x69}}); class Test : public ITest { IMPLEMENT_IOBJECT(Test) public: WvString s; Test(WvStringParm _s) : s(_s) { printf("%p(\"%s\"): creating!\n", this, s.cstr()); } virtual ~Test() { printf("%p(\"%s\"): destroying!\n", this, s.cstr()); } virtual void f() { printf("%p(\"%s\"): f() called!\n", this, s.cstr()); } }; UUID_MAP_BEGIN(Test) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(ITest) UUID_MAP_END static IObject *createfunc(WvStringParm s, IObject*) { return new Test(s); } static IObject *createfunc2(WvStringParm s, IObject*) { return new Test(WvString("bunk(%s)", s)); } static ITest *createfunc3(WvStringParm s, IObject*) { return new Test(WvString("stunk(%s)", s)); } int main() { WvMoniker junk("obj", createfunc); WvMoniker bunk("obj2", createfunc2); WvMoniker stunk("test", createfunc3); WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(IObject_IID); IObject *a = (IObject *)reg->create("obj:obj-a", NULL); IObject *b = (IObject *)reg->create("obj2:obj2-b", NULL); WVRELEASE(reg); IObject *c = wvcreate("obj2:obj2-c"); ITest *d = wvcreate("test:test-d"); if (d) d->f(); WVRELEASE(a); WVRELEASE(b); WVRELEASE(c); WVRELEASE(d); } wvstreams-4.6.1/utils/tests/diriter2test.cc0000644000175000001440000000051511036722347020035 0ustar wlachusers#include "wvdiriter.h" int main() { int guard1 = 0; int guard2 = 0; int guard3 = 0; int guard4 = 0; printf("Before: %d %d %d %d\n", guard1, guard2, guard3, guard4); WvDirIter i("/"); WvDirIter *i2 = new WvDirIter("/"); printf("After: %d %d %d %d\n", guard1, guard2, guard3, guard4); delete i2; } wvstreams-4.6.1/utils/tests/replacetest.cc0000644000175000001440000000026511036722347017726 0ustar wlachusers#include "strutils.h" #include int main() { puts(strreplace("abbababababbba", "ba", "xax")); puts(strreplace("abbababababbbablab", "ba", "xax")); return 0; } wvstreams-4.6.1/utils/tests/maptest.cc0000644000175000001440000000123311036722347017064 0ustar wlachusers#include #include #include "wvstring.h" using std::map; int main () { map mymap; fprintf(stderr, "added foo = bar\n"); mymap["foo"] = "bar"; fprintf(stderr, "looked up foo = %s\n", mymap.find("foo")->second.cstr()); mymap.erase("foo"); assert(mymap.find("foo") == mymap.end()); mymap["meaw"] = "death"; mymap["dog"] = "cow"; mymap["star"] = "trek"; mymap["star"] = "office"; // Iterator test map::iterator it; for (it = mymap.begin(); it != mymap.end(); ++it) fprintf(stderr, "Iter test: %s = %s\n", it->first.cstr(), it->second.cstr()); } wvstreams-4.6.1/utils/tests/magiccircletest.cc0000644000175000001440000000212511036722347020552 0ustar wlachusers #include "wvmagiccircle.h" #include #include #include #include int main() { WvMagicCircle q(999); char buf[1024], buf2[1024]; size_t len; size_t i; srandom(0); if (q.geterr()) { fprintf(stderr, "q: %s\n", q.errstr().cstr()); return 1; } if (fork() > 0) { // parent for (i = 1; i < 1000; i++) { while (q.used() < i) { //usleep(1*1000); //printf("."); //fflush(stdout); } q.skip(1); len = q.get(buf, i-1); memset(buf2, i % 256, i); if (i == 999) { assert(memcmp(buf, buf2, i)); printf("Comparison failed at 999, as expected. Done!\n"); break; } assert(!memcmp(buf, buf2, i-1)); printf(" << %d\n", i); } assert(!q.used()); } else { // child for (i = 1; i <= 999; i++) { printf(">> %d\n", i); memset(buf, i % 256, i); if (i == 999) buf[5]++; while (q.left() < i) ; //usleep(1*1000); q.put(buf, i); } } return 0; } wvstreams-4.6.1/utils/tests/hashtest.cc0000644000175000001440000000465011036722347017240 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvHashTable test program. (One) correct output: * * Hash table size: 15 * String hash test: * 000019ef 000132a5 000a4aa5 00000000 * f3ad1ec0 f3ad1ec0 f3ad5ac0 f3ad1fd0 * Correct answers are: 0xbffffaf0 0xbffffae8 0xbffffae0 (0xbffffac0) * * Result: 0xbffffaf0 0xbffffae8 0xbffffae0 (nil) * Full(3) contents: 0x804f167(blue) 0x804f163(foo) 0x804f16c(true) * * Result: (nil) (nil) 0xbffffae0 (nil) * Full(1) contents: 0x804f16c(true) * * Dict Result: 0xbffffaa0 0xbffffa8c 0xbffffa80 (nil) * Dict Result: 0xbffffaa0 (nil) 0xbffffa80 (nil) */ #include "wvhashtable.h" #include "wvstring.h" #include DeclareWvTable(WvString); struct Intstr { int i; WvString s; Intstr(int _i, WvStringParm _s) { i = _i; s = _s; } }; DeclareWvDict(Intstr, int, i); int main() { WvString x("foo"), y("blue"), z("true"); WvString x2("foo"), y2("blue"), z2("true"), xx("wuzzy"); WvStringTable t(10); printf("Hash table size: %d\n", t.numslots); t.add(&x, false); t.add(&y, false); t.add(&z, false); printf("String hash test: \n\t %08x %08x %08x %08x \n" "\t %08x %08x %08x %08x\n", WvHash(x), WvHash(y), WvHash(z), WvHash((const char *)0), WvHash("fuzzy wuzzy buzzy foo"), WvHash("FUZZY wuzzy BUZZY foo"), WvHash("fuzzy wuzzy buzzy woo"), WvHash("wuzzy wuzzy buzzy foo")); printf("Correct answers are: %p %p %p (%p)\n\n", &x, &y, &z, &xx); printf("Result: %p %p %p %p\n", t[x2], t[y2], t[z2], t[xx]); WvStringTable::Iter i(t); printf("Full(%d) contents: ", t.count()); for (i.rewind(); i.next(); ) printf("%p(%s) ", (const char *)i(), (const char *)i()); printf("\n\n"); t.remove(&x); t.remove(&y2); printf("Result: %p %p %p %p\n", t[x2], t[y2], t[z2], t[xx]); printf("Full(%d) contents: ", t.count()); for (i.rewind(); i.next(); ) printf("%p(%s) ", (const char *)i(), (const char *)i()); printf("\n\n"); Intstr a(5, "big"), b(6, "whistle"), c(7, "money"); IntstrDict d(10); d.add(&a, false); d.add(&b, false); d.add(&c, false); printf("Dict Result: %p %p %p %p\n", d[a.i], d[b.i], d[7], d[10]); d.remove(&b); printf("Dict Result: %p %p %p %p\n", d[a.i], d[b.i], d[7], d[10]); return 0; } wvstreams-4.6.1/utils/tests/serializetest.cc0000644000175000001440000000533011036722347020300 0ustar wlachusers#include "wvserialize.h" struct Silly { int big; long bigger; short small; WvString s1; bool b; WvString s2; void print() { printf("Silly: %d %ld %d '%s' %d '%s'\n", big, bigger, small, s1.cstr(), b, s2.cstr()); } }; void _wv_serialize(WvBuf &buf, const Silly &s) { wv_serialize(buf, s.big); wv_serialize(buf, (int)s.bigger); wv_serialize(buf, s.small); wv_serialize(buf, s.s1); wv_serialize(buf, s.b); wv_serialize(buf, s.s2); } template <> Silly *_wv_deserialize(WvBuf &buf) { Silly *s = new Silly; s->big = wv_deserialize(buf); s->bigger = wv_deserialize(buf); s->small = wv_deserialize(buf); s->s1 = wv_deserialize(buf); s->b = wv_deserialize(buf); s->s2 = wv_deserialize(buf); return s; } template <> Silly _wv_deserialize(WvBuf &buf) { Silly *tmp = _wv_deserialize(buf); Silly tmp2 = *tmp; delete tmp; return tmp2; } DeclareWvList(int); int main() { WvDynBuf buf; bool bb = false; wv_serialize(buf, "hello"); wv_serialize(buf, 5U); wv_serialize(buf, (short)7); wv_serialize(buf, true); wv_serialize(buf, bb); wv_serialize(buf, 'x'); printf("buf used: %d\n", buf.used()); printf("got: '%s'\n", wv_deserialize(buf).cstr()); printf("buf used: %d\n", buf.used()); printf("got: %d\n", wv_deserialize(buf)); printf("got: %d\n", wv_deserialize(buf)); printf("got: %d\n", wv_deserialize(buf)); printf("got: %d\n", wv_deserialize(buf)); printf("got: '%c'\n", wv_deserialize(buf)); printf("\n"); buf.zap(); Silly s = {5, 6, 7, "hello", false, "world"}; s.print(); wv_serialize(buf, s); s.print(); printf("buf used: %d\n", buf.used()); WvBufCursor buf2(buf, 0, buf.used()); Silly *s2 = wv_deserialize(buf2); s2->print(); delete s2; printf("buf used: %d/%d\n", buf2.used(), buf.used()); Silly s3 = wv_deserialize(buf); s3.print(); buf.zap(); intList list; list.append(new int(7), true); list.append(new int(5), true); list.append(new int(1231), true); list.append(new int(973), true); wv_serialize(buf, list); printf("buf used: %d\n", buf.used()); WvDynBuf xbuf; wv_serialize(xbuf, buf); WvBuf *xbuf2 = wv_deserialize(xbuf); intList *list2 = wv_deserialize(*xbuf2); delete xbuf2; printf("%d list elements after deserialize.\n", list.count()); intList::Iter i(*list2); for (i.rewind(); i.next(); ) printf(" ... %d\n", *i); delete list2; return 0; } wvstreams-4.6.1/utils/tests/strtest.cc0000644000175000001440000000657611036722347017136 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvString test program. Correct results: * * A WvString is 8 bytes long. * Foo Foo * 0 1 0 0 1 * 1 0 1 1 0 * 1 0 0 1 * 0 1 * 0 1 * Foo * 1 1 0 * 0 1 0 0 * hello * xyzzi 5 hello b * uest string * vest string * vest string .. west string */ #include "wvstring.h" WvString t1, t2, t3, t4, t5, t6; char globuf[1024]; /* this function is mainly for looking at the assembly output */ void format_test() { WvString s(t1, t2, t3, t4, t5, t6); } WvString test1(WvString s) { s.edit()[0]++; return s; } void fptestfunc(WvStringParm fp1, WvStringParm fpf1, WvStringParm fp2, WvStringParm fpf2) { WvString a(fp1), b(fpf1), c(fp2), d(fpf2); printf("before: %s/%s/%s/%s\n", a.cstr(), b.cstr(), c.cstr(), d.cstr()); strcpy(globuf, "ZOT!"); printf("after: %s/%s/%s/%s\n", a.cstr(), b.cstr(), c.cstr(), d.cstr()); } int main() { printf("A WvString is %d bytes long.\n", sizeof(WvString)); WvString a, b("Foo"), c("Foo"), d("Blue"), e; const char *ca = "Fork", *cb = "Foo", *cc = "Foo", *cd = NULL; { WvString *x = new WvString(a); WvString *y = new WvString(b); printf("%s %s\n", (const char *)b, (const char *)*y); delete y; delete x; } // 0 1 0 0 1 printf("%d %d %d %d %d\n", a == b, b == c, c == d, d == e, e == a); // 1 0 1 1 0 printf("%d %d %d %d %d\n", a != b, b != c, c != d, d != e, e != a); // 1 0 0 1 printf("%d %d %d %d\n", !a, !b, !c, !e); e = c; // 0 1 printf("%d %d\n", e == a, e == b); e = e; // 1 0 printf("%d %d\n", e == a, e == b); e = cb; // 1 1 0 printf("%s\n", (const char *)e); printf("%d %d %d\n", e == cb, e == cc, e == cd); // 0 1 0 0 printf("%d %d %d %d\n", a == ca, b == cb, d == cb, d == cd); // formatting test WvString ft0("%s", "hello"); printf("%s\n", (const char *)ft0); WvString ft("%s %-40s %s %10s", "xyzzi", 5, "hello", "b"); printf("%s\n", (const char *)ft); // parameter passing test WvString s(test1("test string")); printf("%s\n", (const char *)s); s = test1(s); printf("%s\n", (const char *)s); WvString t; t = test1(s); printf("%s .. %s\n", (const char *)s, (const char *)t); // NULL value tests. NULL strings are different from zero-length strings. // null: ok1 // null: 1 1 0 1 0 // null: 0 1 1 1 0 WvString n1, n2((const char *)NULL), n3(n1), n4("foo"), n5("blah"), n6(""); n4 = n1; n1 = n4; n5 = n1; printf("null: ok1\n"); printf("null: %d %d %d %d %d\n", !n1, !n2, n1.len(), n1==n2, n3.num()); n3.append("junk"); printf("null: %d %d %d %d %d\n", n1==n6, !n1, !n6, n1==NULL, n6==NULL); WvString ns("%s %s %s %s %s %s\n", n1, n2, n3, n4, n5, n6); printf("null: %s\n", ns.cstr()); // fast parameter passing test strcpy(globuf, "TestOne"); WvString fp1(globuf); WvFastString fpf1(globuf); strcpy(globuf, "Bonk2"); WvString fp2(globuf); WvFastString fpf2(globuf); printf("%s/%s/%s/%s\n", fp1.cstr(), fpf1.cstr(), fp2.cstr(), fpf2.cstr()); fptestfunc(fp1, fpf1, fp2, fpf2); fptestfunc(fp1, fpf1, fp2, fpf2); return 0; } wvstreams-4.6.1/utils/tests/cbweirdtest.cc0000644000175000001440000000045111036722347017727 0ustar wlachusers#include "wvtr1.h" typedef wv::function Cb; void f() { // nothing } class Derived : public Cb { public: Derived(const Cb &cb) : Cb(cb) { } }; int main() { Cb cb1(f); Cb cb2(cb1); Derived cb3(f); Derived cb4(cb1); Derived cb5(cb3); return 0; } wvstreams-4.6.1/utils/tests/listtest.cc0000644000175000001440000000215011036722347017261 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvStringList test program. Correct results: * Thingy: foo * Thingy: blue * Thingy: true * Dingy: 6 * Dingy: 5 */ #include "wvstringlist.h" #include DeclareWvList(int); int main() { WvString x("foo"), y("blue"), z("true"), bob("Foo: bar: baz: bob"); WvStringList l; WvStringList::Iter i(l); l.append(&x, false); l.append(&y, false); l.append(&z, false); for (i.rewind(); i.next();) printf("Thingy: %s\n", i().cstr()); l.zap(); l.split(bob, ": "); for (i.rewind(); i.next();) printf("Stingy: %s\n", i().cstr()); l.zap(); l.split(bob, ": ", 2); for (i.rewind(); i.next();) printf("Stingy(2): %s\n", i().cstr()); l.zap(); l.split(bob, ": ", 3); for (i.rewind(); i.next();) printf("Stingy(3): %s\n", i().cstr()); int a=5, b=6; intList il; intList::Iter ii(il); il.prepend(&a, false); il.prepend(&b, false); ii.rewind(); while (ii.next()) printf("Dingy: %d\n", ii()); return 0; } wvstreams-4.6.1/utils/tests/hosttest.cc0000644000175000001440000000047611036722347017274 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * Test for the * */ #include "strutils.h" #include int main() { printf("Hostname: %s\n", hostname().cstr()); printf("Fully Qualified Host Name: %s\n", fqdomainname().cstr()); return 0; } wvstreams-4.6.1/utils/tests/tcltest.cc0000644000175000001440000000465711036722347017106 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #include "wvtclstring.h" #include "wvstringlist.h" #include "wvstringmask.h" int main(int argc, char **argv) { WvStringMask nasties(WVTCL_NASTY_SPACES); WvStringMask splitchars(WVTCL_SPLITCHARS); bool bad = false; // correct output (all on one line): // 'chicken hammer {} {banana split} {shameless{frog}parts} // big\}monkey\ \{potatoes {hammer\}time} {"quotable quote"}' static const char *strarray[] = { "chicken", "hammer", "", "banana split", "split\nends", "shameless{frog}parts", "big}monkey {potatoes", "hammer\\}time", "\"quotable quote\"", NULL }; WvStringList l; l.fill(strarray); WvString ls(wvtcl_encode(l, nasties, splitchars)); printf(" List: '%s'\n", ls.cstr()); printf("Unescaped: '%s'\n", wvtcl_unescape(ls).cstr()); // wvtcl_encode (like the real tcl list encoder) will never put things // in quotes by itself. However, the list decoder needs to be able to // handle them, in case the user provides them by hand. So we'll just // tack some quoted strings onto the end. // // We also take this opportunity to test handling of whitespace. // ls.append(" \n \t \"unquotable quote\"\r\n"); ls.append(" \"{embraced\\nunquotable}\" \"quote\"whacker"); // add the expected new strings to the end of the main list, for comparison // purposes below. l.append(new WvString("unquotable quote"), true); l.append(new WvString("{embraced\nunquotable}"), true); l.append(new WvString("quote"), true); l.append(new WvString("whacker"), true); printf("\nList split results:\n"); WvStringList l2; wvtcl_decode(l2, ls, splitchars); WvStringList::Iter i(l), i2(l2); for (i.rewind(), i2.rewind(); i.next(), i2.next(), true; ) { if (!i.cur() && !i2.cur()) break; if (!i.cur()) { printf("Extra element in list 2: '%s'\n", i2->cstr()); bad = true; break; } if (!i2.cur()) { printf("Extra element in list 1: '%s'\n", i->cstr()); bad = true; break; } printf(" '%s'\n", i2->cstr()); if (*i != *i2) { printf(" --> should be '%s'\n", i->cstr()); bad = true; } } if (bad) printf("Lists don't match!\n"); else printf("Lists match.\n"); return bad; } wvstreams-4.6.1/utils/tests/rateadjtest.cc0000644000175000001440000000246111036722347017725 0ustar wlachusers#include "wvrateadjust.h" #include "wvlog.h" #include "strutils.h" #define MSEC_SLEEP 1000 #define SAMPSIZE 2 #define INRATE 100 #define OUTRATE 105 #define BLK (INRATE * SAMPSIZE * MSEC_SLEEP / 1000) int main() { assert((BLK % SAMPSIZE) == 0); WvDynBuf inbuf, outbuf, outbuf2; const void *ptr; char chunk[BLK]; int n = 0; size_t total = 0, total2 = 0, used; WvTime epoch = wvtime(); WvLog test("rateadjtest", WvLog::Info); WvLog dump("Outbuf", WvLog::Debug2); WvRateAdjust adj(SAMPSIZE, INRATE, OUTRATE), adj2(SAMPSIZE, OUTRATE, &adj); for (int i = 0; i < (int)sizeof(chunk); i++) chunk[i] = (i+1) % 256; for (;;) { usleep(1000*MSEC_SLEEP); n = msecdiff(wvtime(), epoch); inbuf.put(chunk, sizeof(chunk)); adj.encode(inbuf, outbuf); used = outbuf.used(); total += used; test("FWD: blk=%s, out=%s (%s.%s/sec)\n", sizeof(chunk), total, total * 1000 / n, (total * 10000 / n) % 10); ptr = outbuf.get(used); //dump("%s\n", hexdump_buffer(chunk, sizeof(chunk))); dump("%s\n", hexdump_buffer(ptr, used < 64 ? used : 64)); outbuf.unget(used); adj2.encode(outbuf, outbuf2); total2 += outbuf2.used(); outbuf2.zap(); test("REV: out=%s (%s.%s/sec)\n", total2, total2 * 1000 / n, (total2 * 10000 / n) % 10); } } wvstreams-4.6.1/utils/tests/forktest.cc0000644000175000001440000000141211036722347017247 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * small program to test the wvfork() function. * * correct output is: * 1 * 2 * 3 */ #include #include #include #include "wvfork.h" int main() { pid_t pid = 0; fcntl(1, F_SETFD, FD_CLOEXEC); // make stdout close-on-exec pid = wvfork(1); // but don't close it this time! if (pid != 0) { // parent printf("1\n"); waitpid(pid, NULL, 0); } else { // child printf("2\n"); pid = wvfork(); // close it this time. if (pid != 0) { // parent printf("3\n"); waitpid(pid, NULL, 0); } else { // child printf("4\n"); // should NOT be printed! } } return (0); } wvstreams-4.6.1/utils/tests/ver.cc0000644000175000001440000000204411036722347016204 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Takes a string on the command line and attempts to turn it into a * hexadecimal version number. * * Mainly useful, stupidly enough, for the softupdate database. */ #include "verstring.h" #include #include int main(int argc, char *argv[]) { unsigned int ver = 0; if (argc == 2) { // if the given string doesn't have any dots, assume it's a // new-style version filename, and insert them where they ought to // go. char buf[20]; if (!strchr(argv[1], '.') && !strchr(argv[1], '_')) { int len = strlen(argv[1]); memset(buf, '0', 10); strcpy(buf+10-len, argv[1]); memmove(buf, buf+2, 2); buf[2]='.'; memmove(buf+3, buf+4, 2); buf[5]='.'; } else strncpy(buf, argv[1], 19); ver = string_to_ver(buf); } printf("0x%08x\n", ver); return 0; } wvstreams-4.6.1/utils/tests/crashtest.cc0000644000175000001440000000223511202637334017406 0ustar wlachusers#include "wvassert.h" #include "wvcrash.h" #include #include #include #include #include #include #ifndef MACOS # include #endif int glob = 5; int sig = 0; void zfunc() { glob = 99; } void yfunc() { glob = 6; zfunc(); if (sig == 0) *(char *)NULL = 0; else kill(getpid(), sig); glob = 9; } void xfunc() { glob = 7; yfunc(); glob = 8; } int main(int argc, char **argv) { if (argc > 2) { printf("wvcrash_setup(argv[0], argv[2]);\n"); wvcrash_setup(argv[0], argv[2]); } else { printf("wvcrash_setup(argv[0]);\n"); wvcrash_setup(argv[0]); } printf("free(malloc(1));\n"); free(malloc(1)); if (argc > 1) { printf("sig = atoi(argv[1]);\n"); sig = atoi(argv[1]); } printf("wvassert(argc < 6);\n"); wvassert(argc < 6, "%s '%s' '%s' '%s' '%s' '%s'", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); printf("wvassert(argc < 5);\n"); wvassert(argc < 5); printf("assert(argc < 4);\n"); assert(argc < 4); printf("xfunc();\n"); xfunc(); } wvstreams-4.6.1/utils/tests/testtest.cc0000644000175000001440000000155411036722347017274 0ustar wlachusers#include "wvtest.h" #include "wvstring.h" #include static int sequence = 0; WVTEST_MAIN("basic 1") { WvString a, b; WVPASS(sequence++ == 0); WVPASS(a==NULL); WVPASS("Next one should fail"); WVFAIL(b==NULL); // should fail WVPASS(1); WVPASS(a==b); WVFAIL(a!=b); a.append(b); WVPASS(a==b); WVPASS("Next one should fail"); WVFAIL(a == b); // should fail WVFAIL(a != b); WVPASS(a == b); WVPASS(!sleep(1)); WVFAIL(a != b); a.append("blah"); WVPASS(a=="blah"); WVPASS(a!=b); } WVTEST_MAIN("basic 2") { WVPASS(++sequence == 2); WVPASS("booga booga"); } WVTEST_MAIN("basic 3") { WVFAIL(++sequence != 3); WVPASS("booga booga"); WVPASS("Next one should fail"); WVPASS(sequence != 3); // should fail } int main() { return WvTest::run_all(); } wvstreams-4.6.1/utils/tests/sorttest.cc0000644000175000001440000000710111036722347017276 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for sorted iterators on lists. * * Correct output: * Frontwards: eight five four nine one seven six ten three two * Unsorted: one two three four five six seven eight nine ten * Backwards: two three ten six seven one nine four five eight * */ #include #include "wvstring.h" #include "wvlinklist.h" #include "wvhashtable.h" #include "wvscatterhash.h" #include "wvsorter.h" DeclareWvList(WvString); DeclareWvTable(WvString); DeclareWvScatterTable2(WvStringTable2, WvString); int apples_to_oranges(const WvString *a, const WvString *b) { return strcmp(*a, *b); } int oranges_to_apples(const WvString *a, const WvString *b) { return -strcmp(*a, *b); } int main() { free(malloc(1)); { // sorted linked list printf("\nLinked list sorter test:\n"); WvStringList l; l.append(new WvString("one"), true); l.append(new WvString("two"), true); l.append(new WvString("three"), true); l.append(new WvString("four"), true); l.append(new WvString("five"), true); l.append(new WvString("six"), true); l.append(new WvString("seven"), true); l.append(new WvString("eight"), true); l.append(new WvString("nine"), true); l.append(new WvString("ten"), true); printf("Frontwards: "); { WvStringList::Sorter s(l, apples_to_oranges); for(s.rewind(); s.next();) printf("%s ", (const char *) s()); } printf("\nUnsorted: "); { WvStringList::Iter i(l); for(i.rewind(); i.next();) printf("%s ", (const char *) i()); } printf("\nBackwards: "); { WvStringList::Sorter s(l, oranges_to_apples); for(s.rewind(); s.next();) printf("%s ", (const char *) s()); } } { // sorted hash table printf("\n\nHash table sorter test:\n"); WvStringTable t(3); t.add(new WvString("one"), true); t.add(new WvString("two"), true); t.add(new WvString("three"), true); t.add(new WvString("four"), true); t.add(new WvString("five"), true); t.add(new WvString("six"), true); t.add(new WvString("seven"), true); t.add(new WvString("eight"), true); t.add(new WvString("nine"), true); t.add(new WvString("ten"), true); printf("Frontwards: "); { WvStringTable::Sorter s(t, apples_to_oranges); for (s.rewind(); s.next(); ) printf("%s ", (const char *) s()); } printf("\nUnsorted: "); { WvStringTable::Iter i(t); for (i.rewind(); i.next(); ) printf("%s ", (const char *) i()); } printf("\nBackwards: "); { WvStringTable::Sorter s(t, oranges_to_apples); for (s.rewind(); s.next(); ) printf("%s ", (const char *) s()); } } { // sorted scatter hash table printf("\n\nScatterHash table sorter test:\n"); WvStringTable2 t(3); t.add(new WvString("one"), true); t.add(new WvString("two"), true); t.add(new WvString("three"), true); t.add(new WvString("four"), true); t.add(new WvString("five"), true); t.add(new WvString("six"), true); t.add(new WvString("seven"), true); t.add(new WvString("eight"), true); t.add(new WvString("nine"), true); t.add(new WvString("ten"), true); printf("Frontwards: "); { WvStringTable2::Sorter s(t, apples_to_oranges); for (s.rewind(); s.next(); ) printf("%s ", (const char *) s()); } printf("\nUnsorted: "); { WvStringTable2::Iter i(t); for (i.rewind(); i.next(); ) printf("%s ", (const char *) i()); } printf("\nBackwards: "); { WvStringTable2::Sorter s(t, oranges_to_apples); for (s.rewind(); s.next(); ) printf("%s ", (const char *) s()); } printf("\n"); } return 0; } wvstreams-4.6.1/utils/tests/buffertest.cc0000644000175000001440000000761011036722347017565 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvBuf test program. Comments below indicate correct results. * */ #include "wvbuf.h" #include #include //#define DEBUG_STRESS int main() { WvInPlaceBuf b(1024); WvDynBuf bb; char *s, xx[1024]; size_t in, i, max, total; printf("InPlaceBuffer TEST\n"); printf("A %20u used, %u free, offset %d/%d\n", b.used(), b.free(), b.strchr('c'), b.strchr((unsigned char)'c')); b.put("frogs on ice", 13); printf("B %20u used, %u free, offset %d/%d\n", b.used(), b.free(), b.strchr('c'), b.strchr((unsigned char)'c')); s = (char *)b.get(8); printf("C s: %s\n", s); printf("D %20u used, %u free, offset %d/%d\n", b.used(), b.free(), b.strchr('c'), b.strchr((unsigned char)'c')); s = (char *)b.get(5); printf("E s: %s\n", s); printf("F %20u used, %u free, offset %d/%d\n", b.used(), b.free(), b.strchr('c'), b.strchr((unsigned char)'c')); b.zap(); printf("G %20u used, %u free, offset %d/%d\n", b.used(), b.free(), b.strchr('c'), b.strchr((unsigned char)'c')); printf("\n"); printf("BUFFER TEST\n"); printf("A %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); bb.put("frogs on ice", 13); printf("B %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); bb.put("frogs on rice", 14); printf("C %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); s = (char *)bb.get(8); printf("D s: %s\n", s); // "frogs on ice" printf("E %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); bb.put("frogs on bryce", 15); s = (char *)bb.get(5); printf("F s: %s\n", s); // " ice" printf("G %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); s = (char *)bb.get(16); printf("H s: %s\n", s); // "frogs on rice" printf("I %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); bb.unget(12); printf("I2 %19u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); s = (char *)bb.get(11); printf("J s: %s\n", s); // "s on rice" s = (char *)bb.get(14); printf("J2 s: %s\n", s); // "rogs on bryce" printf("K %20u used, offset %d/%d\n", bb.used(), bb.strchr('c'), bb.strchr((unsigned char)'c')); printf("\n"); printf("BUFFER STRESS\n"); in = max = total = 0; while (1) { i = random() % sizeof(xx); s = (char *)bb.alloc(i); memcpy(s, xx, i); #ifdef DEBUG_STRESS fprintf(stderr, "alloc(%d)\n", i); #endif in += i; total += i; size_t lastalloc = i; i = random() % sizeof(xx); if (i > lastalloc) i = lastalloc; #ifdef DEBUG_STRESS fprintf(stderr, "unalloc(%d)\n", i); #endif bb.unalloc(i); in -= i; i = random() % sizeof(xx); if (i > in) i = in; #ifdef DEBUG_STRESS fprintf(stderr, "get(%d)\n", i); #endif bb.get(i); in -= i; i = random() % sizeof(xx); #ifdef DEBUG_STRESS fprintf(stderr, "put(%d)\n", i); #endif bb.put(xx, i); in += i; total += i; i = random() % sizeof(xx); if (i > in) i = in; #ifdef DEBUG_STRESS fprintf(stderr, "get(%d)\n", i); #endif bb.get(i); in -= i; size_t lastput = i; i = random() % sizeof(xx); if (i > lastput) i = lastput; #ifdef DEBUG_STRESS fprintf(stderr, "unget(%d)\n", i); #endif bb.unget(i); in += i; assert(bb.used() == in); if (bb.used() > max) { max = bb.used(); printf("New max: %u bytes in subbuffers after %u bytes\n", max, total); } #ifdef DEBUG_STRESS fprintf(stderr, "[%6d]", in); #endif } return 0; } wvstreams-4.6.1/utils/tests/vertest.cc0000644000175000001440000000143711036722347017111 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Version number and string manipulations. Version numbers are 32-bit * hexadecimal numbers such as 0x00012a00. The first 16 bits are the major * version, and the second 16 bits are the (fractional) minor version. For * example, the above example corresponds to version "1.2a" (which is the * version string). */ #include "verstring.h" #include int main() { printf("%s %08x\n", ver_to_string(0x99998888), string_to_ver("1.0")); printf("%s %08x\n", ver_to_string(0x01a00200), string_to_ver(".02a")); printf("%s %08x\n", ver_to_string(0x00001000), string_to_ver("1b")); printf("%s %08x\n", ver_to_string(0x00000000), string_to_ver("1A.")); return 0; } wvstreams-4.6.1/utils/tests/diritertest.cc0000644000175000001440000000211311036722347017747 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for WvDirIter. Takes a directory on the command line, and * prints everything it sees. * */ #define __STDC_FORMAT_MACROS #include #include #include "wvdiriter.h" int main( int argc, char * argv[] ) /*********************************/ { WvString dirname; bool recurse = false; bool skip_mounts = false; for( int i=1; ifullname, i->name.cstr(), i->st_mode, uint64_t(i->st_size) ); } return( 0 ); } wvstreams-4.6.1/utils/tests/callbacktest.cc0000644000175000001440000000205611077124372020046 0ustar wlachusers#include "wvtr1.h" #include struct A { long x, y; A(long _x = 0, long _y = 0) { x = _x; y = _y; } A add(const A &a) { return A(x+a.x, y+a.y); } }; typedef wv::function ACallback; typedef wv::function A2Callback; typedef wv::function A3Callback; static A bunk(const A &a, void *userdata) { long incr = (long)userdata; return A(a.x+incr, a.y+incr*2); } // one-parameter version of bunk() static A bunk1(const A &a) { return bunk(a, (void *)1); } static void print_a(const A &a) { printf("result: %ld/%ld\n", a.x, a.y); } int main() { A a(1000, 2000); ACallback c0(bunk); A2Callback c1(bunk1); // FIXME: I am broken. Please show this to somebody // who can fix.... can fix.... can fix..... // A3Callback c2(WvBoundCallback(bunk, a)); A2Callback c3(wv::bind(&A::add, &a, _1)); print_a(c0(a, (void *)5)); print_a(c1(a)); // print_a(c2((void *)2)); print_a(c3(a)); return 0; } wvstreams-4.6.1/utils/tests/conttest.cc0000644000175000001440000000656711077124372017270 0ustar wlachusers/* * A test program for WvCont (continuable callbacks). */ #include "wvcont.h" #include static void *nonfunc(void *_x) { long x = (long)_x; return (void *)(1234560000 + x); } static void *func(void *_x) { long x = (long)_x; for (int count = 0; count < 4 && WvCont::isok(); count++) WvCont::yield((void *)++x); return (void *) -(++x); } class Honk { public: const char *id; WvContCallback cb; Honk(const char *_id) { id = _id; } void honk_at(Honk &a) { cb = WvCont(wv::bind(&Honk::honker, this, a, _1)); } private: void *honker(Honk &h, void *_x) { long x = (long)_x; printf("%s: STARTING (%ld)\n", id, x); for (x--; WvCont::isok() && x > 0; x--) { printf("%s: --> Honking in (%ld)\n", id, x); h.cb((void *)x); printf("%s: <-- Honking out (%ld)\n", id, x); } printf("%s: DONE\n", id); return (void *)x; } }; int main() { typedef wv::function CbType; // basic functionality (including nested tasks) { CbType cbx = func; // not runnable itself: no yield allowed CbType cb1 = WvCont(cbx); // a subtask CbType cb2 = WvCont(cb1); // another subtask on top CbType cb3 = cb2; // a copy of the second subtask // note that in the above, there's really only one context in which // 'func' actually gets called; there are no parallel running 'func's. // cb2's task calls into cb1's task, however. printf("zot1: %ld\n", (long)cb1((void *)100)); printf("zot1: %ld\n", (long)cb2((void *)200)); printf("zot1: %ld\n", (long)cb3((void *)300)); cb1 = WvCont(nonfunc); printf("zot2: %ld\n", (long)cb1((void *)400)); printf("zot2: %ld\n", (long)cb2((void *)500)); printf("zot2: %ld\n", (long)cb3((void *)600)); cb2 = nonfunc; printf("zot3: %ld\n", (long)cb1((void *)700)); printf("zot3: %ld\n", (long)cb2((void *)800)); printf("zot3: %ld\n", (long)cb3((void *)900)); cb3 = nonfunc; printf("zot4: %ld\n", (long)cb1((void *)1000)); printf("zot4: %ld\n", (long)cb2((void *)1100)); printf("zot4: %ld\n", (long)cb3((void *)1200)); } // fun with recursive continuations. If this doesn't do something // predictable, we'll get screwy bugs when we use this in WvStreams - just // like we did with the pre-WvCont continue_select() implementation. // // The *desired* behaviour here is the same as with real recursive // function calls: if a calls b who calls c, and then c calls a again, // then a should do its thing, return (or yield), then c will finish, // yield, then b will finish, yield, and then a will have a chance to run // again. // // In old wvstreams, we would silently short-circuit the recursion (the // inner a would yield immediately without doing anything). This is // easy to implement, but causes problems if c actually expects a to do // something. // // Unfortunately, the semantics of this are tricky with continuations: // when we call the inner a, we re-enter its context, but that context // is waiting for b to return. It can't do anything unless b returns, // so what can we do? // // ...we assert() instead. So expect an assertion failure below. printf("Expect an assertion failure shortly!\n"); { Honk h1("honk1"), h2("honk2"), h3("honk3"); h1.honk_at(h2); h2.honk_at(h3); h3.honk_at(h1); h1.cb((void *)5); } return 0; } wvstreams-4.6.1/utils/tests/tasktest.cc0000644000175000001440000000414511036722347017256 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvTask test program. */ #include "wvtask.h" #include // for sleep() WvTask *ga, *gb; WvTaskMan *gman; void gentask(void *userdata) { char *str = (char *)userdata; int count = 0, delay = 0; printf("Gentask starting %s\n", str); while (count < 3) { printf("%s count %d -- %p\n", str, ++count, &str); usleep(delay*1000); if (count % 2) { if (gman->whoami() == ga) { if (gb) { printf("Doing gb:\n"); gman->run(*gb, 400); } } else { if (ga) { printf("Doing ga:\n"); gman->run(*ga, 400); } } } delay = gman->yield(); } printf("Gentask ending %s\n", str); } int main() { WvTaskMan *man = WvTaskMan::get(); gman = man; ga = man->start("atask", gentask, (void *)"a"); gb = man->start("btask", gentask, (void *)"b"); // simple test for (int x = 0; x < 10; x++) { printf("main1:\n"); man->run(*ga, 400); printf("main2:\n"); man->run(*gb, 400); // it's still running; can't recycle it yet! //gb->recycle(); if (!gb->isrunning()) gb = man->start("bbtask", gentask, (void *)"bb"); if (!ga->isrunning()) ga = man->start("aatask", gentask, (void *)"aa"); } // finish the tasks while (ga->isrunning()) man->run(*ga, 0); while (gb->isrunning()) man->run(*gb, 0); ga->recycle(); gb->recycle(); ga = NULL; gb = NULL; // stress test WvTaskList tasks; for (int x = 1; x <= 20; x++) { printf("x == %d\n", x); for (int y = 1; y <= 10; y++) { WvTask *t = man->start("stresstask", gentask, (void *)"testy", 16384); tasks.append(t, false); } WvTaskList::Iter i(tasks); for (i.rewind(); i.next(); ) man->run(i(), 10); } while (tasks.count()) { WvTaskList::Iter i(tasks); for (i.rewind(); i.next(); ) { man->run(i(), 100); if (!i().isrunning()) { i().recycle(); i.unlink(); i.rewind(); } } } man->unlink(); return 0; } wvstreams-4.6.1/utils/tests/wvgrep.cc0000644000175000001440000001402611077124114016716 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * A clone of grep(1) that is written entirely in WvStreams * */ #include "wvstring.h" #include "wvstringlist.h" #include "wvargs.h" #include "wvregex.h" #include "wvfile.h" #define VERSION "0.1.0" static void output_filename(WvStringParm filename, char suffix, bool display_nulls) { wvout->print(!!filename? filename: WvFastString("(standard input)")); if (display_nulls) wvout->write("\0", 1); else wvout->write(&suffix, 1); } static int match(const WvRegex ®ex, WvStringParm filename, WvStream *file, bool invert_match, bool display_filename, bool display_line_number, bool display_nulls, bool display_nothing, bool end_on_first_match) { int count = 0; int lineno = 0; while (file->isok()) { const char *line = file->blocking_getline(-1); if (line == NULL) break; ++lineno; bool result = regex.match(line); if (invert_match) result = !result; if (result) { ++count; if (end_on_first_match) return count; } if (!result || display_nothing) continue; if (display_filename) output_filename(filename, ':', display_nulls); if (display_line_number) wvout->print("%s:", lineno); wvout->print("%s\n", line); } return count; } int main(int argc, char **argv) { WvArgs args; args.set_version("wvgrep (WvStreams grep) " VERSION "\n"); args.set_email("<" WVPACKAGE_BUGREPORT ">"); bool opt_count = false; args.add_set_bool_option('c', "count", WvString::null, opt_count); bool opt_extended_regexp = false; args.add_set_bool_option('E', "extended-regexp", WvString::null, opt_extended_regexp); WvString opt_regexp; args.add_option('e', "regexp", WvString::null, WvString::null, opt_regexp); bool opt_basic_regexp = false; args.add_set_bool_option('G', "basic-regexp", WvString::null, opt_basic_regexp); bool opt_with_filename = false; args.add_set_bool_option('H', "with-filename", WvString::null, opt_with_filename); bool opt_no_filename = false; args.add_set_bool_option('h', "no-filename", WvString::null, opt_no_filename); bool opt_ignore_case = false; args.add_set_bool_option('i', "ignore-case", WvString::null, opt_ignore_case); args.add_set_bool_option('y', WvString::null, "Synonym for -i", opt_ignore_case); bool opt_files_without_match = false; args.add_set_bool_option('L', "files-without-match", WvString::null, opt_files_without_match); bool opt_files_with_matches = false; args.add_set_bool_option('l', "files-with-matches", WvString::null, opt_files_with_matches); bool opt_line_number = false; args.add_set_bool_option('n', "line-number", WvString::null, opt_line_number); bool opt_quiet = false; args.add_set_bool_option('q', "quiet", WvString::null, opt_quiet); args.add_set_bool_option(0, "silent", "Synonym for --quiet", opt_quiet); bool opt_no_messages = false; args.add_set_bool_option('s', "no-message", WvString::null, opt_no_messages); bool opt_invert_match = false; args.add_set_bool_option('v', "invert-match", WvString::null, opt_invert_match); bool opt_line_regexp = false; args.add_set_bool_option('x', "line-regexp", WvString::null, opt_line_regexp); bool opt_null = false; args.add_set_bool_option('Z', "null", WvString::null, opt_null); args.add_required_arg("PATTERN"); args.add_optional_arg("FILE", true); args.set_help_header("Search for PATTERN in each FILE or standard input."); args.set_help_footer("With no FILE, this program reads standard input."); WvStringList remaining_args; args.process(argc, argv, &remaining_args); if (!opt_regexp && !remaining_args.isempty()) opt_regexp = remaining_args.popstr(); int cflags = WvFastString(argv[0]) == "egrep"? WvRegex::EXTENDED: WvRegex::BASIC; if (opt_extended_regexp) cflags = WvRegex::EXTENDED; if (opt_basic_regexp) cflags = WvRegex::BASIC; if (opt_ignore_case) cflags |= WvRegex::ICASE; WvString regex_str; if (opt_line_regexp) regex_str = WvString("^%s$", opt_regexp); else regex_str = opt_regexp; WvRegex regex(regex_str, cflags); if (!regex.isok()) { WvString errstr = regex.errstr(); wverr->print("%s: Invalid regular expression", argv[0]); if (!!errstr) wverr->print(errstr); wverr->write("\n", 1); return 2; } bool display_filename = remaining_args.count() >= 2; if (opt_with_filename) display_filename = true; if (opt_no_filename) display_filename = false; if (remaining_args.isempty()) remaining_args.append(WvString::null); bool found_match = false; WvStringList::Iter filename(remaining_args); for (filename.rewind(); filename.next(); ) { WvStream *file; if (!!*filename) file = new WvFile(*filename, O_RDONLY); else file = wvcon; if (!file->isok()) { if (!opt_no_messages) wverr->print("%s: %s: %s\n", argv[0], *filename, file->errstr()); if (!!*filename) WVRELEASE(file); continue; } int count = match(regex, *filename, file, opt_invert_match, display_filename, opt_line_number, opt_null, opt_count || opt_files_without_match || opt_files_with_matches, opt_quiet); if (!!*filename) WVRELEASE(file); if (opt_files_with_matches || opt_files_without_match) { bool display = opt_files_with_matches? count>0: count==0; if (display) output_filename(*filename, '\n', opt_null); } else if(opt_count) { if (display_filename) output_filename(*filename, ':', opt_null); wvout->print("%s\n", count); } found_match = found_match || count > 0; if (opt_quiet && found_match) break; } return found_match? 0: 1; } wvstreams-4.6.1/utils/tests/hextest.cc0000644000175000001440000000260711036722347017101 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for hex functions... */ #include "wvhex.h" #include "wvstream.h" #include "wvistreamlist.h" #include "wvencoderstream.h" #include int main(int argc, char **argv) { char obuf[40]; hexify(obuf, "ABCDE\n\37700", 7); obuf[15] = 'Z'; assert(memcmp(obuf, "41424344450aff\0Z", 16) == 0); assert(strcmp(WvHexEncoder().strflushstr("ABCDE\n\377", true), "41424344450aff") == 0); unhexify(obuf, "41424344450aff\377\0ab"); obuf[7] = 'Z'; assert(memcmp(obuf, "ABCDE\n\xffZ", 8) == 0); // test using stdin/stdout bool encode = true; if (argc > 1 && strcmp(argv[1], "-d") == 0) encode = false; WvEncoder *enc; if (encode) enc = new WvHexEncoder(); else enc = new WvHexDecoder(); WvEncoderStream *stream = new WvEncoderStream((wvout->addRef(), wvout)); stream->auto_flush(false); stream->writechain.append(enc, true); WvIStreamList *slist = new WvIStreamList(); slist->append(stream, false, "stream"); slist->append(wvin, false, "wvin"); wvin->autoforward(*stream); while (wvin->isok() && stream->isok()) { if (slist->select(-1)) slist->callback(); } stream->flush(0); WVRELEASE(stream); WVRELEASE(slist); return 0; } wvstreams-4.6.1/utils/tests/backslashtest.cc0000644000175000001440000000210011036722347020234 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for backslash functions... */ #include "wvbackslash.h" #include "wvstream.h" #include "wvistreamlist.h" #include "wvencoderstream.h" #include int main(int argc, char **argv) { // test using stdin/stdout bool encode = true; if (argc > 1 && strcmp(argv[1], "-d") == 0) encode = false; WvEncoder *enc; if (encode) enc = new WvBackslashEncoder(); else enc = new WvBackslashDecoder(); WvEncoderStream *stream = new WvEncoderStream((wvout->addRef(), wvout)); stream->auto_flush(false); stream->writechain.append(enc, true); WvIStreamList *slist = new WvIStreamList(); slist->append(stream, false, "stream"); slist->append(wvin, false, "wvin"); wvin->autoforward(*stream); while (wvin->isok() && stream->isok()) { if (slist->select(-1)) slist->callback(); } stream->flush(0); WVRELEASE(stream); WVRELEASE(slist); return 0; } wvstreams-4.6.1/utils/tests/dirnametest.cc0000644000175000001440000000063611036722347017734 0ustar wlachusers#include "strutils.h" void test(WvStringParm s) { printf("'%s': '%s' -- '%s'\n", s.cstr(), getdirname(s).cstr(), getfilename(s).cstr()); } int main() { WvString a("/tmp"), b("frog"), c("frog/bog/blog"), d("%s/", c), e("%s//", d), f("%s/zot", e), g(""), h("/big/fat/file"); test(a); test(b); test(c); test(d); test(e); test(f); test(g); test(h); } wvstreams-4.6.1/utils/tests/taskmaxtest.cc0000644000175000001440000000165211036722347017764 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Create new WvTasks until we crash. */ #include "wvtask.h" WvTaskMan *gman; void gentask(void *userdata) { static int xc = 0; int x = ++xc; printf(" Gentask %d (%p)\n", x, userdata); gman->yield(); while (1) { printf(" continue Gentask %d (%p)\n", x, userdata); if (userdata) gman->run(*(WvTask *)userdata); else gman->yield(); } printf(" Gentask ending %d\n", x); } int main() { WvTaskMan *man = WvTaskMan::get(); gman = man; WvTask *t = NULL, *last_t = NULL; WvTaskList tasks; // simple test for (int x = 0; x < 100; x++) { printf("starting %d:\n", x); last_t = t; t = man->start("task", gentask, last_t); tasks.append(t, true); man->run(*t); } man->run(*t); man->unlink(); return 0; } wvstreams-4.6.1/utils/tests/base64test.cc0000644000175000001440000000200111036722347017365 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Test program for base64 functions... */ #include "wvbase64.h" #include "wvstream.h" #include "wvistreamlist.h" #include "wvencoderstream.h" int main(int argc, char **argv) { bool encode = true; if (argc > 1 && strcmp(argv[1], "-d") == 0) encode = false; WvEncoder *enc; if (encode) enc = new WvBase64Encoder(); else enc = new WvBase64Decoder(); WvEncoderStream *stream = new WvEncoderStream((wvout->addRef(), wvout)); stream->auto_flush(false); stream->writechain.append(enc, true); WvIStreamList *slist = new WvIStreamList(); slist->append(stream, false, "stream"); slist->append(wvin, false, "wvin"); wvin->autoforward(*stream); while (wvin->isok() && stream->isok()) { if (slist->select(-1)) slist->callback(); } stream->flush(0); WVRELEASE(stream); WVRELEASE(slist); return 0; } wvstreams-4.6.1/utils/tests/matrixtest.cc0000644000175000001440000000167611036722347017626 0ustar wlachusers#include "wvmatrix.h" #include void print_matrix(WvMatrix &mx) { for (int i = 0; i < mx.m; i++) { for (int j = 0; j < mx.n; j++) printf("%3d ", mx(i, j)); printf("\n"); } } int main() { int dataa[] = {2, 4, -6, 7, 1, 3, 2, 1, -4, 3, -5, 5}; int datab[] = {0, 1, 6, -2, 2, 3, 4, 3, -2, 1, 4, 4}; WvMatrix a(3, 4, dataa); printf("WvMatrix a:\n"); print_matrix(a); WvMatrix b(3, 4, datab); printf("WvMatrix b:\n"); print_matrix(b); WvMatrix c = a + b; printf("WvMatrix a + b = \n"); print_matrix(c); int datad[] = {2, 0, -3, 4, 1, 5}; int datae[] = {7, -1, 4, 7, 2, 5, 0, -4, -3, 1, 2, 3}; WvMatrix d(2, 3, datad); printf("WvMatrix d:\n"); print_matrix(d); WvMatrix e(3, 4, datae); printf("WvMatrix e:\n"); print_matrix(e); WvMatrix f = d * e; printf("WvMatrix d * e = \n"); print_matrix(f); printf("done\n"); return 0; } wvstreams-4.6.1/utils/tests/sizetoatest.cc0000644000175000001440000000125511036722347017771 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * Proper output: * 987.6 TB * 98.7 TB * 9.8 TB * 987.6 GB * 98.7 GB * 9.8 GB * 987.6 MB * 98.7 MB * 9.8 MB * 987.6 KB * 98.7 KB * 9.8 KB * 987 bytes * 98 bytes * 9 bytes * */ #include "strutils.h" #include int main() { long blocks = 987654321; long blocksize = 1000000; while( blocksize != 1 ) { printf( "%s\n", sizetoa( blocks, blocksize ).cstr() ); blocksize /= 10; } while( blocks ) { printf( "%s\n", sizetoa( blocks, blocksize ).cstr() ); blocks /= 10; } return( 0 ); } wvstreams-4.6.1/utils/tests/crashtest-nofd.cc0000644000175000001440000000077111036722347020341 0ustar wlachusers#include "wvcrash.h" #include #include #include #include #include int main(int argc, char **argv) { wvcrash_setup(argv[0], "BLAHBLAH"); int fd, count = 0; while ((fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) { fcntl(fd, F_SETFD, 0); // *not* close-on-exec count++; } printf("Got %d sockets.\n", count); // all fds are now in use; let's see if wvcrash can handle it! abort(); return 0; } wvstreams-4.6.1/utils/tests/encodertest.cc0000644000175000001440000000425711036722347017737 0ustar wlachusers#include "wvgzip.h" #include #include #include #include #include "wvxor.h" extern char *optarg; void usage(const char *prog) { fprintf(stderr, "Usage: %s <-z|-Z|-x ##> [-f]\n" " Encode data from stdin to stdout.\n" " -z: use libz-style encoder (not gzip compatible)\n" " -Z: use libz-style decoder\n" " -x: amazing XOR encryption\n" " -x: amazing XOR decryption\n" " -f: flush output stream often\n", prog); } int main(int argc, char **argv) { WvEncoder *enc = NULL; char buf[2048]; enum { NoMode, Gzip, Gunzip, XOR } mode = NoMode; bool flush_often = false; int c; const char *xor_key = NULL; while ((c = getopt(argc, argv, "zZx:f?")) >= 0) { switch (c) { case 'z': mode = Gzip; break; case 'Z': mode = Gunzip; break; case 'x': mode = XOR; xor_key = optarg; break; case 'f': flush_often = true; break; case '?': default: usage(argv[0]); return 1; } } switch (mode) { case Gzip: enc = new WvGzipEncoder(WvGzipEncoder::Deflate); break; case Gunzip: enc = new WvGzipEncoder(WvGzipEncoder::Inflate); break; case XOR: enc = new WvXOREncoder(xor_key, strlen(xor_key)); break; case NoMode: default: usage(argv[0]); return 2; } assert(enc); WvDynBuf inbuf; WvDynBuf outbuf; while (enc->isok()) { size_t rlen = read(0, buf, sizeof(buf)); //fprintf(stderr, "[read %d bytes]\n", rlen); if (rlen > 0) { inbuf.put(buf, rlen); enc->encode(inbuf, outbuf, flush_often); } else { enc->flush(inbuf, outbuf, true); enc->finish(outbuf); } size_t wlen = outbuf.used(); write(1, outbuf.get(wlen), wlen); //fprintf(stderr, "[wrote %d bytes]\n", wlen); if (rlen <= 0) break; } fprintf(stderr, "exiting...\n"); if (!enc->isok()) fprintf(stderr, "encoder is not okay! %s\n", enc->geterror().cstr()); delete enc; return 0; } wvstreams-4.6.1/utils/tests/wordwraptest.cc0000644000175000001440000000165211036722347020161 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Simple test for WvWordWrapEncoder. */ #include "wvwordwrap.h" #include "wvstream.h" #include "wvistreamlist.h" #include "wvencoderstream.h" int main(int argc, char **argv) { int maxwidth = 80; if (argc > 1) maxwidth = atoi(argv[1]); WvEncoder *enc = new WvWordWrapEncoder(maxwidth); WvEncoderStream *stream = new WvEncoderStream((wvout->addRef(), wvout)); stream->auto_flush(false); stream->writechain.append(enc, true); WvIStreamList *slist = new WvIStreamList(); slist->append(stream, false, "stream"); slist->append(wvin, false, "wvin"); wvin->autoforward(*stream); while (wvin->isok() && stream->isok()) { if (slist->select(-1)) slist->callback(); } stream->flush(0); WVRELEASE(stream); WVRELEASE(slist); return 0; } wvstreams-4.6.1/utils/tests/proctest.cc0000644000175000001440000000742611036722347017264 0ustar wlachusers#include "wvsubproc.h" #include #include int main() { WvSubProc proc; #if 1 // ls should die by itself. fprintf(stderr, "starting ls...\n"); proc.start("ls", "ls", "-F", "/", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(10*1000); fprintf(stderr, "done (%d/%d)...\n", proc.running, proc.estatus); proc.start_again(); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(10*1000); fprintf(stderr, "done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "\n\n"); // sleep should die after getting SIGTERM. fprintf(stderr, "starting sleep...\n"); proc.start("sleep", "sleep", "10", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(2100); fprintf(stderr, "wait done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "sending SIGTERM...\n"); proc.kill(SIGTERM); proc.wait(2200); fprintf(stderr, "wait done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "\n\n"); // sleep should die after getting SIGTERM, so proc.stop() shouldn't take // any time to run. fprintf(stderr, "starting sleep again...\n"); proc.start("sleep", "sleep", "10", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(0); fprintf(stderr, "wait done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "sending SIGTERM...\n"); proc.stop(2300); fprintf(stderr, "stop done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "\n\n"); // bash should refuse to die from SIGTERM, so we have to wait for SIGKILL. fprintf(stderr, "starting bash...\n"); proc.start("bash", "bash", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(2300); fprintf(stderr, "wait done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "stopping process...\n"); proc.stop(2400); fprintf(stderr, "stop done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "\n\n"); // a process that backgrounds itself fprintf(stderr, "starting bash -c 'sleep 100 &'...\n"); proc.start("bash", "bash", "-c", "sleep 100 &", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(2300); fprintf(stderr, "wait done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "stopping process...\n"); proc.stop(2400); fprintf(stderr, "stop done (%d/%d)...\n", proc.running, proc.estatus); fprintf(stderr, "\n\n"); #endif // a fancier process with subprocesses and helpful debug messages fprintf(stderr, "starting ./complex-proc.sh...\n"); proc.start("./complex-proc.sh", "./complex-prox.sh", "XYZ", NULL); fprintf(stderr, "started (%d/%d)...\n", proc.running, proc.pid); proc.wait(4000); fprintf(stderr, "wait done (%d/%d/%d)...\n", proc.running, proc.estatus, proc.old_pids.count()); fprintf(stderr, "stopping process...\n"); proc.stop(2000, false); fprintf(stderr, "stop done (%d/%d/%d)...\n", proc.running, proc.estatus, proc.old_pids.count()); fprintf(stderr, "start again...\n"); proc.start_again(); proc.wait(4000); fprintf(stderr, "wait done (%d/%d/%d)...\n", proc.running, proc.estatus, proc.old_pids.count()); fprintf(stderr, "stopping process...\n"); proc.stop(1000, true); fprintf(stderr, "stop done (%d/%d/%d)...\n", proc.running, proc.estatus, proc.old_pids.count()); fprintf(stderr, "\n\n"); fprintf(stderr, "Checking for leftover subprocesses...\n"); pid_t pid; int status; while ((pid = ::waitpid(-1, &status, 0)) > 0) fprintf(stderr, "LEFTOVER!! pid=%d, status=%d\n", pid, status); return 0; } wvstreams-4.6.1/utils/tests/wvargstest.cc0000644000175000001440000000103511036722347017620 0ustar wlachusers#include "wvargs.h" int main(int argc, char *argv[]) { WvArgs args; WvStringList remaining_args; int int_option; args.add_option('i', "iopt", "integer option", "INT", int_option); args.add_required_arg("FILE"); args.add_optional_arg("FILE", true); if (!args.process(argc, argv, &remaining_args)) return 1; fprintf(stderr, "Printing a brief usage message\n"); args.print_usage(argc, argv); fprintf(stderr, "Printing help message\n"); args.print_help(argc, argv); return 0; } wvstreams-4.6.1/utils/verstring.cc0000644000175000001440000000712111253746065016276 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Version number and string manipulations. Version numbers are 32-bit * hexadecimal numbers such as 0x00012a00. The first 16 bits are the major * version, and the second 16 bits are the (fractional) minor version. For * example, the above example corresponds to version "1.2a" (which is the * version string). */ #include "wvverstring.h" #include #include #include const char *old_ver_to_string(unsigned int ver) { static char str[10]; unsigned int maj = (ver & 0xFFFF0000) >> 16, min = (ver & 0x0000FFFF); sprintf(str, "%x.%04x", maj, min); trim_verstr(str); return str; } const char *new_ver_to_string(unsigned int ver) { static char str[11]; unsigned int maj = (ver & 0xFF000000) >> 24, min = (ver & 0x00FF0000) >> 16, rev = (ver & 0x0000FFFF); sprintf(str, "%x.%02x.%04x", maj, min, rev); return str; } const char *ver_to_string(unsigned int ver) { if (is_new_ver(ver)) return new_ver_to_string(ver); return old_ver_to_string(ver); } unsigned int string_to_old_ver(const char *str) { static char lookup[] = "0123456789abcdef"; unsigned int maj = 0, min = 0; unsigned char *cptr, *idx; int bits; // do the major number cptr = (unsigned char *)str; for (; *cptr && *cptr != '.' && *cptr != '_'; cptr++) { idx = (unsigned char *)strchr(lookup, tolower(*cptr)); if (!idx) continue; maj = (maj << 4) | ((char *)idx - lookup); } // do the minor number for (bits = 4; *cptr && bits > 0; cptr++) { idx = (unsigned char *)strchr(lookup, tolower(*cptr)); if (!idx) continue; min = (min << 4) | ((char *)idx - lookup); bits--; } return (maj << 16) | (min << (4*bits)); } unsigned int string_to_new_ver(const char *str) { static char lookup[] = "0123456789abcdef"; unsigned int maj = 0, min = 0, rev = 0, ver; unsigned char *cptr, *idx; int bits; // do the major number cptr = (unsigned char *)str; for (; *cptr; cptr++) { if (*cptr == '.' || *cptr == '_') { cptr++; break; } idx = (unsigned char *)strchr(lookup, tolower(*cptr)); if (!idx) continue; maj = (maj << 4) | ((char *)idx - lookup); } // do the minor number for (bits = 2; *cptr && *cptr != '.' && *cptr != '_' && bits > 0; cptr++) { idx = (unsigned char *)strchr(lookup, tolower(*cptr)); if (!idx) continue; min = (min << 4) | ((char *)idx - lookup); bits--; } // do the revision number for (bits = 4; *cptr && bits > 0; cptr++) { idx = (unsigned char *)strchr(lookup, tolower(*cptr)); if (!idx) continue; rev = (rev << 4) | ((char *)idx - lookup); bits--; } ver = (maj << 24) | (min << 16) | (rev << (4*bits)); return ver; } unsigned int string_to_ver(const char *str) { if (is_new_verstr(str)) return string_to_new_ver(str); return string_to_old_ver(str); } bool is_new_ver(unsigned int ver) { return (ver & 0xff000000); } bool is_new_verstr(const char *str) { const char *p = strchr(str, '.'); if (p && strchr(p+1, '.')) return true; return false; } char *trim_verstr(char *verstr) { // trim off trailing zeroes char *cptr; for (cptr = strchr(verstr, 0); --cptr >= verstr; ) { if (*cptr != '0') break; if (cptr <= verstr || *(cptr - 1) == '.') break; *cptr = 0; } return verstr; } wvstreams-4.6.1/utils/wvstringtable.cc0000644000175000001440000000114011036722347017135 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Some helper functions for WvStringTable. */ #include "wvstringtable.h" #include "strutils.h" WvString WvStringTable::join(const char *joinchars) const { return ::strcoll_join(*this, joinchars); } void WvStringTable::split(WvStringParm s, const char *splitchars, int limit) { return ::strcoll_split(*this, s, splitchars, limit); } void WvStringTable::splitstrict(WvStringParm s, const char *splitchars, int limit) { return ::strcoll_splitstrict(*this, s, splitchars, limit); } wvstreams-4.6.1/utils/wvtask.cc0000644000175000001440000003315711202637334015572 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A set of classes that provide co-operative multitasking support. See * wvtask.h for more information. */ #include "wvautoconf.h" #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif #include "wvtask.h" #include #include #include #include #include #include #include #ifdef HAVE_VALGRIND_MEMCHECK_H #include // Compatibility for Valgrind 3.1 and previous #ifndef VALGRIND_MAKE_MEM_DEFINED #define VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_READABLE #endif #else #define VALGRIND_MAKE_MEM_DEFINED(x, y) #define RUNNING_ON_VALGRIND 0 #endif #define TASK_DEBUG 0 #if TASK_DEBUG # define Dprintf(fmt, args...) fprintf(stderr, fmt, ##args) #else # define Dprintf(fmt, args...) #endif int WvTask::taskcount, WvTask::numtasks, WvTask::numrunning; WvTaskMan *WvTaskMan::singleton; int WvTaskMan::links, WvTaskMan::magic_number; WvTaskList WvTaskMan::all_tasks, WvTaskMan::free_tasks; ucontext_t WvTaskMan::stackmaster_task, WvTaskMan::get_stack_return, WvTaskMan::toplevel; WvTask *WvTaskMan::current_task, *WvTaskMan::stack_target; char *WvTaskMan::stacktop; static int context_return; static bool use_shared_stack() { return RUNNING_ON_VALGRIND; } static void valgrind_fix(char *stacktop) { #ifdef HAVE_VALGRIND_MEMCHECK_H char val; //printf("valgrind fix: %p-%p\n", &val, stacktop); assert(stacktop > &val); #endif VALGRIND_MAKE_MEM_DEFINED(&val, stacktop - &val); } WvTask::WvTask(WvTaskMan &_man, size_t _stacksize) : man(_man) { stacksize = _stacksize; running = recycled = false; func = NULL; userdata = NULL; tid = ++taskcount; numtasks++; magic_number = WVTASK_MAGIC; stack_magic = NULL; man.get_stack(*this, stacksize); man.all_tasks.append(this, false); } WvTask::~WvTask() { numtasks--; if (running) numrunning--; magic_number = 42; } void WvTask::start(WvStringParm _name, TaskFunc *_func, void *_userdata) { assert(!recycled); name = _name; func = _func; userdata = _userdata; running = true; numrunning++; } void WvTask::recycle() { assert(!running); if (!running && !recycled) { man.free_tasks.append(this, true); recycled = true; } } WvTaskMan *WvTaskMan::get() { if (!links) singleton = new WvTaskMan; links++; return singleton; } void WvTaskMan::unlink() { links--; if (!links) { delete singleton; singleton = NULL; } } static inline const char *Yes_No(bool val) { return val? "Yes": "No"; } WvString WvTaskMan::debugger_tasks_run_cb(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *) { const char *format_str = "%5s%s%7s%s%8s%s%6s%s%s"; WvStringList result; result.append(format_str, "--TID", "-", "Running", "-", "Recycled", "-", "-StkSz", "-", "Name-----"); result_cb(cmd, result); WvTaskList::Iter i(all_tasks); for (i.rewind(); i.next(); ) { result.zap(); result.append(format_str, i->tid, " ", Yes_No(i->running), " ", Yes_No(i->recycled), " ", i->stacksize, " ", i->name); result_cb(cmd, result); } return WvString::null; } WvTaskMan::WvTaskMan() { static bool first = true; if (first) { first = false; WvStreamsDebugger::add_command("tasks", 0, debugger_tasks_run_cb, 0); } stack_target = NULL; current_task = NULL; magic_number = -WVTASK_MAGIC; stacktop = (char *)alloca(0); context_return = 0; assert(getcontext(&get_stack_return) == 0); if (context_return == 0) { // initial setup - start the stackmaster() task (never returns!) stackmaster(); } // if we get here, stackmaster did a longjmp back to us. } WvTaskMan::~WvTaskMan() { magic_number = -42; free_tasks.zap(); } WvTask *WvTaskMan::start(WvStringParm name, WvTask::TaskFunc *func, void *userdata, size_t stacksize) { WvTask *t; WvTaskList::Iter i(free_tasks); for (i.rewind(); i.next(); ) { if (i().stacksize >= stacksize) { t = &i(); i.set_autofree(false); i.unlink(); t->recycled = false; t->start(name, func, userdata); return t; } } // if we get here, no matching task was found. t = new WvTask(*this, stacksize); t->start(name, func, userdata); return t; } int WvTaskMan::run(WvTask &task, int val) { assert(magic_number == -WVTASK_MAGIC); assert(task.magic_number == WVTASK_MAGIC); assert(!task.recycled); Dprintf("WvTaskMan: running task #%d with value %d (%s)\n", task.tid, val, (const char *)task.name); if (&task == current_task) return val; // that's easy! WvTask *old_task = current_task; current_task = &task; ucontext_t *state; if (!old_task) state = &toplevel; // top-level call (not in an actual task yet) else state = &old_task->mystate; context_return = 0; assert(getcontext(state) == 0); int newval = context_return; if (newval == 0) { // saved the state, now run the task. context_return = val; setcontext(&task.mystate); return -1; } else { // need to make state readable to see if we need to make more readable.. VALGRIND_MAKE_MEM_DEFINED(&state, sizeof(state)); // someone did yield() (if toplevel) or run() on our old task; done. if (state != &toplevel) valgrind_fix(stacktop); current_task = old_task; return newval; } } int WvTaskMan::yield(int val) { if (!current_task) return 0; // weird... Dprintf("WvTaskMan: yielding from task #%d with value %d (%s)\n", current_task->tid, val, (const char *)current_task->name); assert(current_task->stack_magic); // if this fails, this task overflowed its stack. Make it bigger! VALGRIND_MAKE_MEM_DEFINED(current_task->stack_magic, sizeof(current_task->stack_magic)); assert(*current_task->stack_magic == WVTASK_MAGIC); #if TASK_DEBUG if (use_shared_stack()) { size_t stackleft; char *stackbottom = (char *)(current_task->stack_magic + 1); for (stackleft = 0; stackleft < current_task->stacksize; stackleft++) { if (stackbottom[stackleft] != 0x42) break; } Dprintf("WvTaskMan: remaining stack after #%d (%s): %ld/%ld\n", current_task->tid, current_task->name.cstr(), (long)stackleft, (long)current_task->stacksize); } #endif context_return = 0; assert(getcontext(¤t_task->mystate) == 0); int newval = context_return; if (newval == 0) { // saved the task state; now yield to the toplevel. context_return = val; setcontext(&toplevel); return -1; } else { // back via longjmp, because someone called run() again. Let's go // back to our running task... valgrind_fix(stacktop); return newval; } } void WvTaskMan::get_stack(WvTask &task, size_t size) { context_return = 0; assert(getcontext(&get_stack_return) == 0); if (context_return == 0) { assert(magic_number == -WVTASK_MAGIC); assert(task.magic_number == WVTASK_MAGIC); if (!use_shared_stack()) { #if defined(__linux__) && (defined(__386__) || defined(__i386) || defined(__i386__)) static char *next_stack_addr = (char *)0xB0000000; static const size_t stack_shift = 0x00100000; next_stack_addr -= stack_shift; #else static char *next_stack_addr = NULL; #endif task.stack = mmap(next_stack_addr, task.stacksize, PROT_READ | PROT_WRITE, #ifndef MACOS MAP_PRIVATE | MAP_ANONYMOUS, #else MAP_PRIVATE, #endif -1, 0); } // initial setup stack_target = &task; context_return = size/1024 + (size%1024 > 0); setcontext(&stackmaster_task); } else { if (current_task) valgrind_fix(stacktop); assert(magic_number == -WVTASK_MAGIC); assert(task.magic_number == WVTASK_MAGIC); // back from stackmaster - the task is now set up. return; } } void WvTaskMan::stackmaster() { // leave lots of room on the "main" stack before doing our magic alloca(1024*1024); _stackmaster(); } void WvTaskMan::_stackmaster() { int val; size_t total; Dprintf("stackmaster 1\n"); // the main loop runs once from the constructor, and then once more // after each stack allocation. for (;;) { assert(magic_number == -WVTASK_MAGIC); context_return = 0; assert(getcontext(&stackmaster_task) == 0); val = context_return; if (val == 0) { assert(magic_number == -WVTASK_MAGIC); // just did setjmp; save stackmaster's current state (with // all current stack allocations) and go back to get_stack // (or the constructor, if that's what called us) context_return = 1; setcontext(&get_stack_return); } else { valgrind_fix(stacktop); assert(magic_number == -WVTASK_MAGIC); total = (val+1) * (size_t)1024; if (!use_shared_stack()) total = 1024; // enough to save the do_task stack frame // set up a stack frame for the new task. This runs once // per get_stack. //alloc_stack_and_switch(total); do_task(); assert(magic_number == -WVTASK_MAGIC); // allocate the stack area so we never use it again alloca(total); // a little sentinel so we can detect stack overflows stack_target->stack_magic = (int *)alloca(sizeof(int)); *stack_target->stack_magic = WVTASK_MAGIC; // clear the stack to 0x42 so we can count unused stack // space later. #if TASK_DEBUG memset(stack_target->stack_magic + 1, 0x42, total - 1024); #endif } } } void WvTaskMan::call_func(WvTask *task) { Dprintf("WvTaskMan: calling task #%d (%s)\n", task->tid, (const char *)task->name); task->func(task->userdata); Dprintf("WvTaskMan: returning from task #%d (%s)\n", task->tid, (const char *)task->name); context_return = 1; } void WvTaskMan::do_task() { assert(magic_number == -WVTASK_MAGIC); WvTask *task = stack_target; assert(task->magic_number == WVTASK_MAGIC); // back here from longjmp; someone wants stack space. context_return = 0; assert(getcontext(&task->mystate) == 0); if (context_return == 0) { // done the setjmp; that means the target task now has // a working jmp_buf all set up. Leave space on the stack // for his data, then repeat the loop in _stackmaster (so we can // return to get_stack(), and allocate more stack for someone later) // // Note that nothing on the allocated stack needs to be valid; when // they longjmp to task->mystate, they'll have a new stack pointer // and they'll already know what to do (in the 'else' clause, below) Dprintf("stackmaster 5\n"); return; } else { // someone did a run() on the task, which // means they're ready to make it go. Do it. valgrind_fix(stacktop); for (;;) { assert(magic_number == -WVTASK_MAGIC); assert(task); assert(task->magic_number == WVTASK_MAGIC); if (task->func && task->running) { if (use_shared_stack()) { // this is the task's main function. It can call yield() // to give up its timeslice if it wants. Either way, it // only returns to *us* if the function actually finishes. task->func(task->userdata); } else { assert(getcontext(&task->func_call) == 0); task->func_call.uc_stack.ss_size = task->stacksize; task->func_call.uc_stack.ss_sp = task->stack; task->func_call.uc_stack.ss_flags = 0; task->func_call.uc_link = &task->func_return; Dprintf("WvTaskMan: makecontext #%d (%s)\n", task->tid, (const char *)task->name); makecontext(&task->func_call, (void (*)(void))call_func, 1, task); context_return = 0; assert(getcontext(&task->func_return) == 0); if (context_return == 0) setcontext(&task->func_call); } // the task's function terminated. task->name = "DEAD"; task->running = false; task->numrunning--; } yield(); } } } const void *WvTaskMan::current_top_of_stack() { #ifdef HAVE_LIBC_STACK_END extern const void *__libc_stack_end; if (use_shared_stack() || current_task == NULL) return __libc_stack_end; else return (const char *)current_task->stack + current_task->stacksize; #else return 0; #endif } size_t WvTaskMan::current_stacksize_limit() { if (use_shared_stack() || current_task == NULL) { struct rlimit rl; if (getrlimit(RLIMIT_STACK, &rl) == 0) return size_t(rl.rlim_cur); else return 0; } else return size_t(current_task->stacksize); } wvstreams-4.6.1/utils/wvbuffer.cc0000644000175000001440000000510411036722347016074 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Specializations of the generic buffering API. */ #include "wvbuf.h" /***** Specialization for raw memory buffers *****/ void WvBufBase::putstr(WvStringParm str) { put((const unsigned char*)str.cstr(), str.len()); } WvString WvBufBase::getstr() { /* Copy the contents into the string. * We used to just return a reference to those bytes, but * that required modifying the buffer to append a null * terminator, which does not work with read-only buffers. * This method is also somewhat safer if a little slower. */ WvString result; size_t len = used(); result.setsize(len + 1); char *str = result.edit(); move(str, len); str[len] = '\0'; return result; } WvString WvBufBase::getstr(size_t len) { WvString result; result.setsize(len + 1); char *str = result.edit(); move(str, len); str[len] = '\0'; return result; } size_t WvBufBase::strchr(int ch) { size_t offset = 0; size_t avail = used(); while (offset < avail) { size_t len = optpeekable(offset); const unsigned char *str = peek(offset, len); for (size_t i = 0; i < len; ++i) if (str[i] == ch) return offset + i + 1; offset += len; } return 0; } size_t WvBufBase::_match(const void *bytelist, size_t numbytes, bool reverse) { size_t offset = 0; size_t avail = used(); const unsigned char *chlist = (const unsigned char*)bytelist; while (offset < avail) { size_t len = optpeekable(offset); const unsigned char *str = peek(offset, len); for (size_t i = 0; i < len; ++i) { int ch = str[i]; size_t c; for (c = 0; c < numbytes; ++c) if (chlist[c] == ch) break; if (reverse) { if (c == numbytes) continue; } else { if (c != numbytes) continue; } return offset + i; } offset += len; } return reverse ? offset : 0; } /***** WvConstStringBuffer *****/ WvConstStringBuffer::WvConstStringBuffer(WvStringParm _str) { reset(_str); } WvConstStringBuffer::WvConstStringBuffer() { } void WvConstStringBuffer::reset(WvStringParm _str) { xstr = _str; WvConstInPlaceBuf::reset(xstr.cstr(), xstr.len()); } wvstreams-4.6.1/utils/wvbackslash.cc0000644000175000001440000001565311036722347016570 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2002 Net Integration Technologies, Inc. * * Performs C-style backslash escaping and unescaping of strings. */ #include #include "wvbackslash.h" static const char *escapein = "\a\b\f\n\r\t\v"; static const char *escapeout = "abfnrtv"; static inline char tohex(int digit, char alphabase = ('a' - 10)) { return (digit < 10 ? '0' : alphabase) + digit; } static inline int fromhex(char digit) { if (isdigit(digit)) return digit - '0'; if (digit >= 'A' && digit <= 'F') return digit - 'A' + 10; if (digit >= 'a' && digit <= 'f') return digit - 'a' + 10; return -1; } static inline int fromoctal(char digit) { if (digit >= '0' && digit <= '7') return digit - '0'; return -1; } /***** WvBackslashEncoder *****/ WvBackslashEncoder::WvBackslashEncoder(WvStringParm _nasties) : nasties(_nasties) { } bool WvBackslashEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { size_t avail = outbuf.free(); size_t len; while ((len = inbuf.optgettable()) != 0) { const unsigned char *datain = inbuf.get(len); for (size_t i = 0; i < len; ++i) { int c = datain[i]; // handle 1 character escape sequences if (avail < 1) { outbuf.unget(len - i); return ! flush; } const char *foundnasty = NULL; const char *foundspecial = NULL; if (c != '\0') { foundnasty = strchr(nasties.cstr(), c); if (! foundnasty) { foundspecial = strchr(escapein, c); if (! foundspecial && isprint(c)) { outbuf.putch(c); avail -= 1; continue; } } } // handle 2 character escape sequences if (avail < 2) { outbuf.unget(len - i); return ! flush; } if (foundnasty != NULL) { outbuf.putch('\\'); outbuf.putch(c); avail -= 2; continue; } if (foundspecial != NULL) { outbuf.putch('\\'); outbuf.putch(escapeout[foundspecial - escapein]); avail -= 2; continue; } // handle 4 character escape sequences if (avail < 4) { outbuf.unget(len - i); return ! flush; } outbuf.put("\\x", 2); outbuf.putch(tohex(c >> 4)); outbuf.putch(tohex(c & 15)); avail -= 4; } } return true; } bool WvBackslashEncoder::_reset() { return true; } /***** WvBackslashDecoder *****/ WvBackslashDecoder::WvBackslashDecoder() : tmpbuf(4) { _reset(); } bool WvBackslashDecoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { if (outbuf.free() == 0) return inbuf.used() == 0; if (! flushtmpbuf(outbuf)) return false; size_t len; while ((len = inbuf.optgettable()) != 0) { const unsigned char *datain = inbuf.get(len); for (size_t i = 0; i < len; ++i) { int c = datain[i]; switch (state) { case Initial: if (c == '\\') state = Escape; tmpbuf.putch(c); break; case Escape: if (c >= '0' && c <= '3') { tmpbuf.unalloc(1); value = c - '0'; state = Octal1; } else if (c == 'x') { tmpbuf.putch(c); state = Hex1; } else if (c == '\n') { // line continuation sequence tmpbuf.unalloc(1); tmpbuf.putch('\n'); state = Initial; } else { const char *found = strchr(escapeout, c); tmpbuf.unalloc(1); if (found != NULL) c = escapein[found - escapeout]; // else we just drop the backslash tmpbuf.putch(c); state = Initial; } break; case Hex2: case Hex1: { int digit = fromhex(c); if (digit >= 0) { if (state == Hex1) { tmpbuf.unalloc(2); value = digit; state = Hex2; } else { value = (value << 4) | digit; state = Initial; } } else { i -= 1; state = Initial; } break; } case Octal3: case Octal2: case Octal1: { int digit = fromoctal(c); if (digit >= 0) { value = (value << 3) | digit; if (state != Octal3) state = State(state + 1); else state = Initial; } else { i -= 1; state = Initial; } break; } } flushtmpbuf(outbuf); if (outbuf.free() == 0) { inbuf.unget(len - i); break; } } } if (flush) { if (inbuf.used() != 0) return false; state = Initial; return flushtmpbuf(outbuf); } return true; } bool WvBackslashDecoder::_reset() { state = Initial; value = -1; tmpbuf.zap(); return true; } bool WvBackslashDecoder::flushtmpbuf(WvBuf &outbuf) { if (state != Initial) return true; if (value != -1) { tmpbuf.putch(value); value = -1; } size_t len = tmpbuf.used(); if (len == 0) return true; size_t avail = outbuf.free(); if (avail > len) avail = len; outbuf.merge(tmpbuf, avail); len -= avail; if (len == 0) { tmpbuf.zap(); return true; } return false; } wvstreams-4.6.1/utils/wvstreamsdebugger.cc0000644000175000001440000000724411036722347020015 0ustar wlachusers#include #include "wvstreamsdebugger.h" #include "wvlinklist.h" using std::set; static set *debuggers; WvStreamsDebugger::CommandMap *WvStreamsDebugger::commands; class WvStreamsDebuggerStaticInitCleanup { public: WvStreamsDebuggerStaticInitCleanup() { WvStreamsDebugger::add_command("help", 0, &WvStreamsDebugger::help_run_cb, 0); } ~WvStreamsDebuggerStaticInitCleanup() { assert(!debuggers || debuggers->empty()); if (WvStreamsDebugger::commands) { delete WvStreamsDebugger::commands; WvStreamsDebugger::commands = NULL; } if (debuggers) { delete debuggers; debuggers = NULL; } } }; static WvStreamsDebuggerStaticInitCleanup ___; void *WvStreamsDebugger::get_command_data(WvStringParm cmd, Command *command) { if (command == NULL) { CommandMap::iterator it = commands->find(cmd); if (it == commands->end()) return NULL; command = &it->second; } void *cd; CommandDataMap::iterator it = command_data.find(cmd); if (it == command_data.end()) { // In case the command has been added since our constructor // was executed... if (command->init_cb) cd = command->init_cb(cmd); else cd = NULL; command_data[cmd] = cd; } else cd = it->second; return cd; } WvStreamsDebugger::WvStreamsDebugger() { if (!debuggers) debuggers = new set; debuggers->insert(this); // Add command data for existing commands CommandMap::iterator it; for (it = commands->begin(); it != commands->end(); ++it) get_command_data(it->first, &it->second); } WvStreamsDebugger::~WvStreamsDebugger() { // Remove command data CommandDataMap::iterator it; for (it = command_data.begin(); it != command_data.end(); ++it) { CommandMap::iterator it2 = commands->find(it->first); if (it2 != commands->end() && it2->second.cleanup_cb) it2->second.cleanup_cb(it->first, it->second); } command_data.clear(); debuggers->erase(this); } WvString WvStreamsDebugger::run(WvStringParm cmd, WvStringList &args, ResultCallback result_cb) { CommandMap::iterator it = commands->find(cmd); if (it == commands->end()) return "No such command"; Command *command = &it->second; return command->run_cb(cmd, args, result_cb, get_command_data(cmd, command)); } bool WvStreamsDebugger::add_command(WvStringParm cmd, InitCallback init_cb, RunCallback run_cb, CleanupCallback cleanup_cb) { if (!commands) commands = new CommandMap; return commands->insert( std::make_pair(cmd, Command(init_cb, run_cb, cleanup_cb))).second; } bool WvStreamsDebugger::foreach(WvStringParm cmd, ForeachCallback foreach_cb) { CommandMap::iterator it = commands->find(cmd); if (it == commands->end()) return false; if (debuggers) { set::iterator it2; for (it2 = debuggers->begin(); it2 != debuggers->end(); ++it2) { void *cd = (*it2)->get_command_data(cmd, &it->second); foreach_cb(cmd, cd); } } return true; } WvString WvStreamsDebugger::help_run_cb(WvStringParm cmd, WvStringList &args, ResultCallback result_cb, void *) { WvStringList cmd_list; cmd_list.append("Commands available:"); CommandMap::iterator it; for (it = commands->begin(); it != commands->end(); ++it) cmd_list.append(it->first); result_cb(cmd, cmd_list); return WvString::null; } wvstreams-4.6.1/utils/t/0000755000175000001440000000000011260431126014171 5ustar wlachuserswvstreams-4.6.1/utils/t/wvtimeutils.t.cc0000644000175000001440000001600311036722347017347 0ustar wlachusers#include "wvtest.h" #include "wvtimeutils.h" #include "wvstring.h" #include "wvstream.h" #ifdef _WIN32 #include #else #include #endif WVTEST_MAIN("msecdiff()") { time_t result; WvTime tmp; // Diff between zero time is 0 result = msecdiff(wvtime_zero, wvtime_zero); WVPASS(result == 0); // Diff between random time (in sec) and zero is random time * 1000 tmp.tv_sec = 854; tmp.tv_usec = 0; result = msecdiff(tmp, wvtime_zero); WVPASS(result == tmp.tv_sec * 1000); // Diff between zero and random time (in sec) is -random time * 1000 tmp.tv_sec = 854; tmp.tv_usec = 0; result = msecdiff(wvtime_zero, tmp); WVPASS(result == tmp.tv_sec * -1000); // Diff between random time (in usec) and zero is random time / 1000 // note: msecdiff simply chops the decimals away tmp.tv_sec = 0; tmp.tv_usec = 999; result = msecdiff(tmp, wvtime_zero); WVPASS(result == 0); tmp.tv_usec = 1000; result = msecdiff(tmp, wvtime_zero); WVPASS(result == 1); tmp.tv_usec = 1001; result = msecdiff(tmp, wvtime_zero); WVPASS(result == 1); // Diff between zero and random time (in usec) is random time / -1000 // note: msecdiff simply chops the decimals away tmp.tv_sec = 0; tmp.tv_usec = 999; result = msecdiff(wvtime_zero, tmp); WVPASS(result == 0); tmp.tv_usec = 1000; result = msecdiff(wvtime_zero, tmp); WVPASS(result == -1); tmp.tv_usec = 1001; result = msecdiff(wvtime_zero, tmp); WVPASS(result == -1); // Diff between random time and same time is 0 tmp.tv_sec = 854; tmp.tv_usec = 854; result = msecdiff(tmp, tmp); WVPASS(result == 0); // Test for integer overflow in msecdiff() WvTime t1(1109780720, 0); WvTime t2(1126725000, 0); time_t tdiff = msecdiff(t1, t2); WVPASS(tdiff < 0); } /* * FIXME: I don't know if there is any way to test this. WVTEST_MAIN("wvtime()") { } */ WVTEST_MAIN("msecadd()") { WvTime result, tmp; // test that wvtime_zero + 0 = wvtime_zero result = msecadd(wvtime_zero, 0); WVPASS(result == wvtime_zero); // test that wvtime_zero + 999 = 0sec (999*1000)usec tmp.tv_sec = 0; tmp.tv_usec = 999 * 1000; result = msecadd(wvtime_zero, 999); WVPASS(result == tmp); // test that wvtime_zero + 1000 = 1sec 0usec tmp.tv_sec = 1; tmp.tv_usec = 0; result = msecadd(wvtime_zero, 1000); WVPASS(result == tmp); // test that wvtime_zero + 1001 = 1sec 1000usec tmp.tv_sec = 1; tmp.tv_usec = 1000; result = msecadd(wvtime_zero, 1001); WVPASS(result == tmp); // test that wvtime_zero + -999 = 0sec (-999*1000)usec tmp.tv_sec = 0; tmp.tv_usec = -999 * 1000; normalize(tmp); result = msecadd(wvtime_zero, -999); WVPASS(result == tmp); // test that wvtime_zero + -1000 = -1sec 0usec tmp.tv_sec = -1; tmp.tv_usec = 0; result = msecadd(wvtime_zero, -1000); WVPASS(result == tmp); // test that wvtime_zero + -1001 = -1sec -1000usec tmp.tv_sec = -1; tmp.tv_usec = -1000; normalize(tmp); result = msecadd(wvtime_zero, -1001); WVPASS(result == tmp); } WVTEST_MAIN("tvdiff()") { WvTime result, tmp; // test that zero - zero = 0 result = tvdiff(wvtime_zero, wvtime_zero); WVPASS(result == wvtime_zero); // diff between random time and wvtime_zero = random time tmp.tv_sec = 854; tmp.tv_usec = 854; result = tvdiff(tmp, wvtime_zero); WVPASS(result == tmp); // diff between wvtime_zero and random time = -random time tmp.tv_sec = 854; tmp.tv_usec = 854; result = tvdiff(wvtime_zero, tmp); tmp.tv_sec = -854; tmp.tv_usec = -854; normalize(tmp); WVPASS(result == tmp); // diff between random time and same time = wvzero_time tmp.tv_sec = 854; tmp.tv_usec = 854; result = tvdiff(tmp, tmp); WVPASS(result == wvtime_zero); } WVTEST_MAIN("normalize()") { WvTime result, tmp; // test that zero is normalized to zero result = wvtime_zero; normalize(result); WVPASS(result == wvtime_zero); // Test that time doesn't change if it doesn't need to tmp.tv_sec = 854; tmp.tv_usec = 999999; result = tmp; normalize(result); WVPASS(result == tmp); // Test that a usec value greater than 1000000 is reduced and put into // the sec value result.tv_sec = 854; result.tv_usec = 1000000; normalize(result); tmp.tv_sec = 855; tmp.tv_usec = 0; WVPASS(result == tmp); result.tv_sec = 854; result.tv_usec = 1000001; normalize(result); tmp.tv_sec = 855; tmp.tv_usec = 1; WVPASS(result == tmp); // Test that a negative usec value get converted to a positive val result.tv_sec = 854; result.tv_usec = -1; normalize(result); tmp.tv_sec = 853; tmp.tv_usec = 999999; WVPASS(result == tmp); result.tv_sec = 854; result.tv_usec = -1000001; normalize(result); tmp.tv_sec = 852; tmp.tv_usec = 999999; WVPASS(result == tmp); result.tv_sec = 854; result.tv_usec = -853000001; normalize(result); tmp.tv_sec = 0; tmp.tv_usec = 999999; WVPASS(result == tmp); // test that both vals negative works. result.tv_sec = -854; result.tv_usec = -1; normalize(result); tmp.tv_sec = -855; tmp.tv_usec = 999999; WVPASS(result == tmp); result.tv_sec = -854; result.tv_usec = -1000001; normalize(result); tmp.tv_sec = -856; tmp.tv_usec = 999999; WVPASS(result == tmp); result.tv_sec = -854; result.tv_usec = -853000001; normalize(result); tmp.tv_sec = -1708; tmp.tv_usec = 999999; WVPASS(result == tmp); } WVTEST_MAIN("operator<()") { WvTime a = wvtime_zero; WvTime b = wvtime_zero; // Test that zero is not less than zero WVFAIL(wvtime_zero < wvtime_zero); // Test a few simple positive values a.tv_sec = 2; a.tv_usec = 999999; b.tv_sec = 1; a.tv_usec = 1999998; WVPASS(b < a); a.tv_sec = 2; a.tv_usec = 999999; b.tv_sec = 1; b.tv_usec = 1999999; WVFAIL(b < a); WVFAIL(a < b); a.tv_sec = 2; a.tv_usec = 999999; b.tv_sec = 1; b.tv_usec = 2000000; WVPASS(a < b); // Test a few simple negative values a.tv_sec = -2; a.tv_usec = -999999; b.tv_sec = -1; a.tv_usec = -1999998; WVPASS(a < b); a.tv_sec = -2; a.tv_usec = -999999; b.tv_sec = -1; b.tv_usec = -1999999; WVFAIL(b < a); WVFAIL(a < b); a.tv_sec = -2; a.tv_usec = -999999; b.tv_sec = -1; b.tv_usec = -2000000; WVPASS(b < a); } WVTEST_MAIN("wvstime") { WvTime now = wvstime(); sleep(1); WVPASS(now == wvstime()); WVFAIL(now == wvtime()); WVPASS(now < wvtime()); wvstime_sync(); WVFAIL(now == wvstime()); WVPASS(now < wvstime()); now = wvstime(); WvStream s; s.select(100, true, true); WVFAIL(now == wvstime()); WVPASS(now < wvstime()); now = wvstime(); s.callback(); WVPASS(now == wvstime()); } wvstreams-4.6.1/utils/t/wverror.t.cc0000644000175000001440000000512711036722347016466 0ustar wlachusers#include "wvtest.h" #include "wverror.h" #include void testnoerr(const WvErrorBase &e) { WVPASS(e.isok()); WVPASS(e.geterr() == 0); WVPASSEQ(e.errstr(), strerror(0)); } void testerr(const WvErrorBase &e, int err) { WVPASS(!e.isok()); WVPASS(e.geterr() == err); WVPASSEQ(e.errstr(), strerror(err)); } void testerrstr(const WvErrorBase &e, WvStringParm err) { WVPASS(!e.isok()); WVPASS(e.geterr() == -1); WVPASSEQ(e.errstr(), err); } WVTEST_MAIN("simple set") { WvError e; // initial state testnoerr(e); // set an int e.seterr(1); testerr(e, 1); // int not overwritten e.seterr(2); testerr(e, 1); e.seterr("special"); testerr(e, 1); // reset to initial e.noerr(); testnoerr(e); // set a string e.seterr("special"); testerrstr(e, "special"); // string not overwritten e.seterr(2); testerrstr(e, "special"); e.seterr("specialer"); testerrstr(e, "special"); } WVTEST_MAIN("copy WvErrorBase") { WvError e1; WvError e2; // initial over empty e1.seterr(e2); testnoerr(e1); // initial over int e1.seterr(1); e1.seterr(e2); testerr(e1, 1); e1.noerr(); // initial over str e1.seterr("special"); e1.seterr(e2); testerrstr(e1, "special"); e1.noerr(); e2.seterr(2); // int over empty e1.seterr(e2); testerr(e1, 2); e1.noerr(); // int over int e1.seterr(1); e1.seterr(e2); testerr(e1, 1); e1.noerr(); // int over str e1.seterr("special"); e1.seterr(e2); testerrstr(e1, "special"); e1.noerr(); e2.noerr(); e2.seterr("specialer"); // str over empty e1.seterr(e2); testerrstr(e1, "specialer"); e1.noerr(); // str over int e1.seterr(1); e1.seterr(e2); testerr(e1, 1); e1.noerr(); // str over str e1.seterr("special"); e1.seterr(e2); testerrstr(e1, "special"); e1.noerr(); } WVTEST_MAIN("set to -1") { WvError e; // overwrite an int e.seterr(1); e.seterr(-1); testerr(e, 1); e.noerr(); // overwrite a str e.seterr("special"); e.seterr(-1); testerrstr(e, "special"); e.noerr(); #if 0 // set directly - should crash e.seterr(-1); testnoerr(e); #endif } WVTEST_MAIN("seterr_both") { WvError e; e.set_both(EEXIST, "blah blah"); WVFAIL(e.isok()); WVPASSEQ(e.get(), EEXIST); WVPASSEQ(e.str(), "blah blah"); WvError e2 = e; WVFAIL(e2.isok()); WVPASSEQ(e2.get(), EEXIST); WVPASSEQ(e2.str(), "blah blah"); } wvstreams-4.6.1/utils/t/wvcallbacklist.t.cc0000644000175000001440000000144411036722347017763 0ustar wlachusers#include "wvcallbacklist.h" #include "wvtest.h" #include "wvtr1.h" typedef wv::function TestCallback; /* The return value will be ignored. */ int testcb(int &count) { ++count; return 42; } WVTEST_MAIN("WvCallbackList sanity") { WvCallbackList list; const unsigned int numcb = 42; char jar[numcb]; int count; WVPASS(list.isempty()); for (unsigned int i = 0; i < numcb; ++i) list.add(testcb, &jar[i]); WVPASS(!list.isempty()); count = 0; list(count); WVPASSEQ(count, numcb); list.del(&jar[0]); count = 0; list(count); WVPASSEQ(count, numcb - 1); for (unsigned int i = 1; i < numcb; ++i) list.del(&jar[i]); WVPASS(list.isempty()); count = 0; list(count); WVPASSEQ(count, 0); } wvstreams-4.6.1/utils/t/wvstreamsdebugger.t.cc0000644000175000001440000000304211036722347020512 0ustar wlachusers#include "wvtest.h" #include "wvstreamsdebugger.h" #include "wvstream.h" void *cmd_init(WvStringParm cmd) { wvcon->print("%s: %s\n", __FUNCTION__, cmd); int *var = new int; *var = 0; return var; } WvString cmd_run(WvStringParm cmd, WvStringList &args, WvStreamsDebugger::ResultCallback result_cb, void *ud) { wvcon->print("%s: %s\n", __FUNCTION__, cmd); WvStringList result_list; result_list.append("value is %s", *(const int *)ud); result_cb(cmd, result_list); return WvString::null; } void cmd_cleanup(WvStringParm cmd, void *ud) { wvcon->print("%s: %s\n", __FUNCTION__, cmd); delete (int *)ud; } void foreach_cb(WvStringParm cmd, void *ud) { wvcon->print("%s: %s\n", __FUNCTION__, cmd); ++*(int *)ud; } static WvString result; void result_cb(WvStringParm cmd, WvStringList &result_list) { wvcon->print("%s: %s\n", __FUNCTION__, cmd); result = result_list.join(" "); } WVTEST_MAIN("add command") { WvStreamsDebugger::add_command("foo", cmd_init, cmd_run, cmd_cleanup); WvStreamsDebugger debugger; WvStringList args; WVPASS(result.isnull()); debugger.run("foo", args, result_cb); WVPASSEQ(result, "value is 0"); WvStreamsDebugger::foreach("foo", foreach_cb); WVPASSEQ(result, "value is 0"); debugger.run("foo", args, result_cb); WVPASSEQ(result, "value is 1"); WvStreamsDebugger::foreach("foo", foreach_cb); WVPASSEQ(result, "value is 1"); debugger.run("foo", args, result_cb); WVPASSEQ(result, "value is 2"); } wvstreams-4.6.1/utils/t/wvtclstring.t.cc0000644000175000001440000002717211036722347017352 0ustar wlachusers#include "wvtest.h" #include "wvtclstring.h" #include "wvstring.h" #include "wvstringlist.h" #include "wvstringmask.h" #include "wvstream.h" #include WVTEST_MAIN("escaping and unescaping") { WvString a, b(""), c("jabba"), d("crab poody-doo"), e("\"quote this!\""), f("pooky{doo"), g("big}monkey {potatoes"), h("hammer\\}time"), i("shameless{frog}parts"), j("wagloo-mas\nuffle"), k("nasty{bad{}}}$break"), result, desired; //null result = wvtcl_escape(a); WVFAIL(result); result = wvtcl_unescape(result); WVPASSEQ(result, a); result = wvtcl_escape(b); desired = WvString("{}"); WVPASSEQ(result, desired); result = wvtcl_unescape(result); WVPASSEQ(result, b); //no escape required result = wvtcl_escape(c); WVPASSEQ(result, c); result = wvtcl_unescape(result); WVPASSEQ(result, c); //bracket escape required WVPASSEQ(wvtcl_escape(" foo"), "{ foo}"); WVPASSEQ(wvtcl_escape("foo "), "{foo }"); result = wvtcl_escape(d); desired = WvString("{%s}", d.cstr()); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); WVPASS(result == d); result = wvtcl_escape(e); desired = WvString("{\"quote this!\"}"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(WvString("\"quote this!\"")); desired = WvString("quote this!"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_escape(i); desired = WvString("{shameless{frog}parts}"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); if (!WVPASS(result == i)) printf(" because [%s] != [%s]\n", result.cstr(), i.cstr()); result = wvtcl_escape(h); desired = WvString("{hammer\\}time}"); printf("%s\n", result.cstr()); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); if (!WVPASS(result == h)) printf(" because [%s] != [%s]\n", result.cstr(), h.cstr()); //\ escaping required result = wvtcl_escape(f); desired = WvString("pooky\\{doo"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); if (!WVPASS(result == f)) printf(" because [%s] != [%s]\n", result.cstr(), f.cstr()); result = wvtcl_escape(g); desired = WvString("big\\}monkey\\ \\{potatoes"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); if (!WVPASS(result == g)) printf(" because [%s] != [%s]\n", result.cstr(), g.cstr()); //escaping with our own nasties result = wvtcl_escape(j, WvStringMask("o-\nu")); desired = WvString("{wagloo-mas\nuffle}"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); if (!WVPASS(result == j)) printf(" because [%s] != [%s]\n", result.cstr(), j.cstr()); result = wvtcl_escape(k, WvStringMask("$ky")); desired = WvString("nast\\y\\{bad\\{\\}\\}\\}\\$brea\\k"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = wvtcl_unescape(result); printf("%s\n", result.cstr()); if (!WVPASS(result == k)) printf(" because [%s] != [%s]\n", result.cstr(), k.cstr()); } WVTEST_MAIN("encoding and decoding") { signal(SIGALRM, SIG_IGN); WvString a("jabba"), b("crab poody-doo"), c("pooky{doo"), result, desired; WvStringList list; list.append(&a, false); list.append(&b, false); list.append(&c, false); list.append(new WvString(), true); result = wvtcl_encode(list, WvStringMask(' '), WvStringMask(' ')); desired = WvString("%s {%s} pooky\\{doo ", a, b); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); wvtcl_decode(list, result); result = *list.first(); list.unlink_first(); if (!WVPASS(result == a)) printf(" because [%s] != [%s]\n", result.cstr(), a.cstr()); result = *list.first(); list.unlink_first(); if (!WVPASS(result == b)) printf(" because [%s] != [%s]\n", result.cstr(), b.cstr()); result = *list.first(); list.unlink_first(); if (!WVPASS(result == c)) printf(" because [%s] != [%s]\n", result.cstr(), c.cstr()); result = *list.first(); WVFAIL(result); list.unlink_first(); } WVTEST_MAIN("getword") { WvDynBuf buf; WvString result, desired, test("jabba {crab poody-doo} pooky\\{doo"); // set buffer buf.putstr(test); // don't unescape result = wvtcl_getword(buf, WvStringMask(" "), false); desired = WvString("jabba"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); // buffer should be updated properly result = buf.getstr(); desired = WvString(" {crab poody-doo} pooky\\{doo"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); // reset buffer buf.putstr(test); // unescape result = wvtcl_getword(buf, WvStringMask(" ")); desired = WvString("jabba"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); // buffer should be updated properly result = wvtcl_getword(buf, WvStringMask(" ")); desired = WvString("crab poody-doo"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); result = buf.getstr(); desired = WvString(" pooky\\{doo"); if (!WVPASS(result == desired)) printf(" because [%s] != [%s]\n", result.cstr(), desired.cstr()); // test no word possible test = WvString("---{incomplete-"); buf.putstr(test); result = wvtcl_getword(buf, WvStringMask("-")); // should return null WVFAIL(result); result = buf.getstr(); if (!WVPASS(result == test)) printf(" because [%s] != [%s]\n", result.cstr(), test.cstr()); // test no word possible and whitespace eating test = WvString(" "); buf.putstr(test); result = wvtcl_getword(buf, WvStringMask(" ")); // should return null WVFAIL(result); result = buf.getstr(); // buffer should be reset to original state, ie unchanged if (!WVPASS(result == test)) printf(" because [%s] != [%s]\n", result.cstr(), test.cstr()); } static void _do_word(WvBuf &buf, WvStringParm word, size_t expect) { WvString new_word = wvtcl_getword(buf, WVTCL_NASTY_NEWLINES); WVPASSEQ(buf.used(), expect); WVPASSEQ(word, new_word); } static void do_word(WvBuf &buf, WvStringParm word, size_t expect) { buf.putstr("%s\n", word); _do_word(buf, word, expect); } WVTEST_MAIN("getword with dynamic buffer") { WvDynBuf buf; WvString word; buf.putstr("\n\n\n"); do_word(buf, "foo", 1); buf.zap(); do_word(buf, "n = 6", 1); do_word(buf, "", 2); // left old newline *and* new newline do_word(buf, "[S1]", 1); do_word(buf, "a = b", 1); do_word(buf, "", 2); do_word(buf, "[S2]", 1); do_word(buf, "Enable = 0", 1); } WVTEST_MAIN("wvtcl_encode specific failures") { WvStringList words; wvout->print(wvtcl_encode(words)); words.append("{{2304 5816322} var} 1102878961 DIR"); words.append("{{2304 5816323} lib} 1098721377 DIR"); words.append("{{2304 5852807} defoma} 1098721283 DIR"); words.append("{{2304 5852904} gs.d} 1098721283 DIR"); words.append("{{2304 5852905} dirs} 1098721269 DIR"); words.append("{{2304 5852906} fonts} 1098721283 DIR"); words.append("{{2304 5853099} Fontmap} 1098721283 REG"); wvout->print(wvtcl_encode(words)); } WVTEST_MAIN("mismatched braces") { WvDynBuf buf; buf.putstr("close}\n{brace}\n{me\n"); _do_word(buf, "close}", 13); // first closebrace isn't "special" _do_word(buf, "brace", 5); // second word is in braces _do_word(buf, WvString(), 5); // last word is incomplete } WVTEST_MAIN("backslashed braces") { WvString line("VAL a b\\}\\\n\\{c\\}\\ =\\ d\\\ne\\ =\\ f\\{"); WvString encoded("%s\n", line); WvString word1("VAL"), word2("a"), word3("b}\n{c} = d\ne = f{"); WvDynBuf buf; buf.putstr(encoded); WVPASSEQ(buf.used(), 34); WvString oline = wvtcl_getword(buf, WVTCL_NASTY_NEWLINES, false); WVPASSEQ(line, oline); WVPASSEQ(buf.used(), 1); // trailing newline buf.zap(); buf.putstr(line); WvString w1 = wvtcl_getword(buf, WvStringMask(" ")); WvString w2 = wvtcl_getword(buf, WvStringMask(" ")); WvString w3 = wvtcl_getword(buf, WvStringMask(" ")); WVPASSEQ(w1, word1); WVPASSEQ(w2, word2); WVPASSEQ(w3, word3); } WVTEST_MAIN("BUGZID:17077") { const char *dirname = "directory name ending in backslash \\"; WvString encoded_dirname = wvtcl_escape(dirname); WvDynBuf buf; buf.putstr(encoded_dirname); WVPASSEQ(wvtcl_getword(buf, WVTCL_NASTY_NEWLINES, false), encoded_dirname); } static void tcltest(const char *a, const char *b) { if (strcmp(a, b) != 0) { fprintf(stderr, "\n"); WVPASSEQ(a, b); // always fails } else fprintf(stderr, "."); // otherwise just print a progress dot } WVTEST_MAIN("wvtcl_getword comprehensive nounescape") { WvDynBuf buf; const int slen = 4; char str[slen+1], last[slen+1] = "goo"; struct { const char *chars; const WvStringMask *mask; } const *test_set, test_sets[] = { { "a{}\\\"", &WVTCL_NASTY_SPACES }, { "a {}\\\"", &WVTCL_NASTY_NEWLINES }, { NULL, NULL } }; for (test_set = &test_sets[0]; test_set->chars; ++test_set) { const WvStringMask &mask = *test_set->mask; const char *chars = test_set->chars; const int len = strlen(chars) + 1; for (int i=0; isplit(*heapString); WVPASS(testTable4->count() == 5); testTable4->splitstrict(*heapString); WVPASS(testTable4->count() == 11); /*testTable4->zap(); testTable4->splitstrict(WvString("I rock hard"), " ", 2); WVFAIL((*testTable4)["rock hard"] != NULL);*/ delete testTable4; WVPASS(!strcmp(heapString->cstr(), "This is\t\talmost\ndone!\t")); delete heapString; } } // END stringtabletest.cc definition wvstreams-4.6.1/utils/t/wvhex.t.cc0000644000175000001440000004600211036722347016116 0ustar wlachusers#include #ifdef _WIN32 #define snprintf _snprintf #endif #include "wvautoconf.h" #ifndef HAVE_ALLOCA # ifdef __GNUC__ # define alloca __builtin_alloca # else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif # endif #endif #include "wvtest.h" #include "wvbuf.h" #include "wvhex.h" #include "wvstream.h" #define THREE_LETTERS "abz" #define THREE_LETTERS_ENC_LC "61627a" #define THREE_LETTERS_ENC_UC "61627A" #define FOUR_LETTERS "a+cz" #define FOUR_LETTERS_ENC_LC "612b637a" #define FOUR_LETTERS_ENC_UC "612B637A" #define FIVE_LETTERS "abcdz" #define FIVE_LETTERS_ENC_LC "616263647a" #define FIVE_LETTERS_ENC_UC "616263647A" #define SIX_LETTERS "ab^dez" #define SIX_LETTERS_ENC_LC "61625e64657a" #define SIX_LETTERS_ENC_UC "61625E64657A" WVTEST_MAIN("basic encoding lowercase") { // always use a brand new encoder since we don't want to have to // deal with 'finish' issues in this WVTEST_MAIN block const char* INPUTS[] = {THREE_LETTERS, FOUR_LETTERS, FIVE_LETTERS, SIX_LETTERS}; const char* OUTPUTS[] = {THREE_LETTERS_ENC_LC, FOUR_LETTERS_ENC_LC, FIVE_LETTERS_ENC_LC, SIX_LETTERS_ENC_LC}; const unsigned int num_tests = 4; for (unsigned int i = 0; i < num_tests; i++) { WvHexEncoder enc; WvString result = enc.strflushstr(INPUTS[i], true); WVPASS(result == OUTPUTS[i]); } { // encode all possible characters WvHexEncoder enc; WvDynBuf src,dest; for (unsigned int c = 0; c <= 255; c++) src.put((unsigned char) c); bool result = enc.encode(src,dest,true,true); WVPASS(result == true); WVPASS(dest.used() == 512); bool encoded_correctly = true; unsigned int n = dest.used() / 2; for (unsigned int i = 0; i < n; i++) { char buf[3]; buf[0] = dest.peek(i*2); buf[1] = dest.peek(i*2 + 1); buf[2] = '\0'; long int curr = strtol(buf, NULL, 16); if ((unsigned int) curr != i) { encoded_correctly = false; break; } } WVPASS(encoded_correctly); } } WVTEST_MAIN("basic encoding uppercase") { // always use a brand new encoder since we don't want to have to // deal with 'finish' issues in this WVTEST_MAIN block const char* INPUTS[] = {THREE_LETTERS, FOUR_LETTERS, FIVE_LETTERS, SIX_LETTERS}; const char* OUTPUTS[] = {THREE_LETTERS_ENC_UC, FOUR_LETTERS_ENC_UC, FIVE_LETTERS_ENC_UC, SIX_LETTERS_ENC_UC}; const unsigned int num_tests = 4; for (unsigned int i = 0; i < num_tests; i++) { WvHexEncoder enc(true); WvString result = enc.strflushstr(INPUTS[i], true); WVPASS(result == OUTPUTS[i]); } { // encode all possible characters WvHexEncoder enc(true); WvDynBuf src,dest; for (unsigned int c = 0; c <= 255; c++) src.put((unsigned char) c); bool result = enc.encode(src,dest,true,true); WVPASS(result == true); WVPASS(dest.used() == 512); bool encoded_correctly = true; unsigned int n = dest.used() / 2; for (unsigned int i = 0; i < n; i++) { char buf[3]; buf[0] = dest.peek(i*2); buf[1] = dest.peek(i*2 + 1); buf[2] = '\0'; long int curr = strtol(buf, NULL, 16); if ((unsigned int) curr != i) { encoded_correctly = false; break; } } WVPASS(encoded_correctly); } } WVTEST_MAIN("legacy hexify function") { // Note that if ibuf is of length n, then obuf must be of // length 2*n + 1 (two bytes for each byte in ibuf, plus // terminating null. // basic tests const char* INPUTS[] = {THREE_LETTERS, FOUR_LETTERS, FIVE_LETTERS, SIX_LETTERS}; const char* OUTPUTS[] = {THREE_LETTERS_ENC_LC, FOUR_LETTERS_ENC_LC, FIVE_LETTERS_ENC_LC, SIX_LETTERS_ENC_LC}; unsigned int num_tests = 4; for (unsigned int i = 0; i < num_tests; i++) { const char *ibuf = INPUTS[i]; size_t n = strlen(ibuf); char *obuf = (char *) alloca(2*n + 1); hexify(obuf, ibuf, n); WVPASS(strcmp(obuf, OUTPUTS[i])==0); } // make sure that 3rd parameter is handled correctly { const char *ibuf = THREE_LETTERS; const size_t n = 2; char obuf[2*n + 1]; memset(obuf, 'K', n); // to be sure that final \0 is put in later hexify(obuf, ibuf, n); WVPASS(strlen(obuf) == 2*n && strncmp(obuf, THREE_LETTERS_ENC_LC,2*n) == 0); } { const char *ibuf = SIX_LETTERS; const size_t n = 1; char obuf[2*n + 1]; memset(obuf, 'K', n); // to be sure that final \0 is put in later hexify(obuf, ibuf, n); WVPASS(strlen(obuf) == 2*n && strncmp(obuf, SIX_LETTERS_ENC_LC,2*n) == 0); } } WVTEST_MAIN("basic decoding lowercase") { // same tests as above, but now doing the reverse operation { // 3 characters... WvHexDecoder dec; WvString result = dec.strflushstr(THREE_LETTERS_ENC_LC, true); WVPASS(result == THREE_LETTERS); } { // 4 characters... WvHexDecoder dec; WvString result = dec.strflushstr(FOUR_LETTERS_ENC_LC, true); WVPASS(result == FOUR_LETTERS); } { // 5 characters... WvHexDecoder dec; WvString result = dec.strflushstr(FIVE_LETTERS_ENC_LC, true); WVPASS(result == FIVE_LETTERS); } { // 6 characters... WvHexDecoder dec; WvString result = dec.strflushstr(SIX_LETTERS_ENC_LC, true); WVPASS(result == SIX_LETTERS); } { // decode all possible characters WvHexDecoder dec; WvDynBuf src,dest; for (unsigned int c = 0; c <= 255; c++) { char buf[3]; snprintf(buf, 3, "%02x", c); src.put(buf, 2); } dec.encode(src,dest,true,true); WVPASS(dest.used() == 256); bool decoded_correctly = true; for (unsigned int i = 0; i < dest.used(); i++) { if (dest.peek(i) != i) { decoded_correctly = false; break; } } WVPASS(decoded_correctly); } } WVTEST_MAIN("basic decoding uppercase") { // same tests as above, but now doing the reverse operation { // 3 characters... WvHexDecoder dec; WvString result = dec.strflushstr(THREE_LETTERS_ENC_UC, true); WVPASS(result == THREE_LETTERS); } { // 4 characters... WvHexDecoder dec; WvString result = dec.strflushstr(FOUR_LETTERS_ENC_UC, true); WVPASS(result == FOUR_LETTERS); } { // 5 characters... WvHexDecoder dec; WvString result = dec.strflushstr(FIVE_LETTERS_ENC_UC, true); WVPASS(result == FIVE_LETTERS); } { // 6 characters... WvHexDecoder dec; WvString result = dec.strflushstr(SIX_LETTERS_ENC_UC, true); WVPASS(result == SIX_LETTERS); } { // decode all possible characters WvHexDecoder dec; WvDynBuf src,dest; for (unsigned int c = 0; c <= 255; c++) { char buf[3]; snprintf(buf, 3, "%02X", c); src.put(buf, 2); } dec.encode(src,dest,true,true); WVPASS(dest.used() == 256); bool decoded_correctly = true; for (unsigned int i = 0; i < dest.used(); i++) { if (dest.peek(i) != i) { decoded_correctly = false; break; } } WVPASS(decoded_correctly); } } // void unhexify(unsigned char *obuf, char *ibuf) // // obuf must be a buffer large enough to contain the entire binary // output string; you can calculate this size with (strlen(ibuf) / 2). // obuf should not be automatically NUL-terminated. // // factor out testing of upper case and lowercase void legacy_unhexify_test(const char *INPUTS[], const char *OUTPUTS[], const unsigned int num_tests) { // test basic decoding with a string that's initially zeros for (unsigned int i = 0; i < num_tests; i++) { const char* ibuf = INPUTS[i]; const size_t n = (strlen(ibuf)/2) + 1; char *obuf = (char *) alloca(n); memset(obuf, 0, n); // make sure it's all zeros unhexify(obuf, ibuf); WVPASS(strcmp(obuf, OUTPUTS[i]) == 0); } // test that obuf is not nul terminated for (unsigned int i = 0; i < num_tests; i++) { const char* ibuf = INPUTS[i]; const size_t n = (strlen(ibuf)/2) + 3; char *obuf = (char *) alloca(n); memset(obuf, 'K', n); // fill it up with something non-zero unhexify(obuf+1, ibuf); // allow one 'K' at the beginning WvString actual_output("K%sKK", OUTPUTS[i]); WVPASS(strncmp(obuf, actual_output.cstr(),n) == 0); } } WVTEST_MAIN("legacy unhexify function (lowercase input)") { const char* INPUTS[] = {THREE_LETTERS_ENC_LC, FOUR_LETTERS_ENC_LC, FIVE_LETTERS_ENC_LC, SIX_LETTERS_ENC_LC}; const char* OUTPUTS[] = {THREE_LETTERS, FOUR_LETTERS, FIVE_LETTERS, SIX_LETTERS}; legacy_unhexify_test(INPUTS, OUTPUTS, 4); } WVTEST_MAIN("legacy unhexify function (uppercase input)") { const char* INPUTS[] = {THREE_LETTERS_ENC_UC, FOUR_LETTERS_ENC_UC, FIVE_LETTERS_ENC_UC, SIX_LETTERS_ENC_UC}; const char* OUTPUTS[] = {THREE_LETTERS, FOUR_LETTERS, FIVE_LETTERS, SIX_LETTERS}; legacy_unhexify_test(INPUTS, OUTPUTS, 4); } WVTEST_MAIN("encode/decode feedback loop") { // Encodes a string in a feedback loop n times, then decodes it n times. // number of times to repeatedly encode for (int n = 2; n < 9; n++ ) { WvString orig("Milk and Cereal"), src, dest; src = orig; for (int i = 0; i < n; i++) { WvHexEncoder enc; enc.flushstrstr(src, dest, true); src = dest; dest = ""; } for (int i = 0; i < n; i++) { WvHexDecoder dec; dec.flushstrstr(src, dest, true); src = dest; dest = ""; } WVPASS( src == orig ); } } WVTEST_MAIN("nothing to encode/decode") { for (int i = 1; i <= 2; i++ ) { { // "null" WvString WvEncoder *enc = (i == 1) ? (WvEncoder *)new WvHexEncoder : new WvHexDecoder; WvString nul, result("stuff there"); enc->flushstrstr(nul, result, true); WVPASS(result == "stuff there"); delete(enc); } { // empty WvString WvEncoder *enc = (i == 1) ? (WvEncoder *)new WvHexEncoder : new WvHexDecoder; WvString empty(""), result("stuff there"); enc->flushstrstr(empty, result, true); WVPASS(result == "stuff there"); delete(enc); } { // empty WvBuf WvEncoder *enc = (i == 1) ? (WvEncoder *)new WvHexEncoder : new WvHexDecoder; WvDynBuf empty, dest; empty.zap(); // ... just to be sure dest.put("stuff there", 11); enc->encode(empty, dest, true, true); WVPASS(dest.used() == 11 && !memcmp(dest.get(dest.used()), "stuff there", 11)); delete(enc); } { // empty char* WvEncoder *enc = (i == 1) ? (WvEncoder *)new WvHexEncoder : new WvHexDecoder; const char *empty = ""; WvDynBuf dest; dest.put("stuff there",11); enc->flushmembuf(empty, 0, dest, true); WVPASS(dest.used() == 11 && !memcmp(dest.get(dest.used()), "stuff there", 11)); delete(enc); } } } WVTEST_MAIN("decoding whitespace") { { // white space at beginning WvHexDecoder dec; WvString a_enc(" " FOUR_LETTERS_ENC_LC), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // white space at end WvHexDecoder dec; WvString a_enc(FOUR_LETTERS_ENC_LC " \n "), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // white space in middle WvHexDecoder dec; WvString a_enc("6 1 2\tb \t\n 6 3 7 a"), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // all kinds of crazy whitespace everywhere WvHexDecoder dec; WvString a_enc("6 1\v\n 2 b \t 6\n\n\n3 7\r a"), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } } WVTEST_MAIN("decoding invalid data") { { // out of range data at beginning WvHexDecoder dec; WvDynBuf src,dest; unsigned char invalid[] = {'G', 'h', 'i'}; src.put(invalid, 3); src.put(FOUR_LETTERS_ENC_LC, sizeof(FOUR_LETTERS_ENC_LC)-1); unsigned int original_size = src.used(); bool ret = dec.encode(src,dest,true,false); WVFAIL(dec.isok()); // read bad data WVPASS(ret == false && dest.used() == 0); // should have removed the character from the buffer WVPASS(src.used() == original_size - 1); } { // out of range data in middle WvHexDecoder dec; WvDynBuf src,dest; src.put("612b", 4); src.put('K'); // the invalid character src.put("637A", 4); bool ret = dec.encode(src,dest,true,false); WVFAIL(dec.isok()); // read bad data WVPASS(ret == false); // decoded as much as possible though... a2Vu -> ken WVPASS(dest.used() == 2 && !memcmp(dest.peek(0,dest.used()), "a+", 2)); WVPASS(src.used() == 4); // 4 chars left since should have removed // the bad character } } #define SHORT_MESSAGE "The quick brown fox jumps over the lazy dog." #define SHORT_MESSAGE_ENC "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f672e" WVTEST_MAIN("encoding data that is streamed in") { // Tests that the encoder works when not all of the data is available at // once. { // Encoder only has access to one character at a time WvHexEncoder enc; WvDynBuf src; WvString a(SHORT_MESSAGE),result; for (unsigned int i = 0; i < a.len(); i++) { src.put(a.edit()[i]); enc.flushbufstr(src, result, false); } enc.flushbufstr(src, result, true); WVPASS(result == SHORT_MESSAGE_ENC); } { // encoder has access to three letters at a time WvHexEncoder enc; WvDynBuf src; WvString result; src.put(THREE_LETTERS, sizeof(THREE_LETTERS) - 1); enc.flushbufstr(src, result, false); src.put(THREE_LETTERS, sizeof(THREE_LETTERS) - 1); enc.flushbufstr(src, result, true); // end of stream now WVPASS(result == THREE_LETTERS_ENC_LC THREE_LETTERS_ENC_LC); } } WVTEST_MAIN("decoding data that is streamed in") { // same tests as above, but with decoding... { // one char at a time WvHexDecoder dec; WvDynBuf src; WvString a(SHORT_MESSAGE_ENC),result; for (unsigned int i = 0; i < a.len(); i++) { src.put(a.edit()[i]); dec.flushbufstr(src, result, false); } dec.flushbufstr(src, result, true); WVPASS(result == SHORT_MESSAGE); } { // six chars at a time WvHexDecoder dec; WvDynBuf src; WvString result; src.put(THREE_LETTERS_ENC_LC, sizeof(THREE_LETTERS_ENC_LC) - 1); dec.flushbufstr(src, result, false); src.put(THREE_LETTERS_ENC_LC, sizeof(THREE_LETTERS_ENC_LC) - 1); dec.flushbufstr(src, result, true); // end of stream now WVPASS(result == THREE_LETTERS THREE_LETTERS); } } WVTEST_MAIN("flushing") { // flush is true { WvHexEncoder enc; WvDynBuf src, dest; bool result; src.put( "a+", 2 ); result = enc.encode(src, dest, true, false); // flush it WVPASS(result); // shouldn't have anything buffered WVPASS(dest.used() == 4 && !memcmp( dest.peek( 0, dest.used() ), "612b", 4)); src.put( "cz", 2 ); result = enc.encode(src, dest, true, false); // flush it WVPASS(result); // still nothing buffered WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "612b637a", 8)); } // same test, but with flush == false { WvHexEncoder enc; WvDynBuf src, dest; bool result; src.put( "a+", 2 ); result = enc.encode(src, dest, false, false); // flush it WVPASS(result); // shouldn't have anything buffered WVPASS(dest.used() == 4 && !memcmp( dest.peek( 0, dest.used() ), "612b", 4)); src.put( "cz", 2 ); result = enc.encode(src, dest, false, false); // flush it WVPASS(result); // still nothing buffered WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "612b637a", 8)); } // same test as first, but calling flush() instead // flush is true { WvHexEncoder enc; WvDynBuf src, dest; bool result; src.put("a+", 2 ); result = enc.flush(src, dest, false); // flush it WVPASS(result); // shouldn't have anything buffered WVPASS(dest.used() == 4 && !memcmp( dest.peek( 0, dest.used() ), "612b", 4)); src.put( "cz", 2 ); result = enc.flush(src, dest, false); // flush it WVPASS(result); WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "612b637a", 8)); } } WVTEST_MAIN("finishing") { // Tests that calling finish() works correctly { WvHexEncoder enc; WvString a(FOUR_LETTERS), a_enc(FOUR_LETTERS_ENC_LC), result; enc.flushstrstr(a, result, true); WVPASS(result == a_enc); WVPASS(enc.isfinished()); WVPASS(enc.isfinished() == enc.isok()); // should be able to call twice WvString should_be_empty(""); bool b = enc.flushstrstr( a, should_be_empty, true ); // can't encode again WVFAIL(b); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == a_enc); } // Same test as above, but explicitly call finish() { WvHexEncoder enc; WvDynBuf src, dest; src.put(FOUR_LETTERS, sizeof(FOUR_LETTERS) - 1); enc.encode(src, dest, true, false); // don't finish yet. enc.finish(dest); // ok, NOW finish. WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), FOUR_LETTERS_ENC_LC, 8)); WVPASS(enc.isfinished()); WVPASS(enc.isfinished() == enc.isok()); // should be able to call twice // shouldn't be able to encode again dest.zap(); bool b = enc.encode(src, dest, true, true); WVFAIL(b); WVPASS(dest.used() == 0); } // Now we do the same two tests with Decoders { WvHexDecoder dec; WvString a(FOUR_LETTERS_ENC_LC), a_dec(FOUR_LETTERS), result; dec.flushstrstr(a, result, true); WVPASS(result == a_dec); WVPASS(dec.isfinished()); WVPASS(dec.isfinished() == dec.isok()); // should be able to call twice WvString should_be_empty(""); bool b = dec.flushstrstr( a, should_be_empty, true ); // can't encode again WVFAIL(b); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == a_dec); } { WvHexDecoder dec; WvDynBuf src, dest; src.put(FOUR_LETTERS_ENC_LC, sizeof(FOUR_LETTERS_ENC_LC) - 1); dec.encode(src, dest, true, false); // don't finish yet. dec.finish(dest); // ok, NOW finish. WVPASS(dest.used() == 4 && !memcmp( dest.peek( 0, dest.used() ), FOUR_LETTERS, 4)); WVPASS(dec.isfinished()); WVPASS(dec.isfinished() == dec.isok()); // should be able to call twice // shouldn't be able to encode again dest.zap(); bool b = dec.encode(src, dest, true, true); WVFAIL(b); WVPASS(dest.used() == 0); } } WVTEST_MAIN("resetting") { { // call finish, make sure it was finished, then reset it and // use it again WvHexEncoder enc; WvDynBuf temp; WvString b(SIX_LETTERS), b_enc(SIX_LETTERS_ENC_LC); WvString should_be_empty(""); enc.finish(temp); WVPASS(enc.isfinished()); // ensure finished bool ret = enc.flushstrstr( b, should_be_empty, true ); // can't encode again WVFAIL(ret); WVPASS(should_be_empty == ""); enc.reset(); WVFAIL(enc.isfinished()); WvString result(""); enc.flushstrstr(b, result, true); WVPASS(result == b_enc); WVPASS(enc.isfinished()); } // same test as above with Decoder { // call finish, make sure it was finished, then reset it and // use it again WvHexDecoder dec; WvDynBuf temp; WvString b(SIX_LETTERS), b_enc(SIX_LETTERS_ENC_LC); WvString should_be_empty(""); dec.finish(temp); WVPASS(dec.isfinished()); // ensure finished bool ret = dec.flushstrstr( b_enc, should_be_empty, true ); // can't encode again WVFAIL(ret); WVPASS(should_be_empty == ""); dec.reset(); WVFAIL(dec.isfinished()); WvString result(""); dec.flushstrstr(b_enc, result, true); WVPASS(result == b); WVPASS(dec.isfinished()); } } wvstreams-4.6.1/utils/t/wvdelayedcallback.t.cc0000644000175000001440000000316411042636572020421 0ustar wlachusers#include "wvdelayedcallback.h" #include "wvistreamlist.h" #include "wvtest.h" static int num; static void add_cb(int howmuch) { num += howmuch; } typedef wv::function InnerCallback; WVTEST_MAIN("repetition") { num = 0; WvIStreamList l; // Create all these with different syntax to make sure all the different // syntaxes actually work. InnerCallback xx = &add_cb; InnerCallback cb1 = WvDelayedCallback(xx); InnerCallback cb2 = wv::delayed(xx); wv::delayed(&add_cb); InnerCallback cb3 = wv::delayed(wv::bind(&add_cb, _1)); InnerCallback cb4 = wv::delayed(&add_cb); InnerCallback cb5 = wv::delayed(wv::delayed(wv::delayed(&add_cb))); l.runonce(10); WVPASSEQ(num, 0); cb1(5); l.runonce(10); WVPASSEQ(num, 5); l.runonce(10); WVPASSEQ(num, 5); cb1(1); cb1(2); WVPASSEQ(num, 5); l.runonce(10); WVPASSEQ(num, 7); l.runonce(10); WVPASSEQ(num, 7); cb1(1); cb1 = 0; // though the callback is now gone, the underlying stream is still // on the globallist (though close()d), and alarm(0)'d; it will // still run. l.runonce(10); WVPASSEQ(num, 8); #if WVDELAYED_SUPPORTS_NESTING_PROPERLY // FIXME: See wvdelayedcallback.h for information about why nested // WvDelayedCallback objects don't actually work. cb5(100); cb4(200); WVPASSEQ(num, 7); l.runonce(10); WVPASSEQ(num, 207); l.runonce(10); WVPASSEQ(num, 207); l.runonce(10); WVPASSEQ(num, 207); l.runonce(10); WVPASSEQ(num, 307); #endif } wvstreams-4.6.1/utils/t/strutils.t.cc0000644000175000001440000012435411077430155016653 0ustar wlachusers#include "wvtest.h" #include "wvfile.h" #include "strutils.h" #include "wvlinklist.h" #ifdef _WIN32 #include #else #include #endif #include /** * Functions in strutils.h left untested: * hexdump_buffer * isnewline * rfc822_date * rfc1123_date * passwd_crypt * * Tests that may be incorrect: * fqdomainname */ /** Tests terminate_string(). * terminate_string() should remove any trailing whitespace on the * incoming string and append the provided char. */ WVTEST_MAIN("terminate_string") { char *input[] = {new char[6], new char[7], new char[2], new char[4]}; strcpy(input[0], "blah"); strcpy(input[1], "blah\n"); strcpy(input[2], ""); strcpy(input[3], "\r\n"); const char *desired[] = {"blah!", "blah!", "!", "!"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = terminate_string(input[i], '!'); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev input[i]; } } /** Tests trim_string(). * trim_string() should remove any leading or trailing whitespace from * the incoming string. */ WVTEST_MAIN("trim") { char *input[] = {new char[7], new char[10], new char[10], new char[10], new char[8]}; strcpy(input[0], "foobar"); strcpy(input[1], "\t foobar"); strcpy(input[2], "foobar\n "); strcpy(input[3], " \tfoo\r\t \n"); strcpy(input[4], "foo bar"); const char *desired[] = {"foobar", "foobar", "foobar", "foo", "foo bar"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = trim_string(input[i]); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev input[i]; } } /** Tests trim_string(). * trim_string(), when provided with a trim character, should return * the portion of the incoming string that is before the first * occurence of that character. */ WVTEST_MAIN("trimtest2.cc") { char *input[] = {new char[9], new char[9], new char[9], new char[9]}; strcpy(input[0], "abcdefgh"); strcpy(input[1], "xbcdefgh"); strcpy(input[2], "abcdefgx"); strcpy(input[3], "abcxefgh"); const char *desired[] = {"abcdefgh", "", "abcdefg", "abc"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = trim_string(input[i], 'x'); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev input[i]; } } /** Tests non_breaking(). * non_breaking() should replace any whitespace character in the * incoming string with " ". */ WVTEST_MAIN("nbsp") { const char *input[] = {"a b c", " a", "a\nb\tc ", "ab c\r"}; const char *desired[] = {"a b c", "  a", "a b c ", "ab c "}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = non_breaking(input[i]); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev result; } } /** Tests replace_char(). * replace_char() should replace all instances of one given character * with another given character. */ WVTEST_MAIN("replace_char") { char *input[] = {new char[9], new char[9], new char[9], new char[9]}; strcpy(input[0], "rbcdefgh"); strcpy(input[1], "abrdergh"); strcpy(input[2], "abrdergr"); strcpy(input[3], "arrdefrh"); const char *desired[] = {"xbcdefgh", "abxdergh", "abxdexgx", "axxdefrh"}; const int len[] = {8, 5, 8, 5}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { replace_char((void *)input[i], 'r', 'x', len[i]); if (!WVFAIL(strcmp(input[i], desired[i]))) printf(" because [%s] != [%s]\n", input[i], desired[i]); deletev input[i]; } } /** Tests snip_string(). * snip_string() should snip a given input string A from another string * B iff A is a prefix of B. */ WVTEST_MAIN("snip") { const char *input[] = {"foomatic", "automatic", "mafootic", " foobar"}; const char *desired[] = {"matic", "automatic", "mafootic", " foobar"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = snip_string((char*)input[i], (char*)"foo"); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); } } /** Tests strlwr(). * strlwr() should convert all characters in an input string to lower case. */ WVTEST_MAIN("strlwr") { char *input[] = {new char[6], new char[6], new char[6], new char[6]}; strcpy(input[0], "AbcdE"); strcpy(input[1], "aB De"); strcpy(input[2], "a@C^e"); strcpy(input[3], "\tB\ndE"); const char *desired[] = {"abcde", "ab de", "a@c^e", "\tb\nde"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = strlwr(input[i]); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev input[i]; } WVPASS(strlwr(NULL) == NULL); } /** Tests strupr(). * strupr() should convert all characters in an input string to upper case. */ WVTEST_MAIN("strupr") { char *input[] = {new char[6], new char[6], new char[6], new char[6]}; strcpy(input[0], "aBCDe"); strcpy(input[1], "Ab dE"); strcpy(input[2], "A@c^E"); strcpy(input[3], "\tb\nDe"); const char *desired[] = {"ABCDE", "AB DE", "A@C^E", "\tB\nDE"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { char *result = strupr(input[i]); if (!WVFAIL(strcmp(result, desired[i]))) printf(" because [%s] != [%s]\n", result, desired[i]); deletev input[i]; } WVPASS(strupr(NULL) == NULL); } /** Tests is_word(). * is_word() should return whether or not all the characters in an * input string are alphanumeric (ie, the string is a 'word'). */ WVTEST_MAIN("is_word") { const char *input[] = {"q1w2e3", "q!w@e#", "Q 86", "\t\n\r52", "hy-phen"}; const bool desired[] = {true, false, false, false, false}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(is_word(input[i]) == desired[i]); } /** Tests url_decode(). * url_decode() should convert all url-encoded characters in an input * string (%xx) to their corresponding ASCII characters. */ WVTEST_MAIN("url_decode") { const char *input = "%49+%6c%69%6b%65+%70%69%7a%7a%61%21"; const char* desired = "I like pizza!"; WVPASSEQ(url_decode(input), desired); const char *c = ""; WVPASSEQ(url_decode(c), ""); WvString x; WVFAIL(url_decode(x)); } /** Tests url_encode(). * url_encode() should convert all appropriate ASCII characters to * their url-encoded equivalent. */ WVTEST_MAIN("url_encode") { const char *input = "http://www.free_email-account.com/~ponyman/mail.pl?name=\'to|\\|Y |)4|\\|Z4\'&pass=$!J83*p&folder=1N8()>?\\/", "J~0|<3R"}; const char *desired[] = {"hoopla\\!", "q\\!w2e3r\\$", "\\_\\+\\:\\\"\\<\\>\\?\\\\\\/", "J\\~0\\|\\<3R"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvString result = backslash_escape(input[i]); if (!WVPASS(result == desired[i])) printf(" because [%s] != [%s]\n", result.cstr(), desired[i]); } } /** Tests strcount(). * strcount() should return the number of occurences of a given * character in the input string. */ WVTEST_MAIN("strcount") { const char *input[] = {"abj;lewi", "lk327ga", "a87gai783a", "aaaaaaa", "ao8&ATO@a"}; int desired[] = {1, 1, 3, 7, 2}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(strcount(input[i], 'a') == desired[i]); } /** Tests encode_hostname_as_DN(). * encode_hostname_as_DN should return a DName with dc components * containing each part of the given URI (host, domain, suffix, etc.) * and a cn component containing the entire URI. */ WVTEST_MAIN("encode_hostname") { const char *input[] = {"www.service.net", "www.you-can-too.com", "happybirthday.org", "www.canada.bigco.co.uk"}; WvString desired[] = {"dc=www,dc=service,dc=net,cn=www.service.net", "dc=www,dc=you-can-too,dc=com,cn=www.you-can-too.com", "dc=happybirthday,dc=org,cn=happybirthday.org", "dc=www,dc=canada,dc=bigco,dc=co,dc=uk,cn=www.canada.bigco.co.uk"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(encode_hostname_as_DN(input[i]) == desired[i]); } /** Tests nice_hostname(). * nice_hostname() should replace underscores with hyphens, removing * duplicates, and remove any invalid (for a URI) characters, unless * they are the first character in the string, in which case they * should be replaced by 'x'. */ WVTEST_MAIN("nice_hostname") { const char *input[] = {"n-i_c-e", "@2COOL", "E\\/1|_.1", "ha--ha__ha"}; WvString desired[] = {"n-i-c-e", "x2COOL", "E1-.1", "ha-ha-ha"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(nice_hostname(input[i]) == desired[i]); } /** Tests getfilename(). * getfilename() should return the bottom-most entry in a given * filename. */ WVTEST_MAIN("getfilename") { const char *input[] = {"/tmp/file", "file.ext", "../../.file.wot", "/snick/dir/", "/snick/dira/../dirb/file"}; WvString desired[] = {"file", "file.ext", ".file.wot", "dir", "file"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(getfilename(input[i]) == desired[i]); } /** Tests getdirname(). * getdirname() should return the directory (hypothetically) containing * the bottom-most entry in a specified filename. */ WVTEST_MAIN("getdirname") { const char *input[] = {"/tmp/file", "file.ext", "../../.file.wot", "/snick/dir/", "/snick/dira/../dirb/file"}; WvString desired[] = {"/tmp", ".", "../..", "/snick", "/snick/dira/../dirb"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) WVPASS(getdirname(input[i]) == desired[i]); } /** Tests sizetoa(). * sizetoa() should return an appropriate text description of the size * of a given number of blocks with a given blocksize. */ WVTEST_MAIN("sizetoa simple") { // Check various blocksizes { long blocks = 987654321; long blocksize = 1000000; const char *desired[15] = {"987.7 TB", "98.8 TB", "9.9 TB", "987.7 GB", "98.8 GB", "9.9 GB", "987.7 MB", "98.8 MB", "9.9 MB", "987.7 kB", "98.8 kB", "9.9 kB", "987 bytes", "98 bytes", "9 bytes"}; int i = 0; while(blocksize != 1) { WVPASSEQ(sizetoa(blocks, blocksize), desired[i]); blocksize /= 10; i++; } while(blocks) { WVPASSEQ(sizetoa(blocks, blocksize), desired[i]); blocks /= 10; i++; } } // Now check rounding WVPASSEQ(sizetoa(0), "0 bytes"); WVPASSEQ(sizetoa(1), "1 bytes"); WVPASSEQ(sizetoa(42), "42 bytes"); WVPASSEQ(sizetoa(666), "666 bytes"); WVPASSEQ(sizetoa(949), "949 bytes"); WVPASSEQ(sizetoa(999), "999 bytes"); WVPASSEQ(sizetoa(1000), "1.0 kB"); WVPASSEQ(sizetoa(1049), "1.0 kB"); WVPASSEQ(sizetoa(1050), "1.1 kB"); WVPASSEQ(sizetoa(1051), "1.1 kB"); WVPASSEQ(sizetoa(1099), "1.1 kB"); WVPASSEQ(sizetoa(1999), "2.0 kB"); WVPASSEQ(sizetoa(949999), "950.0 kB"); WVPASSEQ(sizetoa(999999), "1.0 MB"); WVPASSEQ(sizetoa(1000000), "1.0 MB"); WVPASSEQ(sizetoa(1049999), "1.0 MB"); WVPASSEQ(sizetoa(1050000), "1.1 MB"); WVPASSEQ(sizetoa(1050001), "1.1 MB"); WVPASSEQ(sizetoa(1099999), "1.1 MB"); WVPASSEQ(sizetoa(1999999), "2.0 MB"); WVPASSEQ(sizetoa(949999999), "950.0 MB"); WVPASSEQ(sizetoa(999999999), "1.0 GB"); WVPASSEQ(sizetoa(1000000000), "1.0 GB"); WVPASSEQ(sizetoa(1049999999), "1.0 GB"); WVPASSEQ(sizetoa(1050000000), "1.1 GB"); WVPASSEQ(sizetoa(1050000001), "1.1 GB"); WVPASSEQ(sizetoa(1099999999), "1.1 GB"); WVPASSEQ(sizetoa(1999999999), "2.0 GB"); WVPASSEQ(sizetoa(4294967295ul), "4.3 GB"); WVPASSEQ(sizetoa(949999999999ull), "950.0 GB"); WVPASSEQ(sizetoa(999999999999ull), "1.0 TB"); WVPASSEQ(sizetoa(1000000000000ull), "1.0 TB"); WVPASSEQ(sizetoa(1049999999999ull), "1.0 TB"); WVPASSEQ(sizetoa(1050000000000ull), "1.1 TB"); WVPASSEQ(sizetoa(1050000000001ull), "1.1 TB"); WVPASSEQ(sizetoa(949999999999999ull), "950.0 TB"); WVPASSEQ(sizetoa(999999999999999ull), "1.0 PB"); WVPASSEQ(sizetoa(1000000000000000ull), "1.0 PB"); WVPASSEQ(sizetoa(1049999999999999ull), "1.0 PB"); WVPASSEQ(sizetoa(1050000000000000ull), "1.1 PB"); WVPASSEQ(sizetoa(1050000000000001ull), "1.1 PB"); WVPASSEQ(sizetoa(949999999999999999ull), "950.0 PB"); WVPASSEQ(sizetoa(999999999999999999ull), "1.0 EB"); WVPASSEQ(sizetoa(1000000000000000000ull), "1.0 EB"); WVPASSEQ(sizetoa(1049999999999999999ull), "1.0 EB"); WVPASSEQ(sizetoa(1050000000000000000ull), "1.1 EB"); WVPASSEQ(sizetoa(1050000000000000001ull), "1.1 EB"); WVPASSEQ(sizetoa(18446744073709551615ull), "18.4 EB"); WVPASSEQ(sizetoa(0, 1000), "0 bytes"); WVPASSEQ(sizetoa(1, 1000), "1.0 kB"); WVPASSEQ(sizetoa(42, 1000), "42.0 kB"); WVPASSEQ(sizetoa(666, 1000), "666.0 kB"); WVPASSEQ(sizetoa(949, 1000), "949.0 kB"); WVPASSEQ(sizetoa(999, 1000), "999.0 kB"); WVPASSEQ(sizetoa(949999999999999999ull, 1000), "950.0 EB"); WVPASSEQ(sizetoa(999999999999999999ull, 1000), "1.0 ZB"); WVPASSEQ(sizetoa(1000000000000000000ull, 1000), "1.0 ZB"); WVPASSEQ(sizetoa(1049999999999999999ull, 1000), "1.0 ZB"); WVPASSEQ(sizetoa(1050000000000000000ull, 1000), "1.1 ZB"); WVPASSEQ(sizetoa(1050000000000000001ull, 1000), "1.1 ZB"); WVPASSEQ(sizetoa(1099999999999999999ull, 1000), "1.1 ZB"); WVPASSEQ(sizetoa(1999999999999999999ull, 1000), "2.0 ZB"); WVPASSEQ(sizetoa(18446744073709551615ull, 1000), "18.4 ZB"); WVPASSEQ(sizetoa(949999999999999999ull, 1000000), "950.0 ZB"); WVPASSEQ(sizetoa(999999999999999999ull, 1000000), "1.0 YB"); WVPASSEQ(sizetoa(1000000000000000000ull, 1000000), "1.0 YB"); WVPASSEQ(sizetoa(1049999999999999999ull, 1000000), "1.0 YB"); WVPASSEQ(sizetoa(1050000000000000000ull, 1000000), "1.1 YB"); WVPASSEQ(sizetoa(1050000000000000001ull, 1000000), "1.1 YB"); WVPASSEQ(sizetoa(1099999999999999999ull, 1000000), "1.1 YB"); WVPASSEQ(sizetoa(1999999999999999999ull, 1000000), "2.0 YB"); WVPASSEQ(sizetoa(18446744073709551615ull, 1000000), "18.4 YB"); WVPASSEQ(sizetoa(949999999999999999ull, 1000000000), "950.0 YB"); WVPASSEQ(sizetoa(999999999999999999ull, 1000000000), "1000.0 YB"); WVPASSEQ(sizetoa(1000000000000000000ull, 1000000000), "1000.0 YB"); WVPASSEQ(sizetoa(1049999999999999999ull, 1000000000), "1050.0 YB"); WVPASSEQ(sizetoa(1050000000000000000ull, 1000000000), "1050.0 YB"); WVPASSEQ(sizetoa(1050000000000000001ull, 1000000000), "1050.0 YB"); WVPASSEQ(sizetoa(1099999999999999999ull, 1000000000), "1100.0 YB"); WVPASSEQ(sizetoa(1999999999999999999ull, 1000000000), "2000.0 YB"); WVPASSEQ(sizetoa(18446744073709551615ull, 1000000000), "18446.7 YB"); // Check that irregular block sizes round properly WVPASSEQ(sizetoa(73887, 1000), "73.9 MB"); WVPASSEQ(sizetoa(73887, 1999), "147.7 MB"); WVPASSEQ(sizetoa(73887, 2000), "147.8 MB"); WVPASSEQ(sizetoa(73887, 4096), "302.7 MB"); } /** Tests sizektoa(), * sizektoa() should convert an integer of kilobytes * into a string that describes how big it is, in a human-readable format. */ WVTEST_MAIN("sizektoa") { WVPASSEQ(sizektoa(0), "0 kB"); WVPASSEQ(sizektoa(1), "1 kB"); WVPASSEQ(sizektoa(42), "42 kB"); WVPASSEQ(sizektoa(666), "666 kB"); WVPASSEQ(sizektoa(949), "949 kB"); WVPASSEQ(sizektoa(999), "999 kB"); WVPASSEQ(sizektoa(1000), "1.0 MB"); WVPASSEQ(sizektoa(1049), "1.0 MB"); WVPASSEQ(sizektoa(1050), "1.1 MB"); WVPASSEQ(sizektoa(1051), "1.1 MB"); WVPASSEQ(sizektoa(1099), "1.1 MB"); WVPASSEQ(sizektoa(1999), "2.0 MB"); WVPASSEQ(sizektoa(949999), "950.0 MB"); WVPASSEQ(sizektoa(999999), "1.0 GB"); WVPASSEQ(sizektoa(1000000), "1.0 GB"); WVPASSEQ(sizektoa(1049999), "1.0 GB"); WVPASSEQ(sizektoa(1050000), "1.1 GB"); WVPASSEQ(sizektoa(1050001), "1.1 GB"); WVPASSEQ(sizektoa(1099999), "1.1 GB"); WVPASSEQ(sizektoa(1999999), "2.0 GB"); WVPASSEQ(sizektoa(949999999), "950.0 GB"); WVPASSEQ(sizektoa(999999999), "1.0 TB"); WVPASSEQ(sizektoa(1000000000), "1.0 TB"); WVPASSEQ(sizektoa(1049999999), "1.0 TB"); WVPASSEQ(sizektoa(1050000000), "1.1 TB"); WVPASSEQ(sizektoa(1050000001), "1.1 TB"); WVPASSEQ(sizektoa(1099999999), "1.1 TB"); WVPASSEQ(sizektoa(1999999999), "2.0 TB"); WVPASSEQ(sizektoa(4294967295ul), "4.3 TB"); WVPASSEQ(sizektoa(949999999999ull), "950.0 TB"); WVPASSEQ(sizektoa(999999999999ull), "1.0 PB"); WVPASSEQ(sizektoa(1000000000000ull), "1.0 PB"); WVPASSEQ(sizektoa(1049999999999ull), "1.0 PB"); WVPASSEQ(sizektoa(1050000000000ull), "1.1 PB"); WVPASSEQ(sizektoa(1050000000001ull), "1.1 PB"); WVPASSEQ(sizektoa(949999999999999ull), "950.0 PB"); WVPASSEQ(sizektoa(999999999999999ull), "1.0 EB"); WVPASSEQ(sizektoa(1000000000000000ull), "1.0 EB"); WVPASSEQ(sizektoa(1049999999999999ull), "1.0 EB"); WVPASSEQ(sizektoa(1050000000000000ull), "1.1 EB"); WVPASSEQ(sizektoa(1050000000000001ull), "1.1 EB"); WVPASSEQ(sizektoa(949999999999999999ull), "950.0 EB"); WVPASSEQ(sizektoa(999999999999999999ull), "1.0 ZB"); WVPASSEQ(sizektoa(1000000000000000000ull), "1.0 ZB"); WVPASSEQ(sizektoa(1049999999999999999ull), "1.0 ZB"); WVPASSEQ(sizektoa(1050000000000000000ull), "1.1 ZB"); WVPASSEQ(sizektoa(1050000000000000001ull), "1.1 ZB"); WVPASSEQ(sizektoa(18446744073709551615ull), "18.4 ZB"); } /** Tests sizeitoa(). * sizeitoa() should return an appropriate text description of the size * of a given number of blocks with a given blocksize. */ WVTEST_MAIN("sizeitoa") { // Now check rounding WVPASSEQ(sizeitoa(0), "0 bytes"); WVPASSEQ(sizeitoa(1), "1 bytes"); WVPASSEQ(sizeitoa(42), "42 bytes"); WVPASSEQ(sizeitoa(512), "512 bytes"); WVPASSEQ(sizeitoa(666), "666 bytes"); WVPASSEQ(sizeitoa(949), "949 bytes"); WVPASSEQ(sizeitoa(999), "999 bytes"); WVPASSEQ(sizeitoa(1000), "1000 bytes"); WVPASSEQ(sizeitoa(1023), "1023 bytes"); WVPASSEQ(sizeitoa(1024), "1.0 KiB"); WVPASSEQ(sizeitoa(1025), "1.0 KiB"); WVPASSEQ(sizeitoa(1075), "1.0 KiB"); WVPASSEQ(sizeitoa(1076), "1.1 KiB"); WVPASSEQ(sizeitoa(1116), "1.1 KiB"); WVPASSEQ(sizeitoa(2047), "2.0 KiB"); WVPASSEQ(sizeitoa(2048), "2.0 KiB"); WVPASSEQ(sizeitoa(972799), "950.0 KiB"); WVPASSEQ(sizeitoa(1048575), "1.0 MiB"); WVPASSEQ(sizeitoa(1048576), "1.0 MiB"); WVPASSEQ(sizeitoa(1049999), "1.0 MiB"); WVPASSEQ(sizeitoa(4294967295ul), "4.0 GiB"); WVPASSEQ(sizeitoa(18446744073709551615ull), "16.0 EiB"); WVPASSEQ(sizeitoa(0, 1024), "0 bytes"); WVPASSEQ(sizeitoa(1, 1024), "1.0 KiB"); WVPASSEQ(sizeitoa(42, 1024), "42.0 KiB"); WVPASSEQ(sizeitoa(666, 1024), "666.0 KiB"); WVPASSEQ(sizeitoa(949, 1024), "949.0 KiB"); WVPASSEQ(sizeitoa(999, 1024), "999.0 KiB"); WVPASSEQ(sizeitoa(18446744073709551615ull, 1048576), "16.0 YiB"); WVPASSEQ(sizeitoa(18446744073709551615ull, 1073741824), "16384.0 YiB"); } /** Tests sizekitoa(), * sizekitoa() should convert an integer of kilobytes * into a string that describes how big it is, in a human-readable format. */ WVTEST_MAIN("sizekitoa") { WVPASSEQ(sizekitoa(0), "0 KiB"); WVPASSEQ(sizekitoa(1), "1 KiB"); WVPASSEQ(sizekitoa(42), "42 KiB"); WVPASSEQ(sizekitoa(512), "512 KiB"); WVPASSEQ(sizekitoa(666), "666 KiB"); WVPASSEQ(sizekitoa(949), "949 KiB"); WVPASSEQ(sizekitoa(999), "999 KiB"); WVPASSEQ(sizekitoa(1000), "1000 KiB"); WVPASSEQ(sizekitoa(1023), "1023 KiB"); WVPASSEQ(sizekitoa(1024), "1.0 MiB"); WVPASSEQ(sizekitoa(1025), "1.0 MiB"); WVPASSEQ(sizekitoa(1075), "1.0 MiB"); WVPASSEQ(sizekitoa(1076), "1.1 MiB"); WVPASSEQ(sizekitoa(1116), "1.1 MiB"); WVPASSEQ(sizekitoa(2047), "2.0 MiB"); WVPASSEQ(sizekitoa(2048), "2.0 MiB"); WVPASSEQ(sizekitoa(972799), "950.0 MiB"); WVPASSEQ(sizekitoa(1048575), "1.0 GiB"); WVPASSEQ(sizekitoa(1048576), "1.0 GiB"); WVPASSEQ(sizekitoa(1049999), "1.0 GiB"); WVPASSEQ(sizekitoa(4294967295ul), "4.0 TiB"); WVPASSEQ(sizekitoa(18446744073709551615ull), "16.0 ZiB"); } /** Tests lookup(). * lookup() should return the index into an array of string where * the input string can be found (can be/not be a case sensitive search) * or -1 if the string is not in the array. */ WVTEST_MAIN("lookup") { const char *input[] = {"", "AbC", "a3k3 ", "abc", "ABC", NULL}; WVPASS(lookup("abc", input, true) == 3); WVPASS(lookup("abc", input, false) == 1); WVPASS(lookup("ab", input, false) == -1); WVPASS(lookup("ABC", input, true) == 4); WVPASS(lookup("abcd", input, false) == -1); } /** Compares all the elements of a WvList. * Returns true iff the elements of lhs and rhs are pairwise equivalent * via the != operator. */ template static bool listcmp(const WvList& lhs, const WvList& rhs) { if (lhs.count() != rhs.count()) return false; typename WvList::Iter l(lhs), r(rhs); for (l.rewind(), r.rewind(); l.next() && r.next(); ) { if (*l.ptr() != *r.ptr()) return false; } return true; } /** Tests strcoll_split(). * strcoll_split() should return a list of strings that have been * extracted from an input string with fields separated by an arbitrary * number of given delimiters, with blank strings in the input being * ignored. */ WVTEST_MAIN("strcoll_split") { const char *input[] = {"i:am colon\t:separated::", "i::too:am colon\tseparated"}; WvList desired[sizeof(input) / sizeof(char *)]; WvList desired_lim[sizeof(input) / sizeof(char *)]; desired[0].add(new WvString("i"), true); desired[0].add(new WvString("am"), true); desired[0].add(new WvString("colon"), true); desired[0].add(new WvString("separated"), true); desired[0].add(new WvString(""), true); desired[1].add(new WvString("i"), true); desired[1].add(new WvString("too"), true); desired[1].add(new WvString("am"), true); desired[1].add(new WvString("colon"), true); desired[1].add(new WvString("separated"), true); desired_lim[0].add(new WvString("i"), true); desired_lim[0].add(new WvString("am"), true); desired_lim[0].add(new WvString("colon\t:separated::"), true); desired_lim[1].add(new WvString("i"), true); desired_lim[1].add(new WvString("too"), true); desired_lim[1].add(new WvString("am colon\tseparated"), true); for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvList result; strcoll_split(result, input[i], " \t:"); WVPASS(listcmp(result, desired[i])); } for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvList result; strcoll_split(result, input[i], " \t:", 3); WVPASS(listcmp(result, desired_lim[i])); } } /** Tests strcoll_splitstrict(). * strcoll_splitstrict() should return a list of strings that have been * extracted from an input string with fields separated by an arbitrary * number of given delimiters, with blank fields in the input causing * blank strings in the output. */ WVTEST_MAIN("strcoll_splitstrict") { const char *input[] = {"i:am colon\t:separated::", "i::too:am colon\tseparated"}; WvList desired[sizeof(input) / sizeof(char *)]; WvList desired_lim[sizeof(input) / sizeof(char *)]; desired[0].add(new WvString("i"), true); desired[0].add(new WvString("am"), true); desired[0].add(new WvString("colon"), true); desired[0].add(new WvString(""), true); desired[0].add(new WvString("separated"), true); desired[0].add(new WvString(""), true); desired[0].add(new WvString(""), true); desired[1].add(new WvString("i"), true); desired[1].add(new WvString(""), true); desired[1].add(new WvString("too"), true); desired[1].add(new WvString("am"), true); desired[1].add(new WvString("colon"), true); desired[1].add(new WvString("separated"), true); desired_lim[0].add(new WvString("i"), true); desired_lim[0].add(new WvString("am"), true); desired_lim[0].add(new WvString("colon\t:separated::"), true); desired_lim[1].add(new WvString("i"), true); desired_lim[1].add(new WvString(""), true); desired_lim[1].add(new WvString("too:am colon\tseparated"), true); for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvList result; strcoll_splitstrict(result, input[i], " \t:"); WVPASS(listcmp(result, desired[i])); } for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvList result; strcoll_splitstrict(result, input[i], " \t:", 3); WVPASS(listcmp(result, desired_lim[i])); } } /** Tests strcoll_join(). * strcoll_join() should return a string formed by extracting all * elements from a list and concatenating them, separated by a given * string. */ WVTEST_MAIN("strcoll_join") { WvList input[1]; const char *desired[] = {"pop the top and diediedie"}; const char *desired_join[] = {"pop Xthe top and XdieXdieXdieX"}; input[0].add(new WvString("pop "), true); input[0].add(new WvString("the top and "), true); input[0].add(new WvString("die"), true); input[0].add(new WvString("die"), true); input[0].add(new WvString("die"), true); input[0].add(new WvString(""), true); for (unsigned int i = 0; i < sizeof(input) / sizeof(WvList); ++i) WVPASS(strcoll_join(input[i], "") == desired[i]); for (unsigned int i = 0; i < sizeof(input) / sizeof(WvList); ++i) WVPASS(strcoll_join(input[i], "X") == desired_join[i]); } /** Tests strreplace(). * strreplace() should replace all instances of a given string A in the * input string with a given string B. */ WVTEST_MAIN("replace") { { const char *input[2] = {"abbababababbba", "abbababababbbablab"}; const char *desired[2] = {"abxaxxaxxaxxaxbbxax", "abxaxxaxxaxxaxbbxaxblab"}; for (int i = 0; i < 2; i++) { WvString result = strreplace(input[i], "ba", "xax"); WVPASSEQ(result, desired[i]); } } } /** Tests undupe(). * undupe() should remove all consecutive instances of a given char in * the input string, replacing them with a single instance. */ WVTEST_MAIN("undupe") { const char *input[] = {";alwg8", "aaog8", "absb rd \raaaa", "aa8eai\na8\tawaa"}; const char *desired[] = {";alwg8", "aog8", "absb rd \ra", "a8eai\na8\tawa"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvString result = undupe(input[i], 'a'); if (!WVPASS(result == desired[i])) printf(" because [%s] != [%s]\n", result.cstr(), desired[i]); } } /** Tests hostname(). * hostname() should return the hostname of the local computer. */ WVTEST_MAIN("hostname") { char host[1024]; printf("running gethostname...\n"); fflush(stdout); gethostname(host, sizeof(host)); printf("got it.\n"); fflush(stdout); WVPASSEQ(hostname(), host); } /** Tests fqdomainname(). * fqdomainname() should return the fully-qualified domain name of the * local computer. Of course, it's hard to tell if this worked or not. At * least we should be able to trust the hostname, although the domainname * probably isn't right. */ WVTEST_MAIN("fqdomainname") { #if THIS_WERENT_TOTAL_CRAP char host[1024], *cptr; WvString n(fqdomainname()); if(!!n) { cptr = strchr(n.edit(), '.'); WVPASS(cptr); // FQDN must have a domain name part :) if (cptr) { WVPASS(strchr(cptr+1, '.')); // domain names have more than one part *cptr = 0; // now trim off the domain name part } gethostname(host, sizeof(host)); printf("host='%s' fqdomainname().host='%s'\n", host, n.cstr()); WVPASSEQ(n, host); } else printf("Work around for Segfault"); #endif } /** Tests metriculate(). * metriculate() should convert an input number to a string using * metric spacing conventions (ie. a space every three digits, going * from right to left). */ WVTEST_MAIN("metriculate") { int input[] = {293, 218976, 1896234178, 12837, -28376, -24, -2873, -182736}; const char *desired[] = {"293", "218 976", "1 896 234 178", "12 837", "-28 376", "-24", "-2 873", "-182 736"}; for (unsigned int i = 0; i < sizeof(input) / sizeof(char *); ++i) { WvString result = metriculate(input[i]); if (!WVPASS(result == desired[i])) printf(" because [%s] != [%s]\n", result.cstr(), desired[i]); } } WVTEST_MAIN("afterstr") { WvString big = "foobarman"; WVPASS(afterstr(big, "foo") == "barman"); WVPASS(afterstr(big, "o") == "obarman"); WVPASS(afterstr(big, "man") == ""); WVPASS(afterstr(big, "smarch") == ""); } WVTEST_MAIN("beforestr") { WvString big = "foobarman"; WVPASS(beforestr(big, "foo") == ""); WVPASS(beforestr(big, "o") == "f"); WVPASS(beforestr(big, "man") == "foobar"); WVPASS(beforestr(big, "smarch") == big); } WVTEST_MAIN("substr") { WvString big = "foobarman"; WVPASS(substr(big, 0, 9) == big); WVPASS(substr(big, 0, 10) == big); WVPASS(substr(big, 0, 6) == "foobar"); WVPASS(substr(big, 5, 0) == ""); WVPASS(substr(big, 10, 1) == ""); } WVTEST_MAIN("cstr_escape") { WVPASS(cstr_escape(NULL, 0).isnull()); WVPASS(cstr_escape("", 0) == "\"\""); WVPASS(cstr_escape("\"", 1) == "\"\\\"\""); WVPASS(cstr_escape("\\", 1) == "\"\\\\\""); WVPASS(cstr_escape("\a", 1) == "\"\\a\""); WVPASS(cstr_escape("\b", 1) == "\"\\b\""); WVPASS(cstr_escape("\r", 1) == "\"\\r\""); WVPASS(cstr_escape("\t", 1) == "\"\\t\""); WVPASS(cstr_escape("\n", 1) == "\"\\n\""); WVPASS(cstr_escape("\v", 1) == "\"\\v\""); WVPASS(cstr_escape("\0", 1) == "\"\\0\""); WVPASS(cstr_escape("a", 1) == "\"a\""); WVPASS(cstr_escape("\xFF", 1) == "\"\\xFF\""); } WVTEST_MAIN("cstr_escape_unescape") { int i; const size_t max_size = 256; char orig_data[max_size], data[max_size]; size_t size; for (i=0; i<256; ++i) orig_data[i] = (char)i; // Regular escapes WVPASS(cstr_unescape(cstr_escape(orig_data, max_size), data, max_size, size) && size == max_size && memcmp(orig_data, data, size) == 0); // With TCL escapes WVPASS(cstr_unescape(cstr_escape(orig_data, max_size, CSTR_TCLSTR_ESCAPES), data, max_size, size, CSTR_TCLSTR_ESCAPES) && size == max_size && memcmp(orig_data, data, size) == 0); } WVTEST_MAIN("cstr_unescape") { const size_t max_size = 16; char data[max_size]; size_t size; // Tests for detection of misformatting WVFAIL(cstr_unescape(WvString::null, data, max_size, size) || size); WVPASS(cstr_unescape("", data, max_size, size) && size == 0); WVFAIL(cstr_unescape("garbage", data, max_size, size) || size); WVFAIL(cstr_unescape("\"", data, max_size, size) || size); WVPASS(cstr_unescape(" \"\" ", data, max_size, size) && size == 0); WVPASS(cstr_unescape("\"\" ", data, max_size, size) && size == 0); WVFAIL(cstr_unescape("\"\" \"", data, max_size, size) || size); // Tests for correcly formatted strings with enough space WVPASS(cstr_unescape("\"\"", data, max_size, size) && size == 0); WVPASS(cstr_unescape("\"four\"", data, max_size, size) && size == 4 && memcmp(data, "four", size) == 0); WVPASS(cstr_unescape("\"sixteencharacter\"", data, max_size, size) && size == 16 && memcmp(data, "sixteencharacter", size) == 0); // Test for correctly formatted string without enough space WVPASS(!cstr_unescape("\"nsixteencharacter\"", data, max_size, size) && size == 17 && memcmp(data, "nsixteencharacter", max_size) == 0); // Test for passing data as a NULL WVPASS(cstr_unescape("\"four\"", NULL, max_size, size) && size == 4); // Tests for concatenation WVPASS(cstr_unescape(" \r\"one\" \t\"two\"\v\n", data, max_size, size) && size == 6 && memcmp(data, "onetwo", size) == 0); } void foo(WvStringParm s) { wvcon->print("foo: s is `%s'\n", s); WvString str(s); str = trim_string(str.edit()); wvcon->print("foo: str is `%s'\n", str); } WVTEST_MAIN("WvString: circular reference") { { char cstr[] = "Hello"; WvString CStr(cstr); CStr = CStr.cstr(); wvcon->print("cstr is `%s'\n", CStr); } { WvString s("Law"); s = s.cstr(); wvcon->print("s is `%s'\n", s); } { WvString str(" abc "); str = trim_string(str.edit()); wvcon->print("str is `%s'\n", str); str.append("a"); wvcon->print("str is `%s'\n", str); str.append("lalalalala"); wvcon->print("str is `%s'\n", str); } foo("def "); foo(" "); } WVTEST_MAIN("secondstoa") { WVPASSEQ(secondstoa(0), "0 seconds"); WVPASSEQ(secondstoa(1), "1 second"); WVPASSEQ(secondstoa(2), "2 seconds"); WVPASSEQ(secondstoa(59), "59 seconds"); WVPASSEQ(secondstoa(60), "1 minute"); WVPASSEQ(secondstoa(2*60), "2 minutes"); WVPASSEQ(secondstoa(59*60+1), "59 minutes"); WVPASSEQ(secondstoa(3600), "1 hour"); WVPASSEQ(secondstoa(3600 + 60), "1 hour and 1 minute"); WVPASSEQ(secondstoa(3600 + 2*60), "1 hour and 2 minutes"); WVPASSEQ(secondstoa(2*3600), "2 hours"); WVPASSEQ(secondstoa(2*3600 + 60), "2 hours and 1 minute"); WVPASSEQ(secondstoa(2*3600 + 2*60), "2 hours and 2 minutes"); WVPASSEQ(secondstoa(23*3600 + 59*60), "23 hours and 59 minutes"); WVPASSEQ(secondstoa(23*3600 + 59*60 + 59), "23 hours and 59 minutes"); WVPASSEQ(secondstoa(24*3600), "1 day"); WVPASSEQ(secondstoa(24*3600 + 59), "1 day"); WVPASSEQ(secondstoa(24*3600 + 3600), "1 day and 1 hour"); WVPASSEQ(secondstoa(24*3600 + 3600 + 59), "1 day and 1 hour"); WVPASSEQ(secondstoa(24*3600 + 2*3600), "1 day and 2 hours"); WVPASSEQ(secondstoa(24*3600 + 3600 + 60), "1 day, 1 hour and 1 minute"); WVPASSEQ(secondstoa(24*3600 + 3600 + 2*60), "1 day, 1 hour and 2 minutes"); WVPASSEQ(secondstoa(24*3600 + 2*3600 + 60), "1 day, 2 hours and 1 minute"); WVPASSEQ(secondstoa(24*3600 + 2*3600 + 2*60), "1 day, 2 hours and 2 minutes"); WVPASSEQ(secondstoa(24*3600 + 23*3600 + 59*60 + 59), "1 day, 23 hours and 59 minutes"); WVPASSEQ(secondstoa(2*24*3600), "2 days"); WVPASSEQ(secondstoa(2*24*3600 + 3600), "2 days and 1 hour"); WVPASSEQ(secondstoa(2*24*3600 + 2*3600), "2 days and 2 hours"); WVPASSEQ(secondstoa(2*24*3600 + 3600 + 60), "2 days, 1 hour and 1 minute"); WVPASSEQ(secondstoa(2*24*3600 + 3600 + 2*60), "2 days, 1 hour and 2 minutes"); WVPASSEQ(secondstoa(2*24*3600 + 2*3600 + 60), "2 days, 2 hours and 1 minute"); WVPASSEQ(secondstoa(2*24*3600 + 2*3600 + 2*60), "2 days, 2 hours and 2 minutes"); WVPASSEQ(secondstoa(2*24*3600 + 23*3600 + 59*60 + 59), "2 days, 23 hours and 59 minutes"); WVPASSEQ(secondstoa(10*24*3600), "10 days"); } WVTEST_MAIN("spacecat") { WVPASSEQ(spacecat("xx", "yy"), "xx yy"); WVPASSEQ(spacecat("xx", "yy", ';'), "xx;yy"); WVPASSEQ(spacecat("xx;;", "yy", ';'), "xx;;;yy"); WVPASSEQ(spacecat("xx;;;", "yy", ';', true), "xx;yy"); WVPASSEQ(spacecat("xx;;;", ";yy", ';', true), "xx;yy"); WVPASSEQ(spacecat("", "yy"), " yy"); WVPASSEQ(spacecat("", "yy", ';', true), ";yy"); WVPASSEQ(spacecat("", ";;yy", ';', true), ";yy"); } WVTEST_MAIN("depunctuate") { WVPASSEQ(depunctuate(""), ""); WVPASSEQ(depunctuate("."), ""); WVPASSEQ(depunctuate("?"), ""); WVPASSEQ(depunctuate("!"), ""); WVPASSEQ(depunctuate("a"), "a"); WVPASSEQ(depunctuate("a."), "a"); WVPASSEQ(depunctuate("a?"), "a"); WVPASSEQ(depunctuate("a!"), "a"); WVPASSEQ(depunctuate("a.."), "a."); WVPASSEQ(depunctuate("a. "), "a. "); } WVTEST_MAIN("sizetoa rounding") { struct { unsigned long long value; const char *round_down; const char *round_down_at_point_five; const char *round_up_at_point_five; const char *round_up; } tests[] = { { 0, "0 bytes", "0 bytes", "0 bytes", "0 bytes" }, { 999, "999 bytes", "999 bytes", "999 bytes", "999 bytes" }, { 1000, "1.0 kB", "1.0 kB", "1.0 kB", "1.0 kB" }, { 1001, "1.0 kB", "1.0 kB", "1.0 kB", "1.1 kB" }, { 1049, "1.0 kB", "1.0 kB", "1.0 kB", "1.1 kB" }, { 1050, "1.0 kB", "1.0 kB", "1.1 kB", "1.1 kB" }, { 1051, "1.0 kB", "1.1 kB", "1.1 kB", "1.1 kB" }, { 1099, "1.0 kB", "1.1 kB", "1.1 kB", "1.1 kB" }, { 1100, "1.1 kB", "1.1 kB", "1.1 kB", "1.1 kB" }, { 9900, "9.9 kB", "9.9 kB", "9.9 kB", "9.9 kB" }, { 9901, "9.9 kB", "9.9 kB", "9.9 kB", "10.0 kB" }, { 9949, "9.9 kB", "9.9 kB", "9.9 kB", "10.0 kB" }, { 9950, "9.9 kB", "9.9 kB", "10.0 kB", "10.0 kB" }, { 9951, "9.9 kB", "10.0 kB", "10.0 kB", "10.0 kB" }, { 9999, "9.9 kB", "10.0 kB", "10.0 kB", "10.0 kB" }, { 10000, "10.0 kB", "10.0 kB", "10.0 kB", "10.0 kB" }, { 10049, "10.0 kB", "10.0 kB", "10.0 kB", "10.1 kB" }, { 10050, "10.0 kB", "10.0 kB", "10.1 kB", "10.1 kB" }, { 10051, "10.0 kB", "10.1 kB", "10.1 kB", "10.1 kB" }, { 10099, "10.0 kB", "10.1 kB", "10.1 kB", "10.1 kB" }, { 10100, "10.1 kB", "10.1 kB", "10.1 kB", "10.1 kB" }, { 100000, "100.0 kB", "100.0 kB", "100.0 kB", "100.0 kB" }, { 100049, "100.0 kB", "100.0 kB", "100.0 kB", "100.1 kB" }, { 100050, "100.0 kB", "100.0 kB", "100.1 kB", "100.1 kB" }, { 100051, "100.0 kB", "100.1 kB", "100.1 kB", "100.1 kB" }, { 100099, "100.0 kB", "100.1 kB", "100.1 kB", "100.1 kB" }, { 100100, "100.1 kB", "100.1 kB", "100.1 kB", "100.1 kB" }, { 1000000, "1.0 MB", "1.0 MB", "1.0 MB", "1.0 MB" }, { 1000049, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1000050, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1000051, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1000099, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1000100, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1049000, "1.0 MB", "1.0 MB", "1.0 MB", "1.1 MB" }, { 1050000, "1.0 MB", "1.0 MB", "1.1 MB", "1.1 MB" }, { 1051000, "1.0 MB", "1.1 MB", "1.1 MB", "1.1 MB" }, { 1099000, "1.0 MB", "1.1 MB", "1.1 MB", "1.1 MB" }, { 1100000, "1.1 MB", "1.1 MB", "1.1 MB", "1.1 MB" }, { 10000000000000000000ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.0 EB"}, { 10000000000000000049ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10000000000000000050ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10000000000000000051ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10000000000000000099ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10000000000000000100ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10049000000000000000ull, "10.0 EB", "10.0 EB", "10.0 EB", "10.1 EB"}, { 10050000000000000000ull, "10.0 EB", "10.0 EB", "10.1 EB", "10.1 EB"}, { 10051000000000000000ull, "10.0 EB", "10.1 EB", "10.1 EB", "10.1 EB"}, { 10099000000000000000ull, "10.0 EB", "10.1 EB", "10.1 EB", "10.1 EB"}, { 10100000000000000000ull, "10.1 EB", "10.1 EB", "10.1 EB", "10.1 EB"}, { 0, NULL, NULL, NULL, NULL } }; int i; for (i=0; tests[i].round_down; ++i) { wvout->print("ROUND_DOWN %s:\n", tests[i].value); WVPASSEQ(sizetoa(tests[i].value, 1, ROUND_DOWN), tests[i].round_down); wvout->print("ROUND_DOWN_AT_POINT_FIVE %s:\n", tests[i].value); WVPASSEQ(sizetoa(tests[i].value, 1, ROUND_DOWN_AT_POINT_FIVE), tests[i].round_down_at_point_five); wvout->print("ROUND_UP_AT_POINT_FIVE %s:\n", tests[i].value); WVPASSEQ(sizetoa(tests[i].value, 1, ROUND_UP_AT_POINT_FIVE), tests[i].round_up_at_point_five); wvout->print("ROUND_UP %s:\n", tests[i].value); WVPASSEQ(sizetoa(tests[i].value, 1, ROUND_UP), tests[i].round_up); } } bool checkdateformat(WvString dtstr) { char * head = dtstr.edit(); char * p = head; p += 4; if(*p == '-') *p = '0'; p += 3; if(*p == '-') *p = '0'; p = head; for(int i = 0; i < 10; i++,p++) if(!isdigit(*p)) return false; return true; } bool checktimeformat(WvString dtstr) { char * head = dtstr.edit(); char * p = head; p += 2; if(*p == ':') *p = '0'; p += 3; if(*p == ':') *p = '0'; p = head; for(int i = 0; i < 8; i++,p++) if(!isdigit(*p)) return false; return true; } bool checkdatetimeformat(WvString dtstr) { bool res = false; char * head, *p ; head = p = dtstr.edit(); p += 10; if(*p == ' ') { *p = 0; p++; WvString ds(head); WvString ts(p); if (checktimeformat(ts) && checkdateformat(ds)) res = true; } return res; } WVTEST_MAIN("intl_datetime") { // The intl_* functions express time in local time, which will // produce strings that vary depending on the tester's local time zone. // To work around this, we subtract the timezone offset from the // test timestamp; the functions will add it back in, and the result // is zero. time_t dt = 1152558117; time_t offset = intl_gmtoff(dt); dt -= offset; fprintf(stderr, "Offset: %ld secs (%ld hours)\n", (long)offset, (long)offset/3600); WVPASSEQ(intl_date(dt), "2006-07-10"); WVPASSEQ(intl_time(dt), "19:01:57"); WVPASSEQ(intl_datetime(dt), "2006-07-10 19:01:57"); WVPASS(checktimeformat(intl_time(dt))); WVPASS(checkdateformat(intl_date(dt))); WVPASS(checkdatetimeformat(intl_datetime(dt))); } wvstreams-4.6.1/utils/t/wvlinklist.t.cc0000644000175000001440000001607211036722347017167 0ustar wlachusers#include "wvtest.h" #include "wvstringlist.h" #include "wvlinklist.h" DeclareWvList(int); DeclareWvList2(numberList, int); /** * I've only tested both Declares for basic functionality, they really shouldn't * ever be inconsistent, and it'd be a pretty major bug if they were, if that's * ever a bug, write a unit test for it. */ WVTEST_MAIN("basic") { // test zap() and autofree() { // both lists should perform identically intList l1; numberList l2; bool datafreed = false; int *list[10]; for (int i = 10; i < 20; i++) list[i - 10] = new int(i); // add 20 ints to the list for (int i = 0; i < 10; i++) { l1.add(new int(i), true); l2.add(new int(i), true); } for (int i = 10; i < 20; i++) { l1.add(list[i - 10], false); l2.add(list[i - 10], false); } WVFAIL(l1.isempty()); WVFAIL(l2.isempty()); l1.zap(); l2.zap(); WVPASS(l1.isempty()); WVPASS(l2.isempty()); // test that non-autofreed were left alone for (int i = 10; i < 20; i++) { if (list[i - 10] == NULL) datafreed = true; } WVFAIL(datafreed); for (int i = 0; i < 10; i++) { delete list[i]; } } // test add(), first() and unlink_first() { // both lists should perform identically intList l1; numberList l2; bool datamatchl1 = true, datamatchl2 = true; // construct a list using add and test isempty() while at it WVPASS(l1.isempty()); WVPASS(l2.isempty()); WVPASS(l1.count() == 0); WVPASS(l2.count() == 0); for (int i = 0; i < 100; i++) { l1.add(new int(i), true); l2.add(new int(i), true); } WVPASS(l1.count() == 100); WVPASS(l2.count() == 100); WVFAIL(l1.isempty()); WVFAIL(l2.isempty()); // deconstruct the list testing first() and test isempty() again for (int i = 0; i < 100; i++) { if (*l1.first() != i) datamatchl1 = false; if (*l2.first() != i) datamatchl2 = false; l1.unlink_first(); l2.unlink_first(); } WVPASS(datamatchl1); WVPASS(datamatchl2); // should be empty again now WVPASS(l1.isempty()); WVPASS(l2.isempty()); } // test append(), last(), and unlink() { // both lists should perform identically intList l1; numberList l2; int *last1, *last2; bool datamatchl1 = true, datamatchl2 = true; // construct a list using append() (should be same as add) datamatchl1 = datamatchl2 = true; WVPASS(l1.isempty()); WVPASS(l2.isempty()); for (int i = 0; i < 100; i++) { l1.append(new int(i), true); l2.append(new int(i), true); } WVPASS(l1.count() == 100); WVPASS(l2.count() == 100); WVFAIL(l1.isempty()); WVFAIL(l2.isempty()); // deconstruct the list testing last() and test isempty() again for (int i = 99; i >= 0; i--) { last1 = l1.last(); last2 = l2.last(); if (*last1 != i) datamatchl1 = false; if (*last2 != i) datamatchl2 = false; l1.unlink(last1); l2.unlink(last2); } WVPASS(datamatchl1); WVPASS(datamatchl2); // should be empty again now WVPASS(l1.isempty()); WVPASS(l2.isempty()); } // test prepend(), last(), unlink() and isempty() { // both lists should perform identically intList l1; numberList l2; int *last1, *last2; bool datamatchl1 = true, datamatchl2 = true; // construct a list using prepend() datamatchl1 = datamatchl2 = true; WVPASS(l1.isempty()); WVPASS(l2.isempty()); for (int i = 0; i < 100; i++) { l1.prepend(new int(i), true); l2.prepend(new int(i), true); } WVPASS(l1.count() == 100); WVPASS(l2.count() == 100); WVFAIL(l1.isempty()); WVFAIL(l2.isempty()); // deconstruct the list testing last() and test isempty() again for (int i = 99; i >= 0; i--) { last1 = l1.first(); last2 = l2.first(); if (*last1 != i) datamatchl1 = false; if (*last2 != i) datamatchl2 = false; l1.unlink(last1); l2.unlink(last2); } WVPASS(datamatchl1); WVPASS(datamatchl2); // should be empty again now WVPASS(l1.isempty()); WVPASS(l2.isempty()); } // test iterator traversal { intList l1; for (int i = 0; i < 20; i++) { l1.add(new int(i), true); } intList::Iter i(l1); int curr = 0; bool iterMatches = true; for (i.rewind(); i.next(); curr++) { if (*i.ptr() != curr) iterMatches = false; } WVPASS(iterMatches); } // test deleting while iterating { intList l1; for (int i = 0; i < 20; i++) { l1.add(new int(i), true); } intList::Iter i(l1); for (i.rewind(); i.next(); ) { i.xunlink(); } } } WVTEST_MAIN("listtest.cc") { WvString x("foo"), y("blue"), z("true"), bob("Foo: bar: baz: bob"); WvStringList l; WvStringList::Iter i(l); l.append(&x, false); l.append(&y, false); l.append(&z, false); const char *out1[3] = {"foo", "blue", "true"}; int j = 0; for (i.rewind(); i.next(); j++) if (!WVPASS(i() == out1[j])) printf(" because [%s] != [%s]\n", i().cstr(), out1[j]); const char *out2[4] = {"Foo", "bar", "baz", "bob"}; j = 0; l.zap(); l.split(bob, ": "); for (i.rewind(); i.next(); j++) if (!WVPASS(i() == out2[j])) printf(" because [%s] != [%s]\n", i().cstr(), out2[j]); const char *out3[2] = {"Foo", "bar: baz: bob"}; j = 0; l.zap(); l.split(bob, ": ", 2); for (i.rewind(); i.next(); j++) if (!WVPASS(i() == out3[j])) printf(" because [%s] != [%s]\n", i().cstr(), out3[j]); const char *out4[3] = {"Foo", "bar", "baz: bob"}; j = 0; l.zap(); l.split(bob, ": ", 3); for (i.rewind(); i.next(); j++) if (!WVPASS(i() == out4[j])) printf(" because [%s] != [%s]\n", i().cstr(), out4[j]); int a=5, b=6; int out5[2] = {6, 5}; intList il; intList::Iter ii(il); il.prepend(&a, false); il.prepend(&b, false); ii.rewind(); j = 0; while (ii.next()) { if (!WVPASS(ii() == out5[j])) printf(" because [%d] != [%d]\n", ii(), out5[j]); j++; } } wvstreams-4.6.1/utils/t/wvstring.t.cc0000644000175000001440000001435711077364544016656 0ustar wlachusers#include "wvtest.h" #include "wvstring.h" WVTEST_MAIN("basic") { WvString a, b, c(""), d(""), e("hello"), f("Hello"), g(0), h(1), i(1.0); // null WVFAIL(a); WVPASS(a == NULL); WVFAIL(a == ""); WVPASS(a.isnull()); WVPASSEQ(a.ifnull("x"), "x"); WVPASS(!a); WVFAIL(!!a); WVFAIL(a != NULL); WVPASS(a == b); WVFAIL(a != b); WVPASS(a.len() == 0); // blank WVPASS(c); WVPASS(c == ""); WVFAIL(c == NULL); WVFAIL(c.isnull()); WVPASSEQ(c.ifnull("x"), ""); WVPASS(!c); WVFAIL(!!c); WVPASS(c == d); WVFAIL(c != d); WVFAIL(c == a); WVPASS(c != a); // real WVPASS(e); WVPASS(e == "hello"); WVFAIL(e == "Hello"); WVFAIL(e == f); WVFAIL(e+0 == f+0); // not a wvstring, == now compares pointers! WVPASS(e+0 == e+0); WVPASS(WvString(e+1) == "ello"); WVPASS(WvString(e+1) == f+1); // numbers WVPASS(g == "0"); WVPASS(h == "1"); WVPASS(i == "1"); WVFAIL(h != i); WVPASS(i.num() == 1); WVPASS(WvString(-1).num() == -1); } WVTEST_MAIN("copying") { WvString a1, b1, c1(""), d1(""), e1("hello"), f1("Hello"), g1(0), h1(1), i1(1.0); WvString a2(a1), b2(b1), c2(c1), d2(d1), e2(e1), f2(f1), g2(g1), h2(h1), i2(i1); // if we didn't crash yet, we're halfway there! // equivalent pointers WVPASS(e1+0 == e2+0); WVPASS(e1.edit()+0 != e2+0); const char *olde1 = e1; { WvString x(e1); } // copy and destroy WVPASS(e1.edit() == olde1); // no unnecessary copies // make sure values are equivalent WVPASS(a1 == a2); WVPASS(b1 == b2); WVPASS(c1 == c2); WVPASS(d1 == d2); WVPASS(e1 == e2); WVPASS(f1 == f2); WVPASS(g1 == g2); WVPASS(h1 == h2); WVPASS(i1 == i2); WVFAIL(a2 == c2); // null/empty assignment a2 = c2; WVPASS(a2 == d1); d2 = b2; WVPASS(d2 == a1); } WVTEST_MAIN("append") { WvString a, b, c(""), d("hello"); // append a.append(b); b.append(c); c.append(d); d.append(a); WVPASS(a == NULL); WVPASS(b == ""); WVPASS(c == "hello"); WVPASS(d == "hello"); } WVTEST_MAIN("formatting") { WvString a, b, c(""), d("hello"); // basic formatter WvString x("%s%s", a, b); // undefined, but shouldn't crash WVPASS(WvString("%s%s", c, d) == "hello"); WVPASS(WvString("%s%s", d, d) == "hellohello"); // format d, then assign to d d = WvString("%s%s%s%s", d, d, d, d); WVPASS(d == "hellohellohellohello"); d = WvString(d); WVPASS(d == "hellohellohellohello"); WVPASS(d.len() == 20); WvString str("%c%c%c%c%c", 'H', 'E', 'L', 'L', 'O'); WVPASSEQ(str, "HELLO"); WvString str1("%s %s %s", "Hello", "World"); // insufficient argumenst WVPASSEQ(str1, "Hello World (nil)"); } WVTEST_MAIN("fancy formatting") { // fancy formatter tests WVPASS(WvString("%s") == "%s"); WVPASS(WvString("%%s") == "%%s"); WVPASS(WvString("%s", "x") == "x"); WVPASS(WvString("%%s", "x") == "%s"); WVPASS(WvString("%-5s", "a") == "a "); WVPASS(WvString("%5s", "a") == " a"); WVPASS(WvString("%3s", "hello") == "hello"); WVPASS(WvString("%-3s", "hello") == "hello"); WVPASS(WvString("%.3s", "hello") == "hel"); WVPASS(WvString("%-6.3s", "hello") == "hel "); WVPASS(WvString("%6.3s", "hello") == " hel"); WVPASS(WvString("%6.3s", "a") == " a"); } WVTEST_MAIN("%$ns and %$nc formatting") { WvString a("Hello"), b("World"), c("To"), d("The"); // basic formatter WvString x("%$1s %$3s %$4s %$2s.", a, b, c, d); WVPASSEQ( x, "Hello To The World."); x = WvString("%s %$3s %$4s %s.", a, b, c, d); WVPASSEQ( x, "Hello To The World."); x = WvString("%s %$3s ", a , b , c , d); x.append("%$4s %$2s%$5c", a , b , c , d, '.'); WVPASSEQ( x, "Hello To The World."); x = WvString("This %$2s be %$4s%c %$5s", ':', "must", c, "nil"); WVPASSEQ( x, "This must be nil: (nil)"); x = WvString("This also %$2s be %$4s%c %$20s", ':', "must", c, "nil"); WVPASSEQ( x, "This also must be nil: (nil)"); x = WvString("But this %$3s be %$4s%$2c %$0s", "Ok", ':', "should", "OK"); WVPASSEQ( x, "But this should be OK: Ok"); x = WvString("%$4s this %s%$3c %$-1s", "one", "Ok", ':', "Same as", c ); WVPASSEQ( x, "Same as this one: Ok"); x = WvString("\"%$2s %$1s\" is same as \"%$2s %$1s\".", b, a, d, c); WVPASSEQ( x, "\"Hello World\" is same as \"Hello World\"."); x = WvString("%c%$4c%$2c%$2c%$3c", 'H', 'l' , 'o' , 'e'); WVPASSEQ( x, "Hello"); x = WvString("%-10$1s%5$3$2s%4$4s %-7$2s.", a, b, c, d); WVPASSEQ( x, "Hello To The World ."); } WVTEST_MAIN("conversion from int") { for (int i = 0; i < 1000000; ++i) { WvString number(i); } WVPASSEQ(WvString(0), "0"); WVPASSEQ(WvString(1), "1"); WVPASSEQ(WvString(-1), "-1"); WVPASSEQ(WvString(12), "12"); WVPASSEQ(WvString(32767), "32767"); WVPASSEQ(WvString(65535), "65535"); } WVTEST_MAIN("offset") { WvString emptystr(""); WVPASSEQ(emptystr.offset(0), ""); WVPASSEQ(emptystr.offset(1), ""); WVPASSEQ(emptystr.offset(1000), ""); WvString nullstr(WvString::null); WVPASSEQ(nullstr.offset(0), WvString::null); WVPASSEQ(nullstr.offset(1), WvString::null); WVPASSEQ(nullstr.offset(2), WvString::null); WvString str("foobar"); WVPASSEQ(str.offset(0), "foobar"); WVPASSEQ(str.offset(1), "oobar"); WVPASSEQ(str.offset(1).offset(2), "bar"); WVPASSEQ(str.offset(3), str.offset(1).offset(2)); WVPASSEQ(str.offset(6), ""); WVPASSEQ(str.offset(100), ""); } class WvFooString : public WvFastString { public: static unsigned get_nullbuf_links() { return nullbuf.links; } }; WVTEST_MAIN("nullbuf link counting") { const WvString &ws = "WvString"; const WvFastString &wfs = "WvString"; unsigned before = WvFooString::get_nullbuf_links(); printf("nullbuf has %u links before\n", before); { WvString a("b"); WvString b(ws); WvString c(wfs); } unsigned after = WvFooString::get_nullbuf_links(); printf("nullbuf has %u links after\n", after); // BUGZID:20626 // ensure that we don't leak references when creating WvStrings WVPASS(before == after); } wvstreams-4.6.1/utils/t/wvattrs.t.cc0000644000175000001440000000157111044160724016463 0ustar wlachusers#include "wvattrs.h" #include "wvtest.h" WVTEST_MAIN("get/set") { WvAttrs *one = new WvAttrs; WvAttrs &s = *one; WVPASSEQ(s.get("not set!"), ""); s.set("set1", "val1"); WVPASSEQ(s.get("set1"), "val1"); s.set("set2", "val2"); WVPASSEQ(s.get("set2"), "val2"); s.set("set3", "value3"); s.set("set2", "value2"); WVPASSEQ(s.get("set2"), "value2"); WVPASSEQ(s.get("set3"), "value3"); s.set("set1", ""); WVPASS(s.get("set1").isnull()); //WVPASSEQ(s.get("set1"), ""); s.set("", "this should not be set"); s.set("seter4", "some value"); s.set("seter5", "some other value"); s.set("setter6", "OK, last one"); WVPASSEQ(s.get("seter5"), "some other value"); WVPASS(s.get("not a real value").isnull()); //test copy constructor WvAttrs copy(s); delete one; WVPASSEQ(copy.get("seter4"), "some value"); } wvstreams-4.6.1/utils/t/wvsystem.t.cc0000644000175000001440000000334711036722347016663 0ustar wlachusers#include "wvsystem.h" #include "wvfile.h" #include "wvtest.h" WVTEST_MAIN("wvsystem") { WvString fn("test-%s.tmp", getpid()); WvString fn2("test2-%s.tmp", getpid()); WvString fn3("test3-%s.tmp", getpid()); WvString teststring("test \t string"); ::unlink(fn); WVPASS(access(fn, F_OK) != 0); WVPASSEQ(WvSystem("ls", "-l").outfile(fn).go(), 0); WVPASS(!access(fn, F_OK)); const char *argv1[] = { "ls", "-l", fn, NULL }; const char *argv2[] = { "ls", "-l", "random-nonexistent-file", NULL }; WVPASSEQ(WvSystem(argv1).go(), 0); WVPASS(WvSystem(argv2).go() != 0); // whitespace not preserved due to inadequate quoting system(WvString("echo %s >%s", teststring, fn)); WVPASSEQ(WvFile(fn, O_RDONLY).getline(-1), "test string"); // whitespace preserved because quoting not needed WvSystem("echo", teststring).outfile(fn); WVPASSEQ(WvFile(fn, O_RDONLY).getline(-1), teststring); // WvSystem doesn't run the command until it gets destroyed ::unlink(fn2); { WvSystem x("echo", teststring); x.outfile(fn2); WVFAIL(!access(fn2, F_OK)); } WVPASS(!access(fn2, F_OK)); // make sure infile, outfile, and errfile all work properly ::unlink(fn); ::unlink(fn2); ::unlink(fn3); WvSystem("echo", teststring, "x\n", teststring).outfile(fn); WvSystem("cat", "-", "stupid").infile(fn).outfile(fn2).errfile(fn3); WvString outstr("%s x\n %s\n", teststring, teststring); WVPASSEQ(WvFile(fn, O_RDONLY).blocking_getline(-1, 0), outstr); WVPASSEQ(WvFile(fn2, O_RDONLY).blocking_getline(-1, 0), outstr); WVPASS(!!WvString(WvFile(fn3, O_RDONLY).blocking_getline(-1))); ::unlink(fn); ::unlink(fn2); ::unlink(fn3); } wvstreams-4.6.1/utils/t/wvencoder.t.cc0000644000175000001440000001070711036722347016754 0ustar wlachusers#include "wvencoder.h" #include "wvtest.h" // BEGIN encodertest.cc definition WVTEST_MAIN("encodertest.cc") { WvEncoderChain encoderChain; WvNullEncoder stackNull; WvPassthroughEncoder stackPass; WvNullEncoder *heapNull = new WvNullEncoder(); WvPassthroughEncoder *heapPass = new WvPassthroughEncoder(); encoderChain.append(&stackNull, false); encoderChain.prepend(&stackPass, false); encoderChain.append(heapNull, true); encoderChain.prepend(heapPass, false); { // Simple tests on empty encoders WVPASS(stackNull.isok()); WVPASS(heapPass->isok()); WVFAIL(stackPass.isfinished()); WVPASS(heapNull->geterror() == NULL); WVPASS(encoderChain.isok()); WVFAIL(encoderChain.isfinished()); encoderChain.unlink(heapPass); } { // Simple tests with finishing an encoder and simple encoding WvDynBuf inbuf; inbuf.putstr("Luke is really cool"); WvDynBuf outbuf; WVPASS(heapPass->encode(inbuf, outbuf)); WVPASS(outbuf.getstr() == "Luke is really cool"); printf("%d\n", heapPass->bytes_processed()); WVPASS(heapPass->bytes_processed() == 19); WVFAIL(heapPass->isfinished()); inbuf.putstr("Buffers work kinda weird"); WVPASS(stackNull.encode(inbuf, outbuf, false, true)); WVPASS(inbuf.getstr() == WvString("")); WVPASS(stackNull.isfinished()); WVFAIL(stackNull.encode(inbuf, outbuf)); } { /* Testing some of the built-in encoding functions for a WvEncoder * This section is for everything but buffer-buffer encoding. * Note it mostly tests functions found in WvEncoder itself, * a WvPassthroughEncoder is used only to verify results. */ WvPassthroughEncoder poorSap; size_t paramSize = 12; char testingMem[12] = {0}; char testingMem2[12] = {0}; WVPASS(poorSap.flushstrmem(WvString("Testing"), testingMem, ¶mSize)); WVPASS(!strcmp(testingMem, "Testing")); WVPASS(paramSize == 7); WvString reverse(poorSap.strflushmem(testingMem, paramSize)); WVPASS(reverse == "Testing"); WvDynBuf outbuf; WVPASS(poorSap.flushstrbuf(reverse, outbuf)); WVPASS(outbuf.getstr() == "Testing"); WvString anotherString(poorSap.strflushstr(reverse)); WVPASS(anotherString == "Testing"); outbuf.zap(); WVPASS(poorSap.flushmembuf(testingMem, 12, outbuf)); WVPASS(outbuf.getstr() == "Testing"); WVPASS(poorSap.flushmemmem(testingMem, paramSize, testingMem2, ¶mSize, true)); WVPASS(!strcmp(testingMem, "Testing")); WVPASS(!strcmp(testingMem2, "Testing")); WVFAIL(poorSap.flushmembuf(testingMem, 12, outbuf)); WVPASS(poorSap.reset()); WVPASS(poorSap.isok() && !poorSap.isfinished()); } { //individual encoder encoding tests WvNullEncoder nullie; WvPassthroughEncoder passie; WvDynBuf input; WvDynBuf output; input.putstr("Test"); WVPASS(passie.encode(input, output)); WVPASS(input.getstr() == ""); input.putstr("Another"); WVPASS(passie.encode(input, output)); WVPASS(passie.bytes_processed() == 11); input.putstr("This will die"); WVPASS(nullie.encode(input, output, true, true)); WVPASS(output.getstr() == "TestAnother"); WVPASS(input.getstr() == ""); WVPASS(nullie.reset()); WVPASS(nullie.encode(input, output, true, false)); WVFAIL(nullie.isfinished()); } { //encoder chain tests. WvDynBuf input; WvDynBuf output; input.putstr("Final test"); heapPass->reset(); WVPASS(stackPass.encode(input, output)); WVFAIL(stackNull.encode(input, output)); WVFAIL(encoderChain.encode(input, output)); WVPASS(stackPass.bytes_processed() == 10); WVPASS(heapPass->bytes_processed() == 0); input.putstr("Whatchamahuh?"); WVPASS(stackPass.encode(input, output, true, false)); WVPASS(heapNull->encode(input, output, true, false)); encoderChain.unlink(&stackNull); WVFAIL(encoderChain.isfinished()); WVPASS(encoderChain.encode(input, output, true, false)); WVPASS(encoderChain.isok()); WVPASS(encoderChain.geterror() == NULL); WvPassthroughEncoder* temp = new WvPassthroughEncoder(); encoderChain.append(temp, false); WVPASS(encoderChain.flush(input, output, true)); WVPASS(stackPass.isfinished()); WVPASS(heapNull->isfinished()); encoderChain.zap(); WVPASS(temp->isfinished()); WVPASS(encoderChain.isfinished()); input.putstr("Auf Wiedershen"); WVPASS(encoderChain.reset()); output.zap(); WVPASS(encoderChain.encode(input, output)); WVPASS(output.getstr() == "Auf Wiedershen"); delete temp; } // Valgrind will nicely pick up to make sure everything is freed here. // This element has to be deleted manually because... well; I want that. delete heapPass; } // END encodertest.cc definition wvstreams-4.6.1/utils/t/wvbufferunget.t.cc0000644000175000001440000000107711036722347017651 0ustar wlachusers#include "wvbuf.h" #include "wvstream.h" #include "wvtest.h" #include "wvfile.h" WVTEST_MAIN("unget_with_multiple_buffers") { WvDynBuf buffy; buffy.putstr("Test"); buffy.getstr(); buffy.unget(4); WvFile pass("/etc/passwd", O_RDONLY); pass.runonce(); pass.read(buffy, 1024); unsigned int s = buffy.used(); wvcon->print("Called buffy.getstr(%s)\n", s); buffy.getstr(s); wvcon->print("len:%s ungettable:%s\n", s, buffy.ungettable()); WVFAIL(s != buffy.ungettable()); // buffy.unget(s); WVPASS(1); } wvstreams-4.6.1/utils/t/wvregex.t.cc0000644000175000001440000000416311036722347016446 0ustar wlachusers#include "wvtest.h" #include "wvregex.h" #include "wvstream.h" WVTEST_MAIN("basic syntax") { WvRegex re("ab+c", WvRegex::BASIC); WVFAIL(re.match("")); WVFAIL(re.match("a")); WVFAIL(re.match("ac")); WVFAIL(re.match("abc")); WVPASS(re.match("ab+c")); WVFAIL(re.match("prefixabbcsuffix")); WVFAIL(re.match("abbc")); WVFAIL(re.match("abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc")); WVFAIL(re.match("adc")); } WVTEST_MAIN("extended syntax") { WvRegex re("ab+c", WvRegex::EXTENDED); WVFAIL(re.match("")); WVFAIL(re.match("a")); WVFAIL(re.match("ac")); WVPASS(re.match("abc")); WVPASS(re.match("prefixabbcsuffix")); WVPASS(re.match("abbc")); WVPASS(re.match("abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc")); WVFAIL(re.match("adc")); } WVTEST_MAIN("registers") { WvRegex re("(xyz)a(b*c)([0-9]*)"); WvString reg1, reg2, reg3; WVFAIL(re.match("asodfbaiosdfbn", reg1, reg2, reg3)); WVPASS(re.match("xyzabbbbc123456789", reg1, reg2, reg3)); WVPASS(reg1 == "xyz"); WVPASS(reg2 == "bbbbc"); WVPASS(reg3 == "123456789"); } WVTEST_MAIN("continuable_match") { WvRegex re("Wv(Stream|String)"); int match_start, match_end; WvString reg; WVPASS(re.continuable_match("This is WvStreams", match_start, match_end)); WVPASS(match_start == 8); WVPASS(match_end == 16); WVPASS(re.continuable_match("WvString is part of WvStreams", match_start, match_end, reg)); WVPASS(match_start == 0); WVPASS(match_end == 8); WVPASS(reg == "String"); } WVTEST_MAIN("eflags") { WvRegex re("^WvStream$"); WVPASS(re.match("WvStream")); WVFAIL(re.match("WvStream", WvRegex::NOTBOL)); WVFAIL(re.match("WvStream", WvRegex::NOTEOL)); WVFAIL(re.match("WvStream", WvRegex::NOTBOL | WvRegex::NOTEOL)); } WVTEST_MAIN("all match arguments at once") { WvRegex re("^WvStream"); int match_start, match_end; WvString reg; WVPASS(re.continuable_match("WvStream", match_start, match_end, reg)); WVFAIL(re.continuable_match("WvStream", WvRegex::NOTBOL, match_start, match_end, reg)); } wvstreams-4.6.1/utils/t/wvtask.t.cc0000644000175000001440000000770211077124114016271 0ustar wlachusers/* * FIXME: this is much less extensive than tasktest.cc... */ #include "wvtest.h" #include "wvtask.h" #include "wvtimeutils.h" // for wvdelay() // BEGIN simple definition long glob; static void gentask(void *userdata) { long startval = (long)userdata, val = startval; while (val - startval < 3) { glob = ++val; WvTaskMan::yield(); } } void testme() { WvTaskMan *taskman = WvTaskMan::get(); WVPASS(taskman); WvTask *a = taskman->start("task-a", gentask, (void *)1000); WVPASS(a); WVPASS(a->isrunning()); WvTask *b = taskman->start("task-b", gentask, (void *)2000); WVPASS(b); WVPASS(b->isrunning()); taskman->run(*a); WVPASSEQ(glob, 1001); WVPASS(a->isrunning()); WVPASS(b->isrunning()); taskman->run(*b); taskman->run(*a); WVPASSEQ(glob, 1002); WVPASS(a->isrunning()); WVPASS(b->isrunning()); taskman->run(*b); taskman->run(*b); WVPASSEQ(glob, 2003); WVPASS(a->isrunning()); WVPASS(b->isrunning()); taskman->run(*b); WVPASSEQ(glob, 2003); WVPASS(a->isrunning()); WVPASS(!b->isrunning()); taskman->run(*a); taskman->run(*a); WVPASSEQ(glob, 1003); WVPASS(!a->isrunning()); WVPASS(!b->isrunning()); a->recycle(); b->recycle(); taskman->unlink(); } // END simple definition // BEGIN tasktest.cc definition WvTask *ga, *gb; WvTaskMan *gman; void gentask2(void *userdata) { char *str = (char *)userdata; int count = 0, delay = 0; printf("Gentask starting %s\n", str); while (count < 3) { printf("%s count %d -- %p\n", str, ++count, &str); wvdelay(delay); if (count % 2) { if (gman->whoami() == ga) { if (gb) { printf("Doing gb:\n"); gman->run(*gb, 400); } } else { if (ga) { printf("Doing ga:\n"); gman->run(*ga, 400); } } } delay = gman->yield(); } printf("Gentask ending %s\n", str); } // END tasktest.cc definition WVTEST_MAIN("simple") { testme(); WVPASS("--REPEATING TEST--"); testme(); // make sure deletion/creation works } #ifdef TASKTEST_IS_CONVERTED WVTEST_MAIN("tasktest.cc") { // simple test { WvTaskMan *man = WvTaskMan::get(); gman = man; ga = man->start("atask", gentask2, (void *)"a"); gb = man->start("btask", gentask2, (void *)"b"); for (int x = 0; x < 10; x++) { printf("main1:\n"); man->run(*ga, 400); printf("main2:\n"); man->run(*gb, 400); // it's still running; can't recycle it yet! //gb->recycle(); if (!gb->isrunning()) gb = man->start("bbtask", gentask2, (void *)"bb"); if (!ga->isrunning()) ga = man->start("aatask", gentask2, (void *)"aa"); } // finish the tasks while (ga->isrunning()) man->run(*ga, 0); while (gb->isrunning()) man->run(*gb, 0); ga->recycle(); gb->recycle(); ga = NULL; gb = NULL; } // stress test { WvTaskMan *man = WvTaskMan::get(); gman = man; WvTaskList tasks; for (int x = 1; x <= 20; x++) { printf("x == %d\n", x); for (int y = 1; y <= 10; y++) { WvTask *t = man->start("stresstask", gentask2, (void *)"testy", 16384); tasks.append(t, false); } WvTaskList::Iter i(tasks); for (i.rewind(); i.next(); ) man->run(i(), 10); } while (tasks.count()) { WvTaskList::Iter i(tasks); for (i.rewind(); i.next(); ) { man->run(i(), 100); if (!i().isrunning()) { i().recycle(); i.unlink(); i.rewind(); } } } man->unlink(); } } #endif wvstreams-4.6.1/utils/t/wvdiriter.t.cc0000644000175000001440000000452111036722347016774 0ustar wlachusers#include #include #include #include #include #include #ifdef _WIN32 #include #endif static bool create_dir(WvStringParm dir, const WvStringList &entries) { ::unlink(dir); if (wvmkdir(dir, 0700)) return false; WvStringList::Iter entry(entries); for (entry.rewind(); entry.next(); ) { WvString name("%s/%s", dir, *entry); wvmkdir(getdirname(name), 0700); WvFile(name, O_CREAT | O_EXCL, 0600).print("wvtest"); } return true; } static bool destroy_dir(WvStringParm dir) { system(WvString("rm -rf %s", dir)); return true; } WVTEST_MAIN("Non-recursive WvDirIter") { WvString dir = wvtmpfilename("wvtest-wvdiriter-"); WvStringList entries; entries.split("file-one file-two .dot-file subdir/sub-file"); WVPASS(create_dir(dir, entries)); std::map found; WvDirIter di(dir, false); for (di.rewind(); di.next(); ) found[di->relname] = true; WVFAIL(found.find(".") != found.end()); WVFAIL(found.find("..") != found.end()); WVPASS(found.find("file-one") != found.end()); WVPASS(found.find("file-two") != found.end()); WVPASS(found.find(".dot-file") != found.end()); WVPASS(found.find("subdir") != found.end()); WVFAIL(found.find("subdir/.") != found.end()); WVFAIL(found.find("subdir/..") != found.end()); WVFAIL(found.find("subdir/sub-file") != found.end()); WVPASS(destroy_dir(dir)); } WVTEST_MAIN("Recursive WvDirIter") { WvString dir = wvtmpfilename("wvtest-wvdiriter-"); WvStringList entries; entries.split("file-one file-two .dot-file subdir/sub-file"); WVPASS(create_dir(dir, entries)); std::map found; WvDirIter di(dir, true); for (di.rewind(); di.next(); ) found[di->relname] = true; WVFAIL(found.find(".") != found.end()); WVFAIL(found.find("..") != found.end()); WVPASS(found.find("file-one") != found.end()); WVPASS(found.find("file-two") != found.end()); WVPASS(found.find(".dot-file") != found.end()); WVPASS(found.find("subdir") != found.end()); WVFAIL(found.find("subdir/.") != found.end()); WVFAIL(found.find("subdir/..") != found.end()); WVPASS(found.find("subdir/sub-file") != found.end()); WVPASS(destroy_dir(dir)); } wvstreams-4.6.1/utils/t/wvbuffer.t.cc0000644000175000001440000000725211036722347016607 0ustar wlachusers#include "wvtest.h" #include "wvbuf.h" #include #include //#define DEBUG_STRESS WVTEST_MAIN("InPlaceBuffer") { WvInPlaceBuf b(1024); char *s; WVPASS(b.used() == 0); WVPASS(b.free() == 1024); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.put("frogs on ice", 13); WVPASS(b.used() == 13); WVPASS(b.free() == 1011); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); s = (char *)b.get(8); WVFAIL(strcmp(s, "frogs on ice")); WVPASS(b.used() == 5); WVPASS(b.free() == 1011); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); s = (char *)b.get(5); WVFAIL(strcmp(s, " ice")); WVPASS(b.used() == 0); WVPASS(b.free() == 1011); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.zap(); WVPASS(b.used() == 0); WVPASS(b.free() == 1024); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); } WVTEST_MAIN("unpeek") { WvDynBuf buf; buf.alloc(10000); WVPASSEQ(buf.used(), 10000); buf.alloc(100000); WVPASSEQ(buf.used(), 110000); buf.get(8000); WVPASSEQ(buf.used(), 102000); buf.mutablepeek(0, 2000); WVPASSEQ(buf.used(), 102000); buf.mutablepeek(0, 102000); WVPASSEQ(buf.used(), 102000); } WVTEST_MAIN("Stress") { /* FIXME: find out how we'd know if the buffer failed the stress test, if there * are any more hints than just *not crashed* // Buffer Stress Test { WvDynBuf b; char *s, xx[1024]; size_t in, i, max, total; in = max = total = 0; while (1) { i = random() % sizeof(xx); s = (char *)b.alloc(i); memcpy(s, xx, i); #ifdef DEBUG_STRESS fprintf(stderr, "alloc(%d)\n", i); #endif in += i; total += i; size_t lastalloc = i; i = random() % sizeof(xx); if (i > lastalloc) i = lastalloc; #ifdef DEBUG_STRESS fprintf(stderr, "unalloc(%d)\n", i); #endif b.unalloc(i); in -= i; i = random() % sizeof(xx); if (i > in) i = in; #ifdef DEBUG_STRESS fprintf(stderr, "get(%d)\n", i); #endif b.get(i); in -= i; i = random() % sizeof(xx); #ifdef DEBUG_STRESS fprintf(stderr, "put(%d)\n", i); #endif b.put(xx, i); in += i; total += i; i = random() % sizeof(xx); if (i > in) i = in; #ifdef DEBUG_STRESS fprintf(stderr, "get(%d)\n", i); #endif b.get(i); in -= i; size_t lastput = i; i = random() % sizeof(xx); if (i > lastput) i = lastput; #ifdef DEBUG_STRESS fprintf(stderr, "unget(%d)\n", i); #endif b.unget(i); in += i; assert(b.used() == in); if (b.used() > max) { max = b.used(); printf("New max: %u bytes in subuffers after %u bytes\n", max, total); } #ifdef DEBUG_STRESS fprintf(stderr, "[%6d]", in); #endif } }*/ } WVTEST_MAIN("wvdynbuf big lines") { WvDynBuf buf; char cdata[4096]; int i; for (i=0; i<4096; ++i) cdata[i] = '0' + (i%10); buf.put(cdata, 4090); buf.put(cdata, 4090); WVPASS(*buf.get(101) == '0'); unsigned char *p = buf.mutablepeek(4101, 1); WVPASS(p); WVPASS(p && *p == '2'); WVPASS(*buf.get(4096) == '1'); } wvstreams-4.6.1/utils/t/wvscatterhash.t.cc0000644000175000001440000000466111036722347017650 0ustar wlachusers #include "wvtest.h" #include "wvscatterhash.h" #include "wvstring.h" DeclareWvScatterTable2(TestScatter, WvString); WVTEST_MAIN("scatterhash basics") { TestScatter h; WVPASS(h.isempty()); WVFAIL(h.count()); WvString s("foo"); h.add(new WvString(s), true); WVPASSEQ(h.count(), 1); h.remove(&s); // not the same object we added, but compares equal WVPASS(h.isempty()); } WVTEST_MAIN("scatter hashing count, add, remove") { const int size = 100; //must be larger the 50 WvString *strings[size]; for (int i=0;i 100 && !(count % (elems/20))) { printf("\rAdding %d%%", count / (elems/100)); fflush(stdout); } d.add(new Intstr(count, count), true); } add_passed = d.count() == elems; printf("\n"); WVPASS(add_passed); total = 0; for (count = 0; count < d.numslots; count++) { if (d.wvslots[count].isempty()) total++; } printf("%d of %d empty slots in the table.\n", total, d.numslots); WVPASS(100*total/d.numslots < 20); // less than 20% empty size_t avglength = elems / (d.numslots - total); size_t ideal = elems / d.numslots; printf("Avg chain length: %d (ideally %d)\n", avglength, ideal); printf("Removing...\n"); fflush(stdout); for (count = 0; count < elems; count += 5) { if (!d[count]) remove_passed = false; else d.remove(d[count]); } WVPASS(remove_passed); WVPASS(d.count() == elems - elems/5); IntstrDict::Iter i(d); total = d.count(); count = 0; for (i.rewind(); i.next(); ) { if (total > 20 && !(count % (total/20))) { printf("\rIterate %d%%", count / (total/100)); fflush(stdout); } if (!(i->s == WvString(i->i))) fast_iter_passed = false; count++; } printf("\n"); WVPASS(fast_iter_passed); for (count = 0; count < total; count++) { if (total > 100 && !(count % (total/20))) { printf("\rSlow Iterate %d%%", count / (total/100)); fflush(stdout); } if ((count%5) && !(d[count] && d[count]->s == WvString(d[count]->i))) slow_iter_passed = false; } printf("\n"); WVPASS(slow_iter_passed); } // some things are commented out here because I believe the memory // addresses are not absolute.. I'll admit I can be wrong, so modify // if you wish WVTEST_MAIN("hashtest.cc") { WvString x("foo"), y("blue"), z("true"); WvString x2("foo"), y2("blue"), z2("true"), xx("wuzzy"); WvStringTable t(10); WVPASS(t.numslots == 15); t.add(&x, false); t.add(&y, false); t.add(&z, false); WVPASS(WvHash(x) != 0); WVPASS(WvHash(y) != 0); WVPASS(WvHash(z) != 0); WVPASS(WvHash((const char *)0) == 0); if (!WVPASS(&x == t[x2])) printf(" because [%p] != [%p]\n", &x, t[x2]); if (!WVPASS(&y == t[y2])) printf(" because [%p] != [%p]\n", &y, t[y2]); if (!WVPASS(&z == t[z2])) printf(" because [%p] != [%p]\n", &z, t[z2]); WVPASS(!t[xx]); if (!WVPASS(t.count() == 3)) printf(" because [%d] != [3]\n", t.count()); t.remove(&x); t.remove(&y2); WVPASS(!t[x2]); WVPASS(!t[y2]); WVPASS(!t[xx]); if (!WVPASS(t.count() == 1)) printf(" because [%d] != [1]\n", t.count()); WvStringTable::Iter i(t); for (i.rewind(); i.next(); ) if (!WVPASS(!strcmp((const char *)i(), "true"))) printf(" because [%s] != [true]\n", (const char *)i()); Intstr a(5, "big"), b(6, "whistle"), c(7, "money"); IntstrDict2 d(10); d.add(&a, false); d.add(&b, false); d.add(&c, false); /* if (!WVPASS((unsigned)d[a.i] == 0xbffffabc)) printf(" because [%p] != [0xbffffabc]\n", d[a.i]); if (!WVPASS((unsigned)d[b.i] == 0xbffffaa8)) printf(" because [%p] != [0xbffffaa8]\n", d[b.i]); if (!WVPASS((unsigned)d[7] == 0xbffffa9c)) printf(" because [%p] != [0xbffffa9c]\n", d[7]);*/ if (!WVPASS((unsigned long)d[10] == 0x00000000)) printf(" because [%p] != [0x00000000]\n", d[10]); d.remove(&b); /* if (!WVPASS((unsigned)d[a.i] == 0xbffffabc)) printf(" because [%p] != [0xbffffabc]\n", d[a.i]);*/ /* if (!WVPASS((unsigned)d[b.i] == 0x00000000)) printf(" because [%p] != [0x00000000]\n", d[b.i]); if (!WVPASS((unsigned)d[7] == 0xbffffa9c)) printf(" because [%p] != [0xbffffa9c]\n", d[7]);*/ if (!WVPASS((unsigned long)d[10] == 0x00000000)) printf(" because [%p] != [0x00000000]\n", d[10]); } wvstreams-4.6.1/utils/t/basicfd.t.cc0000644000175000001440000000346111036722347016352 0ustar wlachusers#include "wvtest.h" #include #ifdef _WIN32 #include #include #else #include #include #include #endif #include #include /* * The main point of these tests is for win32, because we override * the close/read/write functions there. read/write get tested easily * elsewhere, but close() is harder to check. * * So the rule is: if reopening a new socket gives the same fd as last * time, you know the old one must be gone. */ static void fd0_ok() { int fd = dup(0); if (!WVPASS(fd > 0)) perror("dup(0)"); close(fd); } static void fdcycle(int base) { int fd1 = dup(base); WVPASS(fd1 >= 0); int fd2 = dup(base); WVPASS(fd2 >= 0); int fd3 = dup(base); WVPASS(fd3 >= 0); close(fd1); WVPASSEQ(dup(base), fd1); close(fd2); close(fd3); WVPASSEQ(dup(fd1), fd2); WVPASSEQ(dup(fd2), fd3); close(fd1); close(fd2); close(fd3); fd0_ok(); #if WINE_DIDNT_FAIL_THIS_TEST close(fd3); WVPASSEQ(errno, EBADF); #endif fd0_ok(); } WVTEST_MAIN("fd-plain recycling tests") { fdcycle(0); fd0_ok(); } WVTEST_MAIN("fd-socket recycling tests") { errno = 0; int sfd1 = socket(PF_INET, SOCK_STREAM, 0); WVPASS(sfd1 >= 0) || fprintf(stderr, "error was: %d\n", errno); int sfd2 = socket(PF_INET, SOCK_STREAM, 0); WVPASS(sfd2 >= 0) || fprintf(stderr, "error was: %d\n", errno); close(sfd1); #ifndef WIN32 WVPASSEQ(socket(PF_INET, SOCK_STREAM, 0), sfd1); //FIXME: Fails in VC++ #endif close(sfd2); #ifndef WIN32 WVPASSEQ(socket(PF_INET, SOCK_STREAM, 0), sfd2);//FIXME: Fails in VC++ #endif fdcycle(0); close(sfd1); close(sfd2); #if WINE_DIDNT_FAIL_THIS_TEST close(sfd2); WVPASSEQ(errno, EBADF); #endif } wvstreams-4.6.1/utils/t/strcrypt.t.cc0000644000175000001440000000262211036722347016647 0ustar wlachusers#include "wvtest.h" #include "strutils.h" #include WVTEST_MAIN("passwd_crypttest.cc") { #ifdef WIN32 srand(time(0)); #else srandom(time(0)); #endif const char *blank = ""; const char *word = "12345678"; const char *longword = "1234567890000000000000000000000000000"; WvString blank_result1 = passwd_crypt(blank); WvString blank_result2 = passwd_crypt(blank); WvString word_result = passwd_crypt(word); WvString longword_result = passwd_crypt(longword); WVPASS(!!blank_result1 && blank_result1 != "*"); WVPASS(!!blank_result2 && blank_result2 != "*"); WVFAIL(blank_result1 == blank_result2); WVPASS(!!word_result && word_result != "*"); WVPASS(!!longword_result && longword_result != "*"); } WVTEST_MAIN("passwd_md5test.cc") { srandom(time(0)); const char *blank = ""; const char *word = "12345678"; const char *longword = "1234567890000000000000000000000000000"; WvString blank_result1 = passwd_md5(blank); WvString blank_result2 = passwd_md5(blank); WvString word_result = passwd_md5(word); WvString longword_result = passwd_md5(longword); WVPASS(!!blank_result1 && blank_result1 != "*"); WVPASS(!!blank_result2 && blank_result2 != "*"); WVFAIL(blank_result1 == blank_result2); WVPASS(!!word_result && word_result != "*"); WVPASS(!!longword_result && longword_result != "*"); } wvstreams-4.6.1/utils/t/wvwordwrap.t.cc0000644000175000001440000000217711036722347017204 0ustar wlachusers#include "wvtest.h" #include "wvwordwrap.h" #include "wvstream.h" #include "wvbufstream.h" #include "wvencoderstream.h" #define WRAP_NUM_INPUT 6 WVTEST_MAIN("wordwraptest.cc") { int maxwidth = 4; WvEncoder *enc = new WvWordWrapEncoder(maxwidth); WvBufStream *ostream = new WvBufStream(); WvDynBuf outbuf; const char *input[WRAP_NUM_INPUT] = {"aaaaaa\n", "abra cadabra\n", "cabo-oose\n", "ja ba ba doo ba\n", "rabarabaraba\n", "\nboo\nboo\n"}; const char *desired[WRAP_NUM_INPUT] = {"aaaa\naa\n", "abra\ncada\nbra\n", "cabo\n-oos\ne\n", "ja\nba\nba\ndoo\nba\n", "raba\nraba\nraba\n", "\nboo\nboo\n"}; WvString result; WvEncoderStream *stream = new WvEncoderStream(ostream); stream->auto_flush(false); stream->writechain.append(enc, true); // start giving stream input and testing ostream for results for (int i = 0; i < WRAP_NUM_INPUT; i++) { stream->write(input[i], strlen(input[i])); ostream->read(outbuf, 1024); result = outbuf.getstr(); WVPASSEQ(result, desired[i]); } stream->flush(0); WVRELEASE(stream); } wvstreams-4.6.1/utils/t/wvargs.t.cc0000644000175000001440000000663311057766345016305 0ustar wlachusers #include "wvautoconf.h" #include "wvtest.h" #include "wvargs.h" WVTEST_MAIN("bools") { bool bool_val = false; WvArgs args; args.add_set_bool_option('s', "set-bool", "Set the bool", bool_val); args.add_reset_bool_option('r', "reset-bool", "Reset the bool", bool_val); args.add_flip_bool_option('f', "flip-bool", "Flip the bool", bool_val); args.set_flag(WvArgs::NO_EXIT_ON_ERRORS, true); bool_val = false; const char *av0[] = { "test" }; WVPASS(args.process(1, (char **)av0)); WVPASS(!bool_val); bool_val = false; const char *av01[] = { "test", "--bad"}; WVFAIL(args.process(2, (char **)av01)); WVPASS(!bool_val); bool_val = false; const char *av1[] = { "test", "-s" }; WVPASS(args.process(2, (char **)av1)); WVPASS(bool_val); bool_val = true; const char *av2[] = { "test", "-r" }; WVPASS(args.process(2, (char **)av2)); WVPASS(!bool_val); bool_val = false; const char *av3[] = { "test", "--set-bool" }; WVPASS(args.process(2, (char **)av3)); WVPASS(bool_val); bool_val = true; const char *av21[] = { "test", "-f" }; WVPASS(args.process(2, (char **)av21)); WVPASS(!bool_val); bool_val = false; const char *av31[] = { "test", "--flip-bool" }; WVPASS(args.process(2, (char **)av31)); WVPASS(bool_val); bool_val = true; const char *av4[] = { "test", "--reset-bool" }; WVPASS(args.process(2, (char **)av4)); WVPASS(!bool_val); bool_val = false; const char *av5[] = { "test", "-s", "--reset-bool" }; WVPASS(args.process(3, (char **)av5)); WVPASS(!bool_val); } template void numeric_test() { T val; char arg[64]; /* We lie and make the above 'const' to prevent GCC from warning us that * assigning "test" to a "char *" is deprecated */ const char *argv[] = { "test", arg }; WvArgs args; args.add_option('s', "set", "Set the value", "The value to set", val); args.set_flag(WvArgs::NO_EXIT_ON_ERRORS, true); val = 1; WVPASS(args.process(1, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "-s"); WVFAIL(args.process(2, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "-s-"); WVFAIL(args.process(2, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "-s0"); WVPASS(args.process(2, (char **)argv)); WVPASS(val == 0); val = 1; sprintf(arg, "--set"); WVFAIL(args.process(2, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "--set-"); WVFAIL(args.process(2, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "--set0"); WVFAIL(args.process(2, (char **)argv)); WVFAIL(val == 0); val = 1; sprintf(arg, "--set=0"); WVPASS(args.process(2, (char **)argv)); WVPASS(val == 0); } WVTEST_MAIN("numerics int") { numeric_test(); } WVTEST_MAIN("numerics long") { numeric_test(); } WVTEST_MAIN("numerics float") { numeric_test(); } WVTEST_MAIN("numerics double") { numeric_test(); } WVTEST_MAIN("string") { WvString sval = "default"; WvArgs args; args.add_option('c', "config", "Config file", "FILENAME", sval); args.set_flag(WvArgs::NO_EXIT_ON_ERRORS, true); const char *av0[] = { "somefile", "-c", "testfilename" }; WVPASS(args.process(3, (char **)av0)); WVPASSEQ(sval, "testfilename"); } wvstreams-4.6.1/utils/t/wvcont.t.cc0000644000175000001440000001053011036722347016272 0ustar wlachusers#include "wvtest.h" #include "wvcont.h" #include // START conttest.cc definitions static void *nonfunc(void *_x) { long x = (long)_x; return (void *)(1234560000 + x); } static void *func(void *_x) { long x = (long)_x; for (int count = 0; count < 4 && WvCont::isok(); count++) WvCont::yield((void *)++x); return (void *) -(++x); } class Honk { public: const char *id; WvContCallback cb; Honk(const char *_id) { id = _id; } void honk_at(Honk &a) { cb = WvCont(wv::bind(&Honk::honker, this, a, _1)); } private: void *honker(Honk &h, void *_x) { long x = (long)_x; // printf("%s: STARTING (%d)\n", id, x); for (x--; WvCont::isok() && x > 0; x--) { // printf("%s: --> Honking in (%d)\n", id, x); h.cb((void *)x); // printf("%s: <-- Honking out (%d)\n", id, x); } // printf("%s: DONE\n", id); return (void *)x; } }; // END conttest.cc definitions WVTEST_MAIN("basics") { typedef wv::function CbType; // basic functionality (including nested tasks) { CbType cbx = func; // not runnable itself: no yield allowed CbType cb1 = WvCont(cbx); // a subtask CbType cb2 = WvCont(cb1); // another subtask on top CbType cb3 = cb2; // a copy of the second subtask // note that in the above, there's really only one context in which // 'func' actually gets called; there are no parallel running 'func's. // cb2's task calls into cb1's task, however. WVPASS((long)cb1((void *)100) == 101); WVPASS((long)cb2((void *)200) == 102); WVPASS((long)cb3((void *)300) == 103); cb1 = WvCont(nonfunc); WVPASS((long)cb1((void *)400) == 1234560400); WVPASS((long)cb2((void *)500) == 104); WVPASS((long)cb3((void *)600) == -105); cb2 = nonfunc; WVPASS((long)cb1((void *)700) == 1234560700); WVPASS((long)cb2((void *)800) == 1234560800); WVPASS((long)cb3((void *)900) == 901); cb3 = nonfunc; WVPASS((long)cb1((void *)1000) == 1234561000); WVPASS((long)cb2((void *)1100) == 1234561100); WVPASS((long)cb3((void *)1200) == 1234561200); } #ifdef CAN_UNITTEST_ASSERTION_FAILURE // fun with recursive continuations. If this doesn't do something // predictable, we'll get screwy bugs when we use this in WvStreams - just // like we did with the pre-WvCont continue_select() implementation. // // The *desired* behaviour here is the same as with real recursive // function calls: if a calls b who calls c, and then c calls a again, // then a should do its thing, return (or yield), then c will finish, // yield, then b will finish, yield, and then a will have a chance to run // again. // // In old wvstreams, we would silently short-circuit the recursion (the // inner a would yield immediately without doing anything). This is // easy to implement, but causes problems if c actually expects a to do // something. // // Unfortunately, the semantics of this are tricky with continuations: // when we call the inner a, we re-enter its context, but that context // is waiting for b to return. It can't do anything unless b returns, // so what can we do? // // ...we assert() instead. So expect an assertion failure below. printf("Expect an assertion failure shortly!\n"); { Honk h1("honk1"), h2("honk2"), h3("honk3"); h1.honk_at(h2); h2.honk_at(h3); h3.honk_at(h1); h1.cb((void *)5); } return 0; #else //#warning "Assertion failure test not converted" #endif } static wv::function rcallback; static int rn = 0; static void *rfunc2(void *) { rn++; WVPASS(rn == 3); return 0; } static void *rfunc1(void *) { rn++; WVPASS(rn == 1); rcallback = WvCont(rfunc2); WVPASS(WvCont::isok()); // not dead until after we yield once! WVPASS(rn == 1); WvCont::yield(); WVPASS(!WvCont::isok()); rn++; WVPASS(rn == 2); return 0; } WVTEST_MAIN("self-redirection") { rcallback = WvCont(rfunc1); rcallback(0); rcallback(0); } static void *twice(void *userdata) { WVPASS(WvCont::isok()); WVPASS(userdata); userdata = WvCont::yield(); WVPASS(WvCont::isok()); WVPASS(userdata); userdata = WvCont::yield(); WVFAIL(WvCont::isok()); WVFAIL(userdata); return NULL; } WVTEST_MAIN("isok timeliness") { WvCont cont(twice); cont((void *)1); cont((void *)2); } wvstreams-4.6.1/utils/t/wvsubprocqueue.t.cc0000644000175000001440000000763511036722347020065 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for running a series or set of processes, one at a time. * See wvsubprocqueue.h. */ #include "wvsubprocqueue.h" #include "wvtest.h" #include "wvfile.h" #include struct WvSubProcQueueTester { WvString fn; WvString cmd1, cmd2, cmd2s; const char *argv1[4]; const char *argv2[4]; const char *argv2s[4]; const char *argv3[4]; int c1, c2; // cookies that we can point to - value doesn't matter WvSubProcQueueTester() : fn("test-%s.tmp", getpid()), cmd1("echo cmd1 >>%s", fn), cmd2("echo cmd2 >>%s", fn), cmd2s("sleep 1; %s", cmd2) { argv1[0] = "sh"; argv1[1] = "-c", argv1[2] = cmd1, argv1[3] = NULL; argv2[0] = "sh"; argv2[1] = "-c", argv2[2] = cmd2, argv2[3] = NULL; argv2s[0]= "sh"; argv2s[1]= "-c", argv2s[2]= cmd2s, argv2s[3]= NULL; argv3[0] = "rm"; argv3[1] = "-f", argv3[2] = fn, argv3[3] = NULL; } }; static WvString contents(WvStringParm fn) { return WvFile(fn, O_RDONLY).blocking_getline(-1, 0); } static bool exists(WvStringParm fn) { return !access(fn, F_OK); } WVTEST_MAIN("wvsubprocqueue1") { WvSubProcQueueTester t; ::unlink(t.fn); WVFAIL(exists(t.fn)); WvSubProcQueue q(1); // basic sequencing ::unlink(t.fn); q.add(NULL, t.argv1[0], t.argv1); q.add(NULL, t.argv3[0], t.argv3); q.add(NULL, t.argv2[0], t.argv2); WVPASSEQ(q.remaining(), 3); q.go(); WVPASSEQ(q.running(), 1); WVPASSEQ(q.remaining(), 3); // one running, two waiting q.finish(); WVPASSEQ(q.remaining(), 0); WVPASS(q.isempty()); WVPASS(exists(t.fn)); WVPASSEQ(contents(t.fn), "cmd2\n"); // cookie sequencing and duplicate detection ::unlink(t.fn); q.add(&t.c1, t.argv1[0], t.argv1); q.add(&t.c1, t.argv1[0], t.argv1); q.add(NULL, t.argv2[0], t.argv2); q.add(&t.c1, t.argv1[0], t.argv1); q.add(NULL, t.argv2[0], t.argv2); q.add(&t.c1, t.argv1[0], t.argv1); q.finish(); WVPASSEQ(contents(t.fn), "cmd1\ncmd2\ncmd2\ncmd1\n"); // enqueuing a cookie that is already running ::unlink(t.fn); q.add(&t.c1, t.argv1[0], t.argv1); q.go(); q.add(NULL, t.argv2[0], t.argv2); q.add(&t.c1, t.argv1[0], t.argv1); q.add(&t.c1, t.argv1[0], t.argv1); q.add(&t.c1, t.argv1[0], t.argv1); q.finish(); WVPASSEQ(contents(t.fn), "cmd1\ncmd2\ncmd1\n"); ::unlink(t.fn); } WVTEST_MAIN("wvsubprocqueue2") { WvSubProcQueueTester t; WvSubProcQueue q(2); ::unlink(t.fn); // parallelism with guaranteed ordering ::unlink(t.fn); q.add(NULL, t.argv1[0], t.argv1); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c1, t.argv2s[0], t.argv2s); q.add(&t.c1, t.argv2s[0], t.argv2s); q.add(NULL, t.argv1[0], t.argv1); q.go(); WVPASSEQ(q.running(), 2); q.finish(); WVPASSEQ(contents(t.fn), "cmd1\ncmd1\ncmd2\ncmd1\n"); // sequencing multiple cookies ::unlink(t.fn); q.add(NULL, t.argv1[0], t.argv1); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c1, t.argv2[0], t.argv2); q.go(); WVPASSEQ(q.running(), 2); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c1, t.argv2[0], t.argv2); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c2, t.argv2s[0], t.argv2s); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c1, t.argv2[0], t.argv2); q.add(NULL, t.argv1[0], t.argv1); q.add(&t.c1, t.argv2[0], t.argv2); q.finish(); WVPASSEQ(contents(t.fn), "cmd1\ncmd1\ncmd2\ncmd1\ncmd1\ncmd2\ncmd1\ncmd1\ncmd2\n"); // enqueuing cookies while running ::unlink(t.fn); q.add(&t.c1, t.argv2[0], t.argv2); q.go(); WVPASSEQ(q.running(), 1); q.add(&t.c1, t.argv2[0], t.argv2); q.add(&t.c1, t.argv2[0], t.argv2); q.finish(); WVPASSEQ(contents(t.fn), "cmd2\ncmd2\n"); ::unlink(t.fn); } wvstreams-4.6.1/utils/t/wvsorter.t.cc0000644000175000001440000000750311036722347016653 0ustar wlachusers#include "wvtest.h" #include "wvstring.h" #include "wvstringlist.h" #include "wvlinklist.h" #include "wvhashtable.h" #include "wvscatterhash.h" // BEGIN sorttest.cc definition DeclareWvTable(WvString); DeclareWvScatterTable2(WvStringTable2, WvString); int apples_to_oranges(const WvString *a, const WvString *b) { return strcmp(*a, *b); } int oranges_to_apples(const WvString *a, const WvString *b) { return -strcmp(*a, *b); } // END sorttest.cc definition WVTEST_MAIN("sorttest.cc") { free(malloc(1)); const char *frontwards[10] = {"eight", "five", "four", "nine", "one", "seven", "six", "ten", "three", "two"}; const char *backwards[10] = {"two", "three", "ten", "six", "seven", "one", "nine", "four", "five", "eight"}; // linked list sorter test { const char *unsorted[10] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}; WvStringList l; for (int i = 0; i < 10; i++) l.append(new WvString(unsorted[i]), true); //Frontwards: { WvStringList::Sorter s(l, apples_to_oranges); int i = 0; for(s.rewind(); s.next(); i++) if (!WVFAIL(strcmp((const char*) s(), frontwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), frontwards[i]); } //Unsorted: { WvStringList::Iter i(l); int j = 0; for(i.rewind(); i.next(); j++) if (!WVFAIL(strcmp((const char *) i(), unsorted[j]))) printf(" because [%s] != [%s]\n", (const char*) i(), unsorted[j]); } //Backwards: { WvStringList::Sorter s(l, oranges_to_apples); int i = 0; for(s.rewind(); s.next(); i++) if (!WVFAIL(strcmp((const char*) s(), backwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), backwards[i]); } } // sorted hash table { const char *unsorted[10] = {"one", "two", "three", "four", "seven", "eight", "five", "six", "nine", "ten"}; WvStringTable t(3); for (int i = 0; i < 10; i++) t.add(new WvString(unsorted[i]), true); //Frontwards: { WvStringTable::Sorter s(t, apples_to_oranges); int i = 0; for (s.rewind(); s.next();i++) if (!WVFAIL(strcmp((const char*) s(), frontwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), frontwards[i]); } //Backwards: { WvStringTable::Sorter s(t, oranges_to_apples); int i = 0; for (s.rewind(); s.next(); i++) if (!WVFAIL(strcmp((const char*) s(), backwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), backwards[i]); } } // sorted scatter hash table { const char *unsorted[10] = {"one", "ten", "seven", "five", "nine", "eight", "six", "three", "two", "four"}; WvStringTable2 t(3); for (int i = 0; i < 10; i++) t.add(new WvString(unsorted[i]), true); //Frontwards: { WvStringTable2::Sorter s(t, apples_to_oranges); int i = 0; for(s.rewind(); s.next();i++) if (!WVFAIL(strcmp((const char*) s(), frontwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), frontwards[i]); } //Backwards: { WvStringTable2::Sorter s(t, oranges_to_apples); int i = 0; for(s.rewind(); s.next(); i++) if (!WVFAIL(strcmp((const char*) s(), backwards[i]))) printf(" because [%s] != [%s]\n", (const char*) s(), backwards[i]); } } } wvstreams-4.6.1/utils/t/wvbackslash.t.cc0000644000175000001440000000440011036722347017261 0ustar wlachusers#include "wvtest.h" #include "wvbackslash.h" #include "wvstream.h" #include "wvbufstream.h" #include "wvfile.h" #include "wvistreamlist.h" #include "wvencoderstream.h" #define BSLASH_NUM_INPUT 5 WVTEST_MAIN("backslashtest.cc") { // Test encoding { WvEncoder *enc = new WvBackslashEncoder(); WvBufStream *ostream = new WvBufStream(); WvDynBuf outbuf; const char *input[BSLASH_NUM_INPUT] = {"encode this!\n", "baroofey\n", "\\", "\nmagoo\b", " "}; const char *desired[BSLASH_NUM_INPUT] = {"encode this!\\n", "baroofey\\n", "\\\\", "\\nmagoo\\b", " "}; WvString result; WvEncoderStream *stream = new WvEncoderStream(ostream); stream->auto_flush(true); stream->writechain.append(enc, true); // start giving stream input and testing ostream for results for (int i = 0; i < BSLASH_NUM_INPUT; i++) { stream->write(input[i], strlen(input[i])); ostream->read(outbuf, 1024); result = outbuf.getstr(); if (!WVPASS(result == desired[i])) printf(" because [%s] != [%s]\n", result.cstr(), desired[i]); } stream->flush(0); WVRELEASE(stream); } // Test decoding { WvEncoder *enc = new WvBackslashDecoder(); WvBufStream *ostream = new WvBufStream(); WvDynBuf outbuf; const char *input[BSLASH_NUM_INPUT] = {"encode this!\\n", "baroofey\\n", "\\\\", "\\nmagoo\\b", " "}; const char *desired[BSLASH_NUM_INPUT] = {"encode this!\n", "baroofey\n", "\\", "\nmagoo\b", " "}; WvString result; WvEncoderStream *stream = new WvEncoderStream(ostream); stream->auto_flush(true); stream->writechain.append(enc, true); // start giving stream input and testing ostream for results for (int i = 0; i < BSLASH_NUM_INPUT; i++) { stream->write(input[i], strlen(input[i])); ostream->read(outbuf, 1024); result = outbuf.getstr(); if (!WVPASS(result == desired[i])) printf(" because [%s] != [%s]\n", result.cstr(), desired[i]); } stream->flush(0); WVRELEASE(stream); } } wvstreams-4.6.1/utils/t/wvgzip.t.cc0000644000175000001440000001456211036722347016311 0ustar wlachusers#include "wvgzip.h" #include "wvtest.h" const int PATTERN_LENGTH = 2; const int NUM_REPEATS = 500; const size_t STRING_LENGTH = PATTERN_LENGTH * NUM_REPEATS; WVTEST_MAIN("wvgzip trivial encode + decode x1") { WvString str; for (int i=0; i 0); WvGzipEncoder unzipper(WvGzipEncoder::Inflate); unzipper.encode(zippedbuf, unzippedbuf, true, true); printf("inbuf: %i unzippedbuf: %i\n", inbuf.used(), unzippedbuf.used()); WVPASS(unzippedbuf.used() == STRING_LENGTH); WvString unzippedstr = unzippedbuf.getstr(); WVPASS(unzippedstr == str); } WVTEST_MAIN("wvgzip trivial encode + decode x2") { size_t bufsize; char buf[40000]; memset(buf, 0, 32768); WvDynBuf uncomp, comp; uncomp.put(buf, 32768); WvGzipEncoder gzencdef(WvGzipEncoder::Deflate); gzencdef.encode(uncomp, comp, true); // Make sure it read everything. WVPASSEQ(uncomp.used(), 0); // Store compressed data for later tests. bufsize = comp.used(); memcpy(buf, comp.get(bufsize), bufsize); comp.put(buf, bufsize); // Test without output limiting. Should do everything in one step. WvGzipEncoder gzencinf(WvGzipEncoder::Inflate); gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), 32768); WVPASSEQ(comp.used(), 0); uncomp.zap(); comp.put(buf, bufsize); gzencinf.reset(); // Test with an out_limit by which the buffer is evenly divisible. const int EVEN_OUT_LIMIT = 1024; gzencinf.out_limit = EVEN_OUT_LIMIT; for (int i = 1; i <= 32; i++) { gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), i*EVEN_OUT_LIMIT); WVPASS(gzencinf.isok()); } uncomp.zap(); comp.put(buf, bufsize); gzencinf.reset(); // Test with an out_limit by which the buffer isn't evenly divisible // (i.e. with a remainder). Also make it bigger than the buffer, // to be sure that we keep on decompressing (BUGZID:20720). const int UNEVEN_OUT_LIMIT = (10240+16); gzencinf.out_limit = UNEVEN_OUT_LIMIT; for (int i = 1; i <= 3; i++) { gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), i*(UNEVEN_OUT_LIMIT)); WVPASS(gzencinf.isok()); } // The remainder. gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), 32768); WVPASS(gzencinf.isok()); // Further encoding shouldn't do anything. gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), 32768); WVPASS(gzencinf.isok()); // Try with a random-content buffer. comp.zap(); uncomp.zap(); srand(time(NULL)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 32768; j++) buf[j] = rand() % 256; uncomp.put(buf, 32768); } WVPASSEQ(uncomp.used(), 65536); gzencdef.reset(); gzencdef.encode(uncomp, comp, true); // Make sure it read everything. WVPASSEQ(uncomp.used(), 0); gzencinf.reset(); gzencinf.out_limit = 20480-1; unsigned int i = 0; do { i++; gzencinf.encode(comp, uncomp, true); WVPASS(uncomp.used() <= i*(20480-1)); WVPASS(gzencinf.isok()); } while (comp.used()); WVPASSEQ(uncomp.used(), 65536); // Further encoding shouldn't do anything. gzencinf.encode(comp, uncomp, true); WVPASSEQ(uncomp.used(), 65536); WVPASS(gzencinf.isok()); } WVTEST_MAIN("compression errors") { WvDynBuf comp, uncomp; WvGzipEncoder gzipdef(WvGzipEncoder::Deflate), gzipinf(WvGzipEncoder::Inflate); gzipdef.full_flush = true; gzipinf.ignore_decompression_errors = true; char inbuf[101], outbuf[101]; srand(time(NULL)); for (int i = 0; i < 100; i++) inbuf[i] = (rand() % 10) + 0x30; inbuf[100] = '\0'; // Deflate data in two separate, fully flushed blocks. uncomp.put(inbuf, 50); gzipdef.encode(uncomp, comp, true); uncomp.put(&inbuf[50], 50); gzipdef.encode(uncomp, comp, true); WVPASS(gzipdef.isok()); // Corrupting the first two bytes will result in completely broken // data, so corrupt byte 3 to test partially recoverable data. size_t comp_used = comp.used(); memcpy(outbuf, comp.get(comp_used), comp_used); WVPASSEQ(comp.used(), 0); outbuf[2] = '!'; comp.put(outbuf, comp_used); gzipinf.encode(comp, uncomp, true, true); WVPASS(gzipinf.isok()); size_t uncomp_used = uncomp.used(); memcpy(outbuf, uncomp.get(uncomp_used), uncomp_used); outbuf[uncomp_used] = '\0'; // We should end up with just the second block completely decompressed // with no errors. WVPASSEQ(uncomp_used, 50); WVPASSEQ(memcmp(&inbuf[50], outbuf, uncomp_used), 0); } WVTEST_MAIN("severe compression errors") { WvDynBuf comp, uncomp; WvGzipEncoder gzipdef(WvGzipEncoder::Deflate), gzipinf(WvGzipEncoder::Inflate); gzipdef.full_flush = true; gzipinf.ignore_decompression_errors = true; char inbuf[32000], outbuf[32768]; srand(time(NULL)); for (int i = 0; i < 31999; i++) inbuf[i] = (rand() % 10) + 0x30; inbuf[31999] = '\0'; uncomp.put(inbuf, 32000); gzipdef.encode(uncomp, comp, true); gzipdef.finish(comp); WVPASS(gzipdef.isok()); size_t comp_used = comp.used(); wvcon->print("comp_used is %s\n", comp_used); comp.get(12); comp_used -= 12; memcpy(outbuf, comp.get(comp_used), comp_used); WVPASSEQ(comp.used(), 0); char *outbufp = outbuf; uncomp.zap(); WVPASS(gzipinf.isok()); size_t decoded = 0; do { size_t to_decode = comp_used - (outbufp - outbuf) < 1024 ? comp_used - (outbufp - outbuf) : 1024; decoded += to_decode; comp.put(outbufp, to_decode); outbufp += to_decode; wvcon->print("Decoding %s bytes.\n", to_decode); gzipinf.encode(comp, uncomp, true); } while (outbufp < outbuf + comp_used); wvcon->print("Decoded %s bytes.\n", decoded); gzipinf.finish(uncomp); if (!gzipinf.isok()) wvcon->print("GzipEncoder error: %s\n", gzipinf.geterror()); } wvstreams-4.6.1/utils/t/wvstringlist.t.cc0000644000175000001440000001023211036722347017530 0ustar wlachusers#include "wvtest.h" #include "wvstringlist.h" #ifndef _WIN32 #include "wvregex.h" #endif WVTEST_MAIN("basic") { WvString output, desired; const char * input[] = {"mahoooey", "", "kablooey", "mafooey", 0}; WvStringList l; // test fill() l.fill(input); // test popstr() for (int i = 0; i < 4; i ++) { output = l.popstr(); if (!WVPASS(output == input[i])) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); } // should return empty string for no element output = l.popstr(); WVPASS(output == ""); // populate the list for (int i = 0; i < 4; i ++) l.append(new WvString(input[i]), true); desired = WvString("%s %s %s %s", input[0], input[1], input[2], input[3]); output = l.join(); l.zap(); if (!WVPASS(output == desired)) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); // split() should ignore all spaces, so just the nonblank ones show up l.split(desired); for (int i = 0; i < 4; i ++) { if (i == 1) continue; // this one was blank, so skip it desired = WvString("%s", input[i]); output = l.popstr(); if (!WVPASS(output == desired)) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); } // splitstrict() should detect all spaces and create null entries desired = WvString("%s %s %s %s", input[0], input[1], input[2], input[3]); l.splitstrict(desired); printf("%s\n", desired.cstr()); for (int i = 0; i < 4; i ++) { desired = WvString("%s", input[i]); output = l.popstr(); if (!WVPASS(output == desired)) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); } desired = WvString(" %s %s %s %s", input[0], input[1], input[2], input[3]); l.splitstrict(desired, " "); //printf("%s\n", l.join().cstr()); desired = WvString(""); output = l.popstr(); // should be an extra space if (!WVPASS(output == desired)) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); // should be the normal input after the space for (int i = 0; i < 4; i ++) { desired = WvString("%s", input[i]); output = l.popstr(); if (!WVPASS(output == desired)) printf(" because [%s] != [%s]\n", output.cstr(), desired.cstr()); } desired = WvString(" %s %s %s %s", input[0], input[1], input[2], input[3]); l.splitstrict(desired, " "); //printf("%s\n", l.join().cstr()); desired = WvString(""); output = l.popstr(); // should be an extra space if (!WVPASS(output == desired)) printf(" because [%s] != [%s}\n", output.cstr(), desired.cstr()); for (int i = 0; i < 4; i ++) { desired = WvString("%s", input[i]); output = l.popstr(); if (!WVPASS(output == desired)) printf(" because [%s] != [%s}\n", output.cstr(), desired.cstr()); } } #ifndef _WIN32 WVTEST_MAIN("regex split") { WvRegex re1("/"), re2("/+"), re3("/*"), re4(""); WvStringList l; #define TEST_SPLIT(str, re, expected) \ do { \ const bool debug = false; \ l.zap(); \ l.split(str, re); \ WvString result = l.join("+"); \ if (debug) fprintf(stderr, "str=%s; result=%s\n", \ str, result.cstr()); \ WVPASS(result == expected); \ } while (false) TEST_SPLIT("tmp//file", re1, "tmp++file"); TEST_SPLIT("/tmp//file", re1, "+tmp++file"); TEST_SPLIT("/tmp/file", re1, "+tmp+file"); TEST_SPLIT("/tmp/file//", re1, "+tmp+file++"); TEST_SPLIT("tmp/file//", re1, "tmp+file++"); TEST_SPLIT("tmpfile", re1, "tmpfile"); TEST_SPLIT("", re1, ""); TEST_SPLIT("tmp//file", re2, "tmp+file"); TEST_SPLIT("///tmp//file", re2, "+tmp+file"); TEST_SPLIT("/////tmp/////file////", re2, "+tmp+file+"); TEST_SPLIT("tmp/file///", re2, "tmp+file+"); TEST_SPLIT("tmpfile/", re2, "tmpfile+"); TEST_SPLIT("tmpfile", re2, "tmpfile"); TEST_SPLIT("", re2, ""); TEST_SPLIT("tmpfile", re3, "tmpfile"); TEST_SPLIT("", re3, ""); TEST_SPLIT("tmpfile", re4, "tmpfile"); TEST_SPLIT("", re4, ""); } #endif wvstreams-4.6.1/utils/t/wvmatrix.t.cc0000644000175000001440000000603411036722347016637 0ustar wlachusers#ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif #include "wvtest.h" #include "wvmatrix.h" // BEGIN matrixtest.cc definition // test that creation matches intended data bool matrix_matches(WvMatrix &in, int data[]) { int k = 0; bool matches = true; for (int i = 0; i < in.m; i++) { for (int j = 0; j < in.n; j++) { if (!WVPASS(in(i, j) == data[k])) { printf(" because [%d] != [%d]\n", in(i, j), data[k]); matches = false; } k++; } } return matches; } // returns true iff in1 + in2 equals out // in1, in2 and out *must* have appropriately matching dimensions bool matrix_sum(WvMatrix &in1, WvMatrix &in2, WvMatrix &out) { bool matches = true; for (int i = 0; i < in1.m; i++) { for (int j = 0; j < in1.n; j++) { if (!WVPASS(out(i, j) == in1(i, j) + in2(i, j))) { printf(" because [%d] != [%d]\n", out(i, j), in1(i, j) + in2(i, j)); matches = false; } } } return matches; } // returns true iff in1 * in2 equals out // in1, in2 and out *must* have appropriately matching dimensions bool matrix_product(WvMatrix &in1, WvMatrix &in2, WvMatrix &out) { int c, n = 0; int *result = (int *) alloca(in1.m * in2.n * sizeof(int)); bool matches = true; // calculate our own results for (int i = 0; i < in1.m; i++) { for (int j = 0; j < in2.n; j++) { c = 0; for (int k = 0; k < in1.n; k++) c += in1(i, k) * in2(k, j); result[n] = c; n++; } } n = 0; for (int i = 0; i < out.m; i++) { for (int j = 0; j < out.n; j++) { if (!WVPASS(out(i, j) == result[n])) { printf(" because [%d] != [%d]\n", out(i, j), result[n]); matches = false; } n++; } } return matches; } // END matrixtest.cc definition WVTEST_MAIN("matrixtest.cc") { // test sum { int dataa[] = {2, 4, -6, 7, 1, 3, 2, 1, -4, 3, -5, 5}; int datab[] = {0, 1, 6, -2, 2, 3, 4, 3, -2, 1, 4, 4}; WvMatrix a(3, 4, dataa); matrix_matches(a, dataa); WvMatrix b(3, 4, datab); matrix_matches(b, datab); WvMatrix c = a + b; matrix_sum(a, b, c); } // test product { int datad[] = {2, 0, -3, 4, 1, 5}; int datae[] = {7, -1, 4, 7, 2, 5, 0, -4, -3, 1, 2, 3}; WvMatrix d(2, 3, datad); matrix_matches(d, datad); WvMatrix e(3, 4, datae); matrix_matches(e, datae); WvMatrix f = d * e; matrix_product(d, e, f); } } wvstreams-4.6.1/utils/t/wvbase64.t.cc0000644000175000001440000003607711036722347016431 0ustar wlachusers#include #include "wvtest.h" #include "wvbuf.h" #include "wvbase64.h" #include "wvstream.h" #define THREE_LETTERS "ken" #define THREE_LETTERS_ENC "a2Vu" #define FOUR_LETTERS "kenk" #define FOUR_LETTERS_ENC "a2Vuaw==" #define FIVE_LETTERS "kenke" #define FIVE_LETTERS_ENC "a2Vua2U=" #define SIX_LETTERS "kenken" #define SIX_LETTERS_ENC "a2Vua2Vu" #define FOURTEEN_LETTERS "aaaaaa:bbbbbbb" #define FOURTEEN_LETTERS_ENC "YWFhYWFhOmJiYmJiYmI=" #define BASE64_ALPHABET_DEC {0, 16, 131, 16, 81, 135, 32, 146, 139, 48, 211, 143, 65, 20, 147, 81, 85, 151, 97, 150, 155, 113, 215, 159, 130, 24, 163, 146, 89, 167, 162, 154, 171, 178, 219, 175, 195, 28, 179, 211, 93, 183, 227, 158, 187, 243, 223, 191}; #define BASE64_ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "abcdefghijklmnopqrstuvwxyz" \ "0123456789+/" #define BASE64_ALPHABET_ENC "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==" WVTEST_MAIN("basic encoding") { // always use a brand new encoder since we don't want to have to // deal with 'finish' issues in this WVTEST_MAIN block { // 3 characters... no padding on end WvBase64Encoder enc; WvString result = enc.strflushstr(THREE_LETTERS, true); WVPASS(result == THREE_LETTERS_ENC); } { // 4 characters... should have two pad characters WvBase64Encoder enc; WvString result = enc.strflushstr(FOUR_LETTERS, true); WVPASS(result == FOUR_LETTERS_ENC); WVFAIL(result == "a2Vuaw="); // forgot pad WVFAIL(result == "a2Vuaw"); // forgot pad WVFAIL(result == "a2Vua"); // output if flushing didn't occur WVFAIL(result == "a2Vu"); // not reading enough input } { // 5 characters... should have one pad character WvBase64Encoder enc; WvString result = enc.strflushstr(FIVE_LETTERS, true); WVPASS(result == FIVE_LETTERS_ENC); WVFAIL(result == "a2Vua2U"); // forgot pad WVFAIL(result == "a2Vua"); // output if flushing didn't occur WVFAIL(result == "a2Vu"); // not reading enough input } { // 6 characters WvBase64Encoder enc; WvString result = enc.strflushstr(SIX_LETTERS, true); WVPASS(result == SIX_LETTERS_ENC); } { // 14 characters WvBase64Encoder enc; WvString result = enc.strflushstr(FOURTEEN_LETTERS, true); WVPASS(result == FOURTEEN_LETTERS_ENC); } { // many characters long... no newlines should be put in after 76 // characters (see RFC2045) since this encoder is not MIME-specific WvBase64Encoder enc; WvString result = enc.strflushstr(BASE64_ALPHABET, true); WVPASS(result == BASE64_ALPHABET_ENC); } { // very special test that makes sure encoded output uses all possible // characters WvBase64Encoder enc; const unsigned char a[] = BASE64_ALPHABET_DEC; WvString result = enc.strflushmem(a, sizeof(a), true); WVPASS(result == BASE64_ALPHABET); } } WVTEST_MAIN("basic decoding") { // same tests as above, but now doing the reverse operation { // 3 characters... no padding on end WvBase64Decoder dec; WvString result = dec.strflushstr(THREE_LETTERS_ENC, true); WVPASS(result == THREE_LETTERS); } { // 4 characters... should have two pad characters WvBase64Decoder dec; WvString result = dec.strflushstr(FOUR_LETTERS_ENC, true); WVPASS(result == FOUR_LETTERS); } { // 5 characters... should have one pad character WvBase64Decoder dec; WvString result = dec.strflushstr(FIVE_LETTERS_ENC, true); WVPASS(result == FIVE_LETTERS); } { // 6 characters WvBase64Decoder dec; WvString result = dec.strflushstr(SIX_LETTERS_ENC, true); WVPASS(result == SIX_LETTERS); } { // many characters long... WvBase64Decoder dec; WvString result = dec.strflushstr(BASE64_ALPHABET_ENC, true); WVPASS(result == BASE64_ALPHABET); } { // special case... WvBase64Decoder dec; WvDynBuf dest; dec.flushstrbuf( BASE64_ALPHABET, dest, true ); const unsigned char a[] = BASE64_ALPHABET_DEC; WVPASS(dest.used() == sizeof( a ) && !memcmp( a, dest.get(dest.used()), sizeof(a)) ); } } WVTEST_MAIN("encode/decode feedback loop") { // Base64 is totally reversible... this test encodes a string // in a feedback loop n times, then decodes it n times. // number of times to repeatedly encode for (int n = 2; n < 9; n++ ) { WvString orig("Milk and Cereal"), src, dest; src = orig; for (int i = 0; i < n; i++) { WvBase64Encoder enc; enc.flushstrstr(src, dest, true); src = dest; dest = ""; } for (int i = 0; i < n; i++) { WvBase64Decoder dec; dec.flushstrstr(src, dest, true); src = dest; dest = ""; } WVPASS( src == orig ); } } WVTEST_MAIN("nothing to encode/decode") { for (int i = 1; i <= 2; i++ ) { { // "null" WvString WvEncoder *enc = (i == 1) ? (WvEncoder *) new WvBase64Encoder : new WvBase64Decoder; WvString nul, result("stuff there"); enc->flushstrstr(nul, result, true); WVPASS(result == "stuff there"); delete(enc); } { // empty WvString WvEncoder *enc = (i == 1) ? (WvEncoder *) new WvBase64Encoder : new WvBase64Decoder; WvString empty(""), result("stuff there"); enc->flushstrstr(empty, result, true); WVPASS(result == "stuff there"); delete(enc); } { // empty WvBuf WvEncoder *enc = (i == 1) ? (WvEncoder *) new WvBase64Encoder : new WvBase64Decoder; WvDynBuf empty, dest; empty.zap(); // ... just to be sure dest.put( "stuff there", 11 ); enc->encode(empty, dest, true, true); WVPASS(dest.used() == 11 && !memcmp(dest.get(dest.used()), "stuff there", 11)); delete(enc); } } } WVTEST_MAIN("decoding whitespace") { { // white space at beginning WvBase64Decoder dec; WvString a_enc(" " FOUR_LETTERS_ENC), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // white space at end WvBase64Decoder dec; WvString a_enc(FOUR_LETTERS_ENC " \n "), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // white space in middle WvBase64Decoder dec; WvString a_enc("a 2 V\tu \t\n a w = ="), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } { // all kinds of crazy whitespace everywhere WvBase64Decoder dec; WvString a_enc("a 2\v\n V u \t a\n\n\nw =\r ="), result; dec.flushstrstr(a_enc,result,true); WVPASS(result == FOUR_LETTERS); } } WVTEST_MAIN("decoding invalid data") { { // out of range data at beginning WvBase64Decoder dec; WvDynBuf src,dest; unsigned char invalid[] = {199,200,201}; src.put(invalid, 3); src.put(FOUR_LETTERS_ENC, sizeof(FOUR_LETTERS_ENC)-1); size_t original_size = src.used(); bool ret = dec.encode(src,dest,true,false); WVFAIL(dec.isok()); // read bad data WVPASS(ret == false && dest.used() == 0); // should have removed the character from the buffer WVPASS(src.used() == original_size - 1); } { // out of range data in middle WvBase64Decoder dec; WvDynBuf src,dest; src.put("a2Vu", 4); src.put(200); // the invalid character src.put("2Vu", 3); bool ret = dec.encode(src,dest,true,false); WVFAIL(dec.isok()); // read bad data WVPASS(ret == false); // this line was causing valgrind errors, but it appears to be debugging. // wvcon->print( "%s\n", (const char*) dest.peek( 0, dest.used() )); // decoded as much as possible though... a2Vu -> ken WVPASS(dest.used() == 3 && !memcmp(dest.get(dest.used()), "ken", 3)); WVPASS(src.used() == 3); // should have removed the bad character } { // not enough equal signs.. should be two, but only one WvBase64Decoder dec; WvString src("a2Vuaw="), dest; bool ret = dec.flushstrstr(src, dest, true); WVPASS(dec.isok()); WVPASS(ret == false); WVPASS(dest == "kenk"); // should have been able to decode } { // not enough equal signs.. should be one, but none WvBase64Decoder dec; WvString src("a2Vua2U"), dest; bool ret = dec.flushstrstr(src, dest, true); WVPASS(dec.isok()); WVPASS(ret == false); WVPASS(dest == "kenke"); // should have been able to decode } } #define SHORT_MESSAGE "The quick brown fox jumps over the lazy dog." #define SHORT_MESSAGE_ENC "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=" WVTEST_MAIN("encoding data that is streamed in") { // Tests that the encoder works when not all of the data is available at // once. { // Encoder only has access to one character at a time WvBase64Encoder enc; WvDynBuf src; WvString a(SHORT_MESSAGE),result; for (unsigned int i = 0; i < a.len(); i++) { src.put(a.edit()[i]); enc.flushbufstr(src, result, false); } enc.flushbufstr(src, result, true); WVPASS(result == SHORT_MESSAGE_ENC); } { // encoder has access to three letters at a time WvBase64Encoder enc; WvDynBuf src; WvString result; src.put(THREE_LETTERS, sizeof(THREE_LETTERS) - 1); enc.flushbufstr(src, result, false); src.put(THREE_LETTERS, sizeof(THREE_LETTERS) - 1); enc.flushbufstr(src, result, true); // end of stream now WVPASS(result == SIX_LETTERS_ENC); WVFAIL(result == THREE_LETTERS_ENC); } } WVTEST_MAIN("decoding data that is streamed in") { // same tests as above, but with decoding... { // one char at a time WvBase64Decoder dec; WvDynBuf src; WvString a(SHORT_MESSAGE_ENC),result; for (unsigned int i = 0; i < a.len(); i++) { src.put(a.edit()[i]); dec.flushbufstr(src, result, false); } dec.flushbufstr(src, result, true); WVPASS(result == SHORT_MESSAGE); } { // four chars at a time WvBase64Decoder dec; WvDynBuf src; WvString result; src.put(THREE_LETTERS_ENC, sizeof(THREE_LETTERS_ENC) - 1); dec.flushbufstr(src, result, false); src.put(THREE_LETTERS_ENC, sizeof(THREE_LETTERS_ENC) - 1); dec.flushbufstr(src, result, true); // end of stream now WVPASS(result == SIX_LETTERS); WVFAIL(result == THREE_LETTERS); } } WVTEST_MAIN("flushing") { // flush is true { // Putting in 4 characters will leave 1 byte of leftover data // (base64 works in chunks of 3 bytes). So result will first be // false. Adding 2 more characters will give 6 characters total // in the input buffer (4+2). So there's no leftover data and // result will be true the second time. WvBase64Encoder enc; WvDynBuf src, dest; bool result; src.put( "kenk", 4 ); result = enc.encode(src, dest, true, false); // flush it WVFAIL(result); // should be one byte left over... WVPASS(dest.used() == 5 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua", 5)); src.put( "en", 2 ); result = enc.encode(src, dest, true, false); // flush it WVPASS(result); // now had 4+2 = 6 bytes... no leftover data WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua2Vu", 8)); } // same test, but with flush == false // flush is true { WvBase64Encoder enc; WvDynBuf src, dest; bool result; src.put( "kenk", 4 ); result = enc.encode(src, dest, false, false); // flush it WVPASS(result); // should be one byte left over... WVPASS(dest.used() == 5 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua", 5)); src.put( "en", 2 ); result = enc.encode(src, dest, false, false); // flush it WVPASS(result); // now had 4+2 = 6 bytes... no leftover data WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua2Vu", 8)); } // same test as first, but calling flush() instead // flush is true { WvBase64Encoder enc; WvDynBuf src, dest; bool result; src.put( "kenk", 4 ); result = enc.flush(src, dest, false); // flush it WVFAIL(result); // should be one byte left over... WVPASS(dest.used() == 5 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua", 5)); src.put( "en", 2 ); result = enc.flush(src, dest, false); // flush it WVPASS(result); // now had 4+2 = 6 bytes... no leftover data WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), "a2Vua2Vu", 8)); } } WVTEST_MAIN("finishing") { // Tests that calling finish() works correctly { WvBase64Encoder enc; WvString a(FOUR_LETTERS), a_enc(FOUR_LETTERS_ENC), result; enc.flushstrstr(a, result, true); WVPASS(result == a_enc); WVPASS(enc.isfinished()); WVPASS(enc.isfinished() == enc.isok()); // should be able to call twice WvString should_be_empty(""); bool b = enc.flushstrstr( a, should_be_empty, true ); // can't encode again WVPASS(b == false); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == a_enc); } // Same test as above, but explicitly call finish() { WvBase64Encoder enc; WvDynBuf src, dest; src.put(FOUR_LETTERS, sizeof(FOUR_LETTERS) - 1); enc.encode(src, dest, true, false); // don't finish yet. enc.finish(dest); // ok, NOW finish. WVPASS(dest.used() == 8 && !memcmp( dest.peek( 0, dest.used() ), FOUR_LETTERS_ENC, 8)); WVPASS(enc.isfinished()); WVPASS(enc.isfinished() == enc.isok()); // should be able to call twice // shouldn't be able to encode again dest.zap(); bool b = enc.encode( src, dest, true, true ); WVPASS(b == false); WVPASS(dest.used() == 0); } // Now we do the same two tests with Decoders { WvBase64Decoder dec; WvString a(FOUR_LETTERS_ENC), a_dec(FOUR_LETTERS), result; dec.flushstrstr(a, result, true); WVPASS(result == a_dec); WVPASS(dec.isfinished()); WVPASS(dec.isfinished() == dec.isok()); // should be able to call twice WvString should_be_empty(""); bool b = dec.flushstrstr( a, should_be_empty, true ); // can't encode again WVPASS(b == false); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == a_dec); } { WvBase64Decoder dec; WvDynBuf src, dest; src.put(FOUR_LETTERS_ENC, sizeof(FOUR_LETTERS_ENC) - 1); dec.encode(src, dest, true, false); // don't finish yet. dec.finish(dest); // ok, NOW finish. WVPASS(dest.used() == 4 && !memcmp( dest.peek( 0, dest.used() ), FOUR_LETTERS, 4)); WVPASS(dec.isfinished()); WVPASS(dec.isfinished() == dec.isok()); // should be able to call twice // shouldn't be able to encode again dest.zap(); bool b = dec.encode( src, dest, true, true ); WVPASS(b == false); WVPASS(dest.used() == 0); } } WVTEST_MAIN("resetting") { { // call finish, make sure it was finished, then reset it and // use it again WvBase64Encoder enc; WvDynBuf temp; WvString b(SIX_LETTERS), b_enc(SIX_LETTERS_ENC); WvString should_be_empty(""); enc.finish(temp); WVPASS(enc.isfinished()); // ensure finished bool ret = enc.flushstrstr( b, should_be_empty, true ); // can't encode again WVPASS(ret == false); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == b_enc); enc.reset(); WVFAIL(enc.isfinished()); WvString result(""); enc.flushstrstr(b, result, true); WVPASS(result == b_enc); WVPASS(enc.isfinished()); } // same test as above with Decoder { // call finish, make sure it was finished, then reset it and // use it again WvBase64Decoder dec; WvDynBuf temp; WvString b(SIX_LETTERS), b_enc(SIX_LETTERS_ENC); WvString should_be_empty(""); dec.finish(temp); WVPASS(dec.isfinished()); // ensure finished bool ret = dec.flushstrstr( b_enc, should_be_empty, true ); // can't encode again WVPASS(ret == false); WVPASS(should_be_empty == ""); WVFAIL(should_be_empty == b); dec.reset(); WVFAIL(dec.isfinished()); WvString result(""); dec.flushstrstr(b_enc, result, true); wvcon->print( "%s", result ); WVPASS(result == b); WVPASS(dec.isfinished()); } } wvstreams-4.6.1/utils/t/wvcallback.t.cc0000644000175000001440000000474111042636572017073 0ustar wlachusers#include "wvtest.h" #include "wvtr1.h" #include // START callbacktest.cc definitions struct A { long x, y; A(long _x = 0, long _y = 0) { x = _x; y = _y; } A add(const A &a) { return A(x+a.x, y+a.y); } }; typedef wv::function ACallback; typedef wv::function A2Callback; typedef wv::function A3Callback; static A bunk(const A &a, void *userdata) { long incr = (long)userdata; return A(a.x+incr, a.y+incr*2); } // one-parameter version of bunk() static A bunk1(const A &a) { return bunk(a, (void *)1); } typedef wv::function Cb; typedef wv::function ICb; void f() { // nothing } class Derived : public Cb { public: Derived(const Cb &cb) : Cb(cb) { } }; static int ginstance; class Functor { public: int instance; Functor() { instance = ++ginstance; } Functor(const Functor &f) { instance = ++ginstance; } int operator()() { return instance; } }; WVTEST_MAIN("callbacktest.cc") { { A a(1000, 2000); A result; ACallback c0(bunk); A2Callback c1(bunk1); A3Callback c2(wv::bind(&bunk, a, _1)); A2Callback c3(wv::bind(&A::add, &a, _1)); result = (c0(a, (void *)5)); if (!WVPASS(result.y == 2 * result.x)) printf(" because [%ld] != 2 * [%ld]\n", result.y, result.x); result = (c1(a)); if (!WVPASS(result.y == 2 * result.x)) printf(" because [%ld] != 2 * [%ld]\n", result.y, result.x); result = (c2((void *)2)); if (!WVPASS(result.y == 2 * result.x)) printf(" because [%ld] != 2 * [%ld]\n", result.y, result.x); result = (c3(a)); if (!WVPASS(result.y == 2 * result.x)) printf(" because [%ld] != 2 * [%ld]\n", result.y, result.x); } } WVTEST_MAIN("cbweirdtest") { { Cb cb1(f); Cb cb2(cb1); Derived cb3(f); Derived cb4(cb1); Derived cb5(cb3); cb5(); cb4(); } WVPASS(true); // test that instantiating WvCallback from a functor object actually // copies that object, it doesn't just take a reference. // This is relevant for WvCont. { Functor ff; WVPASSEQ(ff(), 1); WVPASSEQ(ff(), 1); ICb *cb1 = new ICb(ff); ICb *cb2 = new ICb(*cb1); int c1 = (*cb1)(); WVPASS(c1 > 1); delete cb1; WVPASS((*cb2)() > c1); delete cb2; } WVPASS(true); } wvstreams-4.6.1/utils/t/wvstringmask.t.cc0000644000175000001440000000213611122170511017476 0ustar wlachusers#include "wvtest.h" #include "wvstringmask.h" #include #include WVTEST_MAIN("wvstringmask") { WvStringMask a, b(""), c(' '), d("cab"); // null bool empty = true; for (int i = CHAR_MIN; i < 256; ++i) { if (a[i]) { printf("i == %d\n", i); empty = false; } } WVPASS(empty); WVPASSEQ(a.first(), '\0'); // empty string empty = true; for (int i = CHAR_MIN; i < 256; ++i) { if (b[i]) { printf("i == %d\n", i); empty = false; } } WVPASS(empty); WVPASSEQ(b.first(), '\0'); // space character empty = true; for (int i = CHAR_MIN; i < 256; ++i) { if (c[i]) { printf("i == %d\n", i); empty = false; } } WVFAIL(empty); WVPASSEQ(c.first(), ' '); // string empty = true; for (int i = CHAR_MIN; i < 256; ++i) { switch (i) { case 'a': case 'b': case 'c': if (!d[i]) { printf("i == %d\n", i); WVPASS(d[i]); } break; default: if (d[i]) { printf("i == %d\n", i); WVFAIL(d[i]); } } } WVPASSEQ(d.first(), 'c'); } wvstreams-4.6.1/utils/t/wvglob.t.cc0000644000175000001440000000300111036722347016245 0ustar wlachusers#include "wvtest.h" #include "wvglob.h" #include "wvstream.h" WVTEST_MAIN("glob to regex") { const char **glob; // Good globs: const char *good_globs[] = { "", "?", "*", "[abc]", "[!abc]", "[^abc]", "*.{cc,h}", "*.{}", "file?.[abc]d*", "+|()$^", "[!0-9]", "{n{1,+|2{a,b,c},3}e\\{st.{c\\[c*,?h},fi\\?le[!0-9]}", NULL }; for (glob=&good_globs[0]; *glob; ++glob) { WvString errstr; WvString regex = WvGlob::glob_to_regex(*glob, &errstr); WVPASS(!errstr); wvout->print("glob=%s regex=%s errstr=%s\n", *glob, regex, errstr); } // Bad globs: const char *bad_globs[] = { "[a-z", "file*.{a,b", "{a,b{c,d{e,f},g},h[def", "\\[\\*\\", NULL }; for (glob=&bad_globs[0]; *glob; ++glob) { WvString errstr; WvString regex = WvGlob::glob_to_regex(*glob, &errstr); WVFAIL(!errstr); wvout->print("glob=%s regex=%s errstr=%s\n", *glob, regex, errstr); } } WVTEST_MAIN("glob object") { WvGlob glob("file[0-9].{cc,h}"); WVPASS(glob.match("file3.h")); WVPASS(glob.match("file9.cc")); WVFAIL(glob.match("fil3.h")); WVFAIL(glob.match("")); WVFAIL(glob.match("file")); } WVTEST_MAIN("glob registers") { WvGlob glob("file?.{cc,h}.*.[a-z]"); WvString one, two, three, four; WVPASS(glob.match("file7.cc.fred.q", one, two, three, four)); WVPASS(one == "7"); WVPASS(two == "cc"); WVPASS(three == "fred"); WVPASS(four == "q"); } wvstreams-4.6.1/utils/t/verstring.t.cc0000644000175000001440000001120211036722347016772 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. */ #include "wvtest.h" #include "wvverstring.h" #include #include /** Tests ver_to_string(), string_to_ver(), new_ver_to_string(), * string_to_new_ver(), old_ver_to_string(), and string_to_old_ver(). * * Given a hex number 0xabcdefgh, where each letter represents a hex * digit, old_ver_to_string should return a string of the form "abcd.efgh", * with any meaningless zeros removed. new_ver_to_string should return * a string of the form "ab.cd.efgh", with zeroes at the beginning only * removed. * * Similarly, given a string of the form "abcd.efgh", string_to_old_ver * should return a hex number of the form 0xabcdefgh, with implicit * meaningless zeros inserted. string_to_new_ver would translate * "ab.cd.efgh" as 0xabcdefgh. string_to_new_ver should also translate * "ab.c.def" as 0xab0cdef0. * * string_to_ver and ver_to_string should choose the new or old functions; * see wvverstring.h for details. */ WVTEST_MAIN("new_version functions") { // old-style versions if (!WVFAIL(strcmp(old_ver_to_string(0x99998888), "9999.8888"))) printf(" because [%s] != [9999.8888]\n", old_ver_to_string(0x99998888)); if (!WVPASS(string_to_old_ver("1.0") == 0x00010000)) printf(" because [%08x] != [00010000]\n", string_to_old_ver("1.0")); if (!WVFAIL(strcmp(old_ver_to_string(0x01a00200), "1a0.02"))) printf(" because [%s] != [1a0.02]\n", old_ver_to_string(0x01a00200)); if (!WVPASS(string_to_old_ver(".02a") == 0x000002a0)) printf(" because [%08x] != [000002a0]\n", string_to_old_ver(".02a")); if (!WVFAIL(strcmp(old_ver_to_string(0x00001000), "0.1"))) printf(" because [%s] != [0.1]\n", old_ver_to_string(0x00001000)); if (!WVPASS(string_to_old_ver("1b") == 0x001b0000)) printf(" because [%08x] != [001b0000]\n", string_to_old_ver("1b")); if (!WVFAIL(strcmp(old_ver_to_string(0x00000000), "0.0"))) printf(" because [%s] != [0.0]\n", old_ver_to_string(0x00000000)); if (!WVPASS(string_to_old_ver("1A.") == 0x001a0000)) printf(" because [%08x] != [001a0000]\n", string_to_old_ver("1A.")); // new-style versions if (!WVFAIL(strcmp(new_ver_to_string(0x99887777), "99.88.7777"))) printf(" because [%s] != [99.88.7777]\n", new_ver_to_string(0x99887777)); if (!WVFAIL(strcmp(new_ver_to_string(0x01a00200), "1.a0.0200"))) printf(" because [%s] != [1.a0.02]\n", new_ver_to_string(0x01a00200)); if (!WVFAIL(strcmp(new_ver_to_string(0x00001000), "0.00.1000"))) printf(" because [%s] != [0.00.1]\n", new_ver_to_string(0x00001000)); if (!WVFAIL(strcmp(new_ver_to_string(0x00000000), "0.00.0000"))) printf(" because [%s] != [0.00.0]\n", new_ver_to_string(0x00000000)); if (!WVFAIL(strcmp(new_ver_to_string(0x04010000), "4.01.0000"))) printf(" because [%s] != [4.01.0]\n", new_ver_to_string(0x04010000)); if (!WVPASS(string_to_new_ver("1.00.0") == 0x01000000)) printf(" because [%08x] != [01000000]\n", string_to_new_ver("1.00.0")); if (!WVPASS(string_to_new_ver("3.66c") == 0x0366c000)) printf(" because [%08x] != [0366c000]\n", string_to_new_ver("3.66c")); if (!WVPASS(string_to_new_ver(".02.a") == 0x0002a000)) printf(" because [%08x] != [0002a000]\n", string_to_new_ver(".02.a")); if (!WVPASS(string_to_new_ver("4.1.2a6") == 0x04012a60)) printf(" because [%08x] != [04012a60]\n", string_to_new_ver("4.1.2a6")); if (!WVPASS(string_to_new_ver(".5.37ab") == 0x000537ab)) printf(" because [%08x] != [000537ab]\n", string_to_new_ver(".5.37a")); if (!WVPASS(string_to_new_ver("1b") == 0x1b000000)) printf(" because [%08x] != [1b000000]\n", string_to_new_ver("1b")); if (!WVPASS(string_to_new_ver("1A.") == 0x1a000000)) printf(" because [%08x] != [1a000000]\n", string_to_new_ver("1A.")); if (!WVPASS(string_to_new_ver("4.01") == 0x04010000)) printf(" because [%08x] != [04010000]\n", string_to_new_ver("4.01")); // automatic conversion if (!WVFAIL(strcmp(ver_to_string(0x01000001), "1.00.0001"))) printf(" because [%s] != [1.00.0001]\n", ver_to_string(0x01000001)); if (!WVFAIL(strcmp(ver_to_string(0x00999999), "99.9999"))) printf(" because [%s] != [99.9999]\n", ver_to_string(0x00999999)); if (!WVPASS(string_to_ver("1.0") == 0x00010000)) printf(" because [%08x] != [00010000]\n", string_to_ver("1.0")); if (!WVPASS(string_to_ver("1.0.0") == 0x01000000)) printf(" because [%08x] != [01000000]\n", string_to_ver("1.0.0")); } wvstreams-4.6.1/utils/t/wvpushdir.t.cc0000644000175000001440000000324611202637334017007 0ustar wlachusers#include "wvtest.h" #include "wvpushdir.h" #include #include #include #include #include WVTEST_MAIN("pushdir exists") { WvString dir("/tmp/wvpushdir-%s", getpid()); mkdir(dir, 0775); WvPushDir newpushdir(dir); WVPASS(newpushdir.isok()); #ifdef MACOS char *pwd = static_cast(calloc(PATH_MAX,sizeof(char *))); getcwd(pwd,PATH_MAX); #else char *pwd = get_current_dir_name(); #endif WVPASSEQ(pwd, dir); free(pwd); unlink(dir); } WVTEST_MAIN("pushdir does NOT exist") { WvString dir("/tmp/wvpushdir-%s", getpid() + 32767); WvPushDir newpushdir(dir); WVFAIL(newpushdir.isok()); } WVTEST_MAIN("pushdir is a file") { WvString dir("/tmp/wvpushdir-%s", getpid()); mkdir(dir, 0775); system(WvString("touch %s/tmpfile", dir)); WvPushDir newpushdir(WvString("%s/tmpfile", dir)); WVFAIL(newpushdir.isok()); unlink(WvString("%s/tmpfile", dir)); unlink(dir); } WVTEST_MAIN("rmdir calls fail") { WvString dir("/tmp/wvpushdir-%s", getpid()); mkdir(dir, 0775); WvPushDir newpushdir(dir); WVFAIL(rmdir(dir)); WVPASS(newpushdir.isok()); } #ifndef _WIN32 WVTEST_MAIN("pushdir is allocated on the STACK only") { pid_t child = fork(); if (child == 0) { (void)new WvPushDir("anyfile"); // should never be reached, if it does, it should return good so // that we'll fail when we check for a fail _exit(0); } else if (child < 0) { WVFAIL("Fork failed"); return; } int status; waitpid(child, &status, 0); WVPASSEQ(WTERMSIG(status), 6); // sig_abrt } #endif wvstreams-4.6.1/utils/t/wvdynbuf.t.cc0000644000175000001440000000655611036722347016633 0ustar wlachusers#include "wvbuf.h" #include "wvtest.h" #include "wvstrutils.h" WVTEST_MAIN("DynBuf") { { WvDynBuf b; char *s; WVPASS(b.used() == 0); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.put("frogs on ice", 13); WVPASS(b.used() == 13); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.put("frogs on rice", 14); WVPASS(b.used() == 27); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); s = (char *)b.get(8); if (WVFAIL(strcmp(s, "frogs on ice"))) printf(" because [%s] != [frogs on ice]\n", s); WVPASS(b.used() == 19); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.put("frogs on bryce", 15); s = (char *)b.get(5); if (WVFAIL(strcmp(s, " ice"))) printf(" because [%s] != [ ice]\n", s); WVPASS(b.used() == 29); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); s = (char *)b.get(16); if (WVFAIL(strcmp(s, "frogs on rice"))) printf(" because [%s] != [frogs on rice]\n", s); WVPASS(b.used() == 13); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); b.unget(12); WVPASS(b.used() == 25); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); s = (char *)b.get(11); if (WVFAIL(strcmp(s, "s on rice"))) printf(" because [%s] != [s on rice]\n", s); s = (char *)b.get(14); if (WVFAIL(strcmp(s, "rogs on bryce"))) printf(" because [%s] != [rogs on bryce]\n", s); WVPASS(b.used() == 0); WVPASS(b.strchr('c') == b.strchr((unsigned char)'c')); } { WvDynBuf buf; buf.put("get \0", 5); buf.put("not \0", 5); buf.put("this\0", 5); WvString s; s.append((char *)buf.get(5)); buf.skip(5); s.append((char *)buf.get(5)); WVPASS(strcmp(s.cstr(), "Get this")); } { WvDynBuf big; char bigbuf[1024]; memset(bigbuf, 'c', 1024); for (int x=0; x < 768; x++) big.put(bigbuf, 1024); WVPASSEQ(big.used(), 786432); bool ok = true; for (int x=0; x < 1024; x++) { if (strncmp((const char *)big.get(768), bigbuf, 768)) ok = false; } WVPASS(ok); } } const int NUM_ZEROS = 4096; // this test makes sure that one can grab large chunks of data from a dynbuf WVTEST_MAIN("dynbuf contiguous getting") { WvDynBuf b; WvStringList outlines; for (int j=0; j<3; j++) { outlines.append("Version: 4"); outlines.append("Authenticate: foo"); char zeros[NUM_ZEROS]; memset(zeros, (int)'0', NUM_ZEROS); outlines.append(zeros); } WvStringList::Iter iter(outlines); for (iter.rewind(); iter.next();) { b.put(iter().cstr(), iter().len()); b.put('\n'); } for (iter.rewind(); iter.next();) { size_t i = 0; i = b.strchr('\n'); if (i > 0) { char *eol = (char *)b.mutablepeek(i - 1, 1); assert(eol); *eol = 0; WvString bar(const_cast((const char *)b.get(i))); WVPASS(bar == iter()); } } } wvstreams-4.6.1/utils/t/wvglobdiriter.t.cc0000644000175000001440000000445211036722347017643 0ustar wlachusers#include #include #include #include #include static bool create_dir(WvStringParm dir, const WvStringList &entries) { if (mkdir(dir, 0700)) return false; WvStringList::Iter entry(entries); for (entry.rewind(); entry.next(); ) { WvString name("%s/%s", dir, *entry); mkdir(getdirname(name), 0700); WvFile(name, O_CREAT | O_EXCL, 0600).print("wvtest"); } return true; } static bool destroy_dir(WvStringParm dir) { system(WvString("rm -rf %s", dir)); return true; } WVTEST_MAIN("Non-recursive WvGlobDirIter") { WvString dir("/tmp/wvtest-wvdiriter-%s", getpid()); WvStringList entries; entries.split("file-one file-two .dot-file subdir/sub-file"); WVPASS(create_dir(dir, entries)); std::map found; WvGlobDirIter di(dir, "file-*", false); for (di.rewind(); di.next(); ) found[di->relname] = true; WVFAIL(found.find(".") != found.end()); WVFAIL(found.find("..") != found.end()); WVPASS(found.find("file-one") != found.end()); WVPASS(found.find("file-two") != found.end()); WVFAIL(found.find(".dot-file") != found.end()); WVFAIL(found.find("subdir") != found.end()); WVFAIL(found.find("subdir/.") != found.end()); WVFAIL(found.find("subdir/..") != found.end()); WVFAIL(found.find("subdir/sub-file") != found.end()); WVPASS(destroy_dir(dir)); } WVTEST_MAIN("Recursive WvGlobDirIter") { WvString dir("/tmp/wvtest-wvdiriter-%s", getpid()); WvStringList entries; entries.split("file-one file-two .dot-file subdir/sub-file"); WVPASS(create_dir(dir, entries)); std::map found; WvGlobDirIter di(dir, "subdir/*-file", true); for (di.rewind(); di.next(); ) found[di->relname] = true; WVFAIL(found.find(".") != found.end()); WVFAIL(found.find("..") != found.end()); WVFAIL(found.find("file-one") != found.end()); WVFAIL(found.find("file-two") != found.end()); WVFAIL(found.find(".dot-file") != found.end()); WVFAIL(found.find("subdir") != found.end()); WVFAIL(found.find("subdir/.") != found.end()); WVFAIL(found.find("subdir/..") != found.end()); WVPASS(found.find("subdir/sub-file") != found.end()); WVPASS(destroy_dir(dir)); } wvstreams-4.6.1/utils/wvgzip.cc0000644000175000001440000000752511077124114015576 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Gzip encoder/decoder based on zlib. */ #include "wvgzip.h" #include #include #define ZBUFSIZE 10240 WvGzipEncoder::WvGzipEncoder(Mode _mode, size_t _out_limit) : out_limit(_out_limit), tmpbuf(ZBUFSIZE), mode(_mode) { ignore_decompression_errors = false; full_flush = false; init(); } WvGzipEncoder::~WvGzipEncoder() { close(); } void WvGzipEncoder::init() { zstr = new z_stream; memset(zstr, 0, sizeof(*zstr)); zstr->zalloc = Z_NULL; zstr->zfree = Z_NULL; zstr->opaque = NULL; zstr->msg = NULL; int retval; if (mode == Deflate) retval = deflateInit(zstr, Z_BEST_SPEED); else retval = inflateInit(zstr); if (retval != Z_OK) { seterror("error %s initializing gzip %s: %s", retval, mode == Deflate ? "compressor" : "decompressor", zstr->msg ? zstr->msg : "unknown"); return; } zstr->next_in = zstr->next_out = NULL; zstr->avail_in = zstr->avail_out = 0; } void WvGzipEncoder::close() { if (mode == Deflate) deflateEnd(zstr); else inflateEnd(zstr); delete zstr; } bool WvGzipEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { bool success; output = 0; for (;;) { size_t starting_size = inbuf.used(); prepare(& inbuf); bool alldata = inbuf.used() == 0; success = process(outbuf, flush && alldata, false); if (zstr->avail_in != 0) { // unget unused data inbuf.unget(zstr->avail_in); zstr->avail_in = 0; } if (! success) return false; if (alldata || (starting_size == inbuf.used()) || (out_limit && (output >= out_limit))) return true; } } bool WvGzipEncoder::_finish(WvBuf &outbuf) { prepare(NULL); return process(outbuf, false, true); } bool WvGzipEncoder::_reset() { close(); init(); return true; } void WvGzipEncoder::prepare(WvBuf *inbuf) { assert(zstr->avail_in == 0); if (inbuf && inbuf->used() != 0) { size_t avail = inbuf->optgettable(); zstr->avail_in = avail; zstr->next_in = const_cast( (const Bytef*)inbuf->get(avail)); } else { zstr->avail_in = 0; zstr->next_in = (Bytef*)""; // so it's not NULL } } bool WvGzipEncoder::process(WvBuf &outbuf, bool flush, bool finish) { int flushmode = finish ? Z_FINISH : flush ? (full_flush ? Z_FULL_FLUSH : Z_SYNC_FLUSH) : Z_NO_FLUSH; int retval; do { // process the next chunk tmpbuf.zap(); size_t avail_out = tmpbuf.free(); if (out_limit) avail_out = tmpbuf.free() < (out_limit - output) ? tmpbuf.free() : (out_limit - output); zstr->avail_out = avail_out; zstr->next_out = tmpbuf.alloc(avail_out); if (mode == Deflate) retval = deflate(zstr, flushmode); else retval = inflate(zstr, flushmode); tmpbuf.unalloc(zstr->avail_out); output += avail_out - zstr->avail_out; // consume pending output outbuf.merge(tmpbuf); if (retval == Z_DATA_ERROR && mode == Inflate && ignore_decompression_errors) retval = inflateSync(zstr); } while (retval == Z_OK && (!out_limit || (out_limit > output))); if (retval == Z_STREAM_END) setfinished(); else if (retval != Z_OK && retval != Z_BUF_ERROR && !(retval == Z_DATA_ERROR && mode == Inflate && ignore_decompression_errors)) { seterror("error %s during gzip %s: %s", retval, mode == Deflate ? "compression" : "decompression", zstr->msg ? zstr->msg : "unknown"); return false; } return true; } wvstreams-4.6.1/utils/wvencoder.cc0000644000175000001440000001717211036722347016252 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A top-level data encoder class. See wvencoder.h. */ #include "wvencoder.h" /***** WvEncoder *****/ WvEncoder::WvEncoder() { okay = true; finished = false; } WvEncoder::~WvEncoder() { } WvString WvEncoder::geterror() const { if (isok()) return WvString::null; if (!!errstr) return errstr; WvString message = _geterror(); if (!!message) return message; return "unknown encoder error"; } bool WvEncoder::encode(WvBuf &inbuf, WvBuf &outbuf, bool flush, bool _finish) { // deliberately not using isok() and isfinished() here bool success = okay && !finished && (inbuf.used() != 0 || flush); if (success) success = _encode(inbuf, outbuf, flush); if (_finish) success = finish(outbuf) && success; return success; } bool WvEncoder::finish(WvBuf &outbuf) { // deliberately not using isok() and isfinished() here bool success = okay && !finished; if (success) success = _finish(outbuf); setfinished(); return success; } bool WvEncoder::reset() { // reset local state okay = true; finished = false; errstr = WvString::null; // attempt to reset the encoder bool success = _reset(); if (!success) { if (okay) seterror("reset not supported by encoder"); } return success; } bool WvEncoder::flushstrbuf(WvStringParm instr, WvBuf &outbuf, bool finish) { WvConstStringBuffer inbuf(instr); bool success = encode(inbuf, outbuf, true, finish); return success; } bool WvEncoder::flushstrstr(WvStringParm instr, WvString &outstr, bool finish) { WvConstStringBuffer inbuf(instr); WvDynBuf outbuf; bool success = encode(inbuf, outbuf, true, finish); outstr.append(outbuf.getstr()); return success; } bool WvEncoder::encodebufstr(WvBuf &inbuf, WvString &outstr, bool flush, bool finish) { WvDynBuf outbuf; bool success = encode(inbuf, outbuf, flush, finish); outstr.append(outbuf.getstr()); return success; } WvString WvEncoder::strflushstr(WvStringParm instr, bool finish) { WvString outstr; flushstrstr(instr, outstr, finish); return outstr; } WvString WvEncoder::strflushbuf(WvBuf &inbuf, bool finish) { WvString outstr; flushbufstr(inbuf, outstr, finish); return outstr; } bool WvEncoder::flushmembuf(const void *inmem, size_t inlen, WvBuf &outbuf, bool finish) { WvConstInPlaceBuf inbuf(inmem, inlen); bool success = encode(inbuf, outbuf, true, finish); return success; } bool WvEncoder::flushmemmem(const void *inmem, size_t inlen, void *outmem, size_t *outlen, bool finish) { WvConstInPlaceBuf inbuf(inmem, inlen); return encodebufmem(inbuf, outmem, outlen, true, finish); } bool WvEncoder::encodebufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool flush, bool finish) { WvInPlaceBuf outbuf(outmem, 0, *outlen); bool success = encode(inbuf, outbuf, true, finish); *outlen = outbuf.used(); return success; } bool WvEncoder::flushstrmem(WvStringParm instr, void *outmem, size_t *outlen, bool finish) { WvConstStringBuffer inbuf(instr); return flushbufmem(inbuf, outmem, outlen, finish); } WvString WvEncoder::strflushmem(const void *inmem, size_t inlen, bool finish) { WvConstInPlaceBuf inbuf(inmem, inlen); return strflushbuf(inbuf, finish); } /***** WvNullEncoder *****/ bool WvNullEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { in.zap(); return true; } bool WvNullEncoder::_reset() { return true; } /***** WvPassthroughEncoder *****/ WvPassthroughEncoder::WvPassthroughEncoder() { _reset(); } bool WvPassthroughEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { total += in.used(); out.merge(in); return true; } bool WvPassthroughEncoder::_reset() { total = 0; return true; } /***** WvEncoderChain *****/ WvEncoderChain::WvEncoderChain() { last_run = NULL; } WvEncoderChain::~WvEncoderChain() { } bool WvEncoderChain::_isok() const { ChainElemList::Iter it(const_cast(encoders)); for (it.rewind(); it.next(); ) if (!it->enc->isok()) return false; return true; } bool WvEncoderChain::_isfinished() const { ChainElemList::Iter it(const_cast(encoders)); for (it.rewind(); it.next(); ) if (it->enc->isfinished()) return true; return false; } WvString WvEncoderChain::_geterror() const { ChainElemList::Iter it(const_cast(encoders)); for (it.rewind(); it.next(); ) { WvString message = it->enc->geterror(); if (!!message) return message; } return WvString::null; } // NOTE: In this function we deliberately ignore deep isok() and // isfinished() results to allow addition/removal of // individual broken encoders while still processing data // through as much of the chain as possible. bool WvEncoderChain::do_encode(WvBuf &in, WvBuf &out, ChainElem *start_after, bool flush, bool finish) { bool success = true; WvBuf *tmpin = ∈ ChainElemList::Iter it(encoders); it.rewind(); if (start_after) it.find(start_after); last_run = start_after; for (; it.cur() && it.next(); ) { if (!it->enc->encode(*tmpin, it->out, flush)) success = false; if (finish && !it->enc->finish(it->out)) success = false; last_run = it.ptr(); tmpin = &it->out; } out.merge(*tmpin); return success; } bool WvEncoderChain::_encode(WvBuf &in, WvBuf &out, bool flush) { return do_encode(in, out, NULL, flush, false); } bool WvEncoderChain::_finish(WvBuf &out) { WvNullBuf empty; return do_encode(empty, out, NULL, true, true); } bool WvEncoderChain::continue_encode(WvBuf &in, WvBuf &out) { //fprintf(stderr, "continue_encode(%d,%d,%p)\n", // in.used(), out.used(), last_run); return do_encode(in, out, last_run, false, false); } bool WvEncoderChain::_reset() { bool success = true; ChainElemList::Iter it(encoders); for (it.rewind(); it.next(); ) { it->out.zap(); if (!it->enc->reset()) success = false; } return success; } void WvEncoderChain::append(WvEncoder *enc, bool autofree) { encoders.append(new ChainElem(enc, autofree), true); } void WvEncoderChain::prepend(WvEncoder *enc, bool autofree) { encoders.prepend(new ChainElem(enc, autofree), true); } bool WvEncoderChain::get_autofree(WvEncoder *enc) const { ChainElemList::Iter i(encoders); for (i.rewind(); i.next(); ) if (i->enc == enc && i.get_autofree()) return true; return false; } void WvEncoderChain::set_autofree(WvEncoder *enc, bool autofree) { ChainElemList::Iter i(encoders); if (autofree) { // Ensure only the first matching encoder has autofree set bool first = true; for (i.rewind(); i.next(); ) { if (i->enc == enc) { if (first) { i.set_autofree(true); first = false; } else i.set_autofree(false); } } } else { // Clear autofree for all matching encoders for (i.rewind(); i.next(); ) if (i->enc == enc) i.set_autofree(false); } } void WvEncoderChain::unlink(WvEncoder *enc) { ChainElemList::Iter it(encoders); for (it.rewind(); it.next(); ) if (it->enc == enc) it.xunlink(); } void WvEncoderChain::zap() { encoders.zap(); } size_t WvEncoderChain::buffered() { size_t used = 0; ChainElemList::Iter it(encoders); for (it.rewind(); it.next(); ) used += it().out.used(); return used; } wvstreams-4.6.1/utils/wvmoniker.cc0000644000175000001440000001057011057766345016303 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Support for monikers, which are strings that you can pass to a magic * factory to get objects supporting a particular interface. See wvmoniker.h. */ #include "wvmonikerregistry.h" #include "strutils.h" #include #include #include "wvscatterhash.h" #if 0 # define DEBUGLOG(fmt, args...) fprintf(stderr, fmt, ## args) #else #ifndef _MSC_VER # define DEBUGLOG(fmt, args...) #else // MS Visual C++ doesn't support varags preproc macros # define DEBUGLOG #endif #endif static unsigned WvHash(const UUID &_uuid) { unsigned val = 0; unsigned int *uuid = (unsigned int *)&_uuid; int max = sizeof(UUID)/sizeof(*uuid); for (int count = 0; count < max; count++) val += uuid[count]; return val; } DeclareWvScatterDict(WvMonikerRegistry, UUID, reg_iid); static WvMonikerRegistryDict *regs; WvMonikerRegistry::WvMonikerRegistry(const UUID &iid) : reg_iid(iid) { DEBUGLOG("WvMonikerRegistry creating.\n"); refcount = 0; } WvMonikerRegistry::~WvMonikerRegistry() { DEBUGLOG("WvMonikerRegistry destroying.\n"); } void WvMonikerRegistry::add(WvStringParm id, WvMonikerCreateFunc *func, const bool override) { DEBUGLOG("WvMonikerRegistry register(%s).\n", id.cstr()); if (!override) { RegistrationList::Iter i(list); for (i.rewind(); i.next(); ) assert(i.ptr()->id != id); //no duplicates without override } list.prepend(new Registration(id, func), true); } void WvMonikerRegistry::del(WvStringParm id) { DEBUGLOG("WvMonikerRegistry unregister(%s).\n", id.cstr()); RegistrationList::Iter i(list); for (i.rewind(); i.next(); ) { if (i.ptr()->id == id) { i.unlink(); return; } } //We should never get here, as we should never be removing elements which don't exist assert(false); } void *WvMonikerRegistry::create(WvStringParm _s, IObject *obj) { WvString t(_s); WvString s(trim_string(t.edit())); char *cptr = strchr(s.edit(), ':'); if (cptr) *cptr++ = 0; else cptr = (char*)""; DEBUGLOG("WvMonikerRegistry create object ('%s' '%s').\n", s.cstr(), cptr); RegistrationList::Iter i(list); for (i.rewind(); i.next(); ) { if (i.ptr()->id == s) return i.ptr()->func(cptr, obj); } return NULL; } WvMonikerRegistry *WvMonikerRegistry::find_reg(const UUID &iid) { DEBUGLOG("WvMonikerRegistry find_reg.\n"); if (!regs) regs = new WvMonikerRegistryDict(10); WvMonikerRegistry *reg = (*regs)[iid]; if (!reg) { // we have to make one! reg = new WvMonikerRegistry(iid); regs->add(reg, true); reg->addRef(); // one reference for being in the list at all } reg->addRef(); return reg; } IObject *WvMonikerRegistry::getInterface(const UUID &uuid) { #if 0 if (uuid.equals(IObject_IID)) { addRef(); return this; } #endif // we don't really support any interfaces for now. return 0; } unsigned int WvMonikerRegistry::addRef() { DEBUGLOG("WvMonikerRegistry addRef.\n"); return ++refcount; } unsigned int WvMonikerRegistry::release() { DEBUGLOG("WvMonikerRegistry release.\n"); if (--refcount > 1) return refcount; if (refcount == 1) { // the list has one reference to us, but it's no longer needed. // Note: remove() will delete this object! regs->remove(this); if (regs->isempty()) { delete regs; regs = NULL; } return 0; } /* protect against re-entering the destructor */ refcount = 1; delete this; return 0; } WvMonikerBase::WvMonikerBase(const UUID &iid, WvStringParm _id, WvMonikerCreateFunc *func, const bool override) : id(_id) { DEBUGLOG("WvMoniker creating(%s).\n", id.cstr()); reg = WvMonikerRegistry::find_reg(iid); if (reg) reg->add(id, func, override); } WvMonikerBase::~WvMonikerBase() { DEBUGLOG("WvMoniker destroying(%s).\n", id.cstr()); if (reg) { reg->del(id); WVRELEASE(reg); } } void *wvcreate(const UUID &iid, WvStringParm moniker, IObject *obj) { assert(!moniker.isnull()); // fprintf(stderr, "wvcreate: Looking for '%s'\n", moniker.cstr()); WvMonikerRegistry *reg = WvMonikerRegistry::find_reg(iid); if (reg) { void *ret = reg->create(moniker, obj); WVRELEASE(reg); return ret; } else return NULL; } wvstreams-4.6.1/utils/wvshmzone.cc0000644000175000001440000000140011036722347016301 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A shared-memory zone via mmap(). See wvshmzone.h. */ #include "wvshmzone.h" #include #include #include #include #include #include #include WvShmZone::WvShmZone(size_t _size) { size = (int)_size; assert(size > 0); buf = NULL; fd = open("/dev/zero", O_RDWR); if (fd < 0) { seterr(errno); return; } buf = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (!buf) { seterr(errno); return; } } WvShmZone::~WvShmZone() { if (buf) munmap(buf, size); if (fd >= 0) close(fd); } wvstreams-4.6.1/utils/wverror.cc0000644000175000001440000001201311205042556015744 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A class for managing error numbers and strings. See wverror.h. */ #include "wverror.h" #include #ifdef _WIN32 #include "windows.h" struct WvErrMap { int num; const char *str; }; static WvErrMap wverrmap[] = { { WSAEINTR, "Interrupted" }, { WSAEBADF, "Bad file descriptor" }, { WSAEACCES, "Access denied" }, { WSAEFAULT, "Bad address" }, { WSAEINVAL, "Invalid argument" }, { WSAEMFILE, "Too many open files" }, { WSAEWOULDBLOCK, "Operation would block" }, { WSAEINPROGRESS, "Operation now in progress" }, { WSAEALREADY, "Operation already in progress" }, { WSAENOTSOCK, "Socket operation on non-socket" }, { WSAEDESTADDRREQ, "Destination address required" }, { WSAEMSGSIZE, "Message too long" }, { WSAEPROTOTYPE, "Protocol wrong type for socket" }, { WSAENOPROTOOPT, "Protocol not available" }, { WSAEPROTONOSUPPORT, "Protocol not supported" }, { WSAESOCKTNOSUPPORT, "Socket type not supported" }, { WSAEOPNOTSUPP, "Operation not supported on transport endpoint" }, { WSAEPFNOSUPPORT, "Protocol family not supported" }, { WSAEAFNOSUPPORT, "Address family not supported by protocol" }, { WSAEADDRINUSE, "Address already in use" }, { WSAEADDRNOTAVAIL, "Cannot assign requested address" }, { WSAENETDOWN, "Network is down" }, { WSAENETUNREACH, "Network is unreachable" }, { WSAENETRESET, "Network dropped connection because of reset" }, { WSAECONNABORTED, "Software caused connection abort" }, { WSAECONNRESET, "Connection reset by peer" }, { WSAENOBUFS, "No buffer space available" }, { WSAEISCONN, "Transport endpoint is already connected" }, { WSAENOTCONN, "Transport endpoint is not connected" }, { WSAESHUTDOWN, "Cannot send after transport endpoint shutdown" }, { WSAETOOMANYREFS, "Too many references: cannot splice" }, { WSAETIMEDOUT, "Connection timed out" }, { WSAECONNREFUSED, "Connection refused" }, { WSAELOOP, "Too many symbolic links encountered" }, { WSAENAMETOOLONG, "File name too long" }, { WSAEHOSTDOWN, "Host is down" }, { WSAEHOSTUNREACH, "No route to host" }, { WSAENOTEMPTY, "Directory not empty" }, { WSAEPROCLIM, "Process limit reached" }, { WSAEUSERS, "Too many users" }, { WSAEDQUOT, "Disk quota exceeded" }, { WSAESTALE, "Stale file handle" }, { WSAEREMOTE, "Object is remote" }, { WSAEDISCON, "Disconnected" }, { WSAENOMORE, "No more data" }, { WSAECANCELLED, "Operation cancelled" }, { WSAEINVALIDPROCTABLE, "Invalid process table" }, { WSAEINVALIDPROVIDER, "Invalid provider" }, { WSAEPROVIDERFAILEDINIT, "Provider failed to initialize" }, { WSAEREFUSED, "Operation refused" }, { 0, NULL } }; static const char *wv_errmap(int errnum) { for (WvErrMap *i = wverrmap; i->num; i++) if (i->num == errnum) return i->str; return NULL; } #endif WvErrorBase::~WvErrorBase() { // nothing special } // win32's strerror() function is incredibly weak, so we'll provide a better // one. WvString WvErrorBase::strerror(int errnum) { assert(errnum >= 0); #ifndef _WIN32 return ::strerror(errnum); #else const char *wverr = wv_errmap(errnum); if (wverr) return wverr; else if (errnum >= WSABASEERR && errnum < WSABASEERR+2000) { // otherwise, an unrecognized winsock error: try getting the error // message from win32. char msg[4096]; const HMODULE module = GetModuleHandle("winsock.dll"); DWORD result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, module, errnum, 0, msg, sizeof(msg), 0); if (result) return msg; DWORD e = GetLastError(); return WvString("Unknown format %s for error %s", e, errnum); } else { const char *str = ::strerror(errnum); if (!strcmp(str, "Unknown error")) return WvString("Unknown win32 error #%s", errnum); else return str; } #endif } WvString WvErrorBase::errstr() const { int errnum = geterr(); if (errnum < 0) { assert(!!errstring); return errstring; } else { if (!!errstring) return errstring; return WvErrorBase::strerror(errnum); } } void WvErrorBase::seterr(int _errnum) { if (!errnum) { assert((_errnum != -1 || !!errstring) && "attempt to set errnum to -1 without also setting errstring"); #ifdef _WIN32 if (_errnum == WSAECONNABORTED) _errnum = WSAECONNREFUSED; // work around WINE bug #endif errnum = _errnum; } } void WvErrorBase::seterr(WvStringParm specialerr) { assert(!!specialerr); if (!errnum) { errstring = specialerr; seterr(-1); } } void WvErrorBase::seterr(const WvErrorBase &err) { if (err.geterr() > 0) seterr(err.geterr()); else if (err.geterr() < 0) seterr(err.errstr()); } void WvErrorBase::seterr_both(int _errnum, WvStringParm specialerr) { assert(!!specialerr); if (!errnum) { errstring = specialerr; seterr(_errnum); } } wvstreams-4.6.1/utils/wvhex.cc0000644000175000001440000000407711036722347015417 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Hex encoder and decoder. */ #include "wvhex.h" #include static inline char tohex(int digit, char alphabase) { return (digit < 10 ? '0' : alphabase) + digit; } static inline int fromhex(char digit) { if (isdigit(digit)) return digit - '0'; if (isupper(digit)) return digit - 'A' + 10; return digit - 'a' + 10; } /***** WvHexEncoder *****/ WvHexEncoder::WvHexEncoder(bool use_uppercase) { alphabase = (use_uppercase ? 'A' : 'a') - 10; _reset(); } bool WvHexEncoder::_reset() { return true; } bool WvHexEncoder::_encode(WvBuf &in, WvBuf &out, bool flush) { while (in.used() != 0) { unsigned char byte = in.getch(); out.putch(tohex(byte >> 4, alphabase)); out.putch(tohex(byte & 15, alphabase)); } return true; } /***** WvHexDecoder *****/ WvHexDecoder::WvHexDecoder() { _reset(); } bool WvHexDecoder::_reset() { issecond = false; first = 0; return true; } bool WvHexDecoder::_encode(WvBuf &in, WvBuf &out, bool flush) { while (in.used() != 0) { char ch = (char) in.getch(); if (isxdigit(ch)) { int digit = fromhex(ch); if ( (issecond = ! issecond) ) first = digit; else out.putch(first << 4 | digit); continue; } if (isspace(ch)) continue; seterror("invalid character '%s' in hex input", ch); return false; } if (flush && issecond) return false; // not enough hex digits supplied return true; } /*** Compatibility ***/ void hexify(char *obuf, const void *ibuf, size_t len) { size_t outlen = len * 2 + 1; WvHexEncoder(false /*use_uppercase*/). flushmemmem(ibuf, len, obuf, & outlen); obuf[outlen] = '\0'; } void unhexify(void *obuf, const char *ibuf) { size_t inlen = strlen(ibuf); size_t outlen = inlen / 2; WvHexDecoder().flushmemmem(ibuf, inlen, obuf, & outlen); } wvstreams-4.6.1/utils/wvsystem.cc0000644000175000001440000000307611036722347016155 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A more convenient wrapper around WvSubProc. See wvsystem.h. */ #include "wvsystem.h" #include #include #include WvSystem::~WvSystem() { go(); } void WvSystem::init(const char * const *argv) { started = false; WvSubProc::preparev(argv[0], argv); } // open a given filename or device, making sure it has the given fd. If // there is an open file on that fd already, it gets closed. static void fd_open(int fd, WvStringParm file, int mode) { ::close(fd); int nfd = ::open(file, mode, 0666); if (nfd < 0) return; if (nfd != fd) { ::dup2(nfd, fd); ::close(nfd); } } // overrides WvSubProc::fork(). int WvSystem::fork(int *waitfd) { int pid = WvSubProc::fork(waitfd); if (!pid) // child { if (!fdfiles[0].isnull()) fd_open(0, fdfiles[0], O_RDONLY); if (!fdfiles[1].isnull()) fd_open(1, fdfiles[1], O_WRONLY|O_CREAT); if (!fdfiles[2].isnull()) fd_open(2, fdfiles[2], O_WRONLY|O_CREAT); } return pid; } int WvSystem::go() { if (!started) { WvSubProc::start_again(); started = true; } WvSubProc::wait(-1, false); return WvSubProc::estatus; } WvSystem &WvSystem::infile(WvStringParm filename) { fdfiles[0] = filename; return *this; } WvSystem &WvSystem::outfile(WvStringParm filename) { fdfiles[1] = filename; return *this; } WvSystem &WvSystem::errfile(WvStringParm filename) { fdfiles[2] = filename; return *this; } wvstreams-4.6.1/utils/wvstringmask.cc0000644000175000001440000000207511036722347017011 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Implementation of an efficient lookup for a set characters. * * It is, however, a little space intensive, but you should statically * create them in your functions, and then they won't be so bad. */ #include "wvstringmask.h" WvStringMask::WvStringMask(WvStringParm s) { zap(); set(s, true); } WvStringMask::WvStringMask(char c) { zap(); set(c, true); } bool WvStringMask::operator[](const char c) const { unsigned char uc = c; return _set[uc]; } const char WvStringMask::first() const { return _first; } void WvStringMask::zap() { memset(_set, 0, sizeof(bool) * sizeof(_set)); _first = '\0'; } void WvStringMask::set(const char c, bool value) { if (!_first) _first = c; _set[unsigned(c)] = value; } void WvStringMask::set(WvStringParm s, bool value) { if (!s.isnull()) { const char *c = s.cstr(); if (!_first) _first = *c; while (*c) { _set[unsigned(*c)] = value; ++c; } } } wvstreams-4.6.1/utils/wvuid.cc0000644000175000001440000000210611036722347015403 0ustar wlachusers/* -*- Mode: C++ -*- * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Portable standins for getuid() and friends. See wvuid.h. */ #include "wvautoconf.h" #include "wvuid.h" #if WIN32 WvString wv_username_from_uid(wvuid_t uid) { // FIXME not implemented return WvString::null; } wvuid_t wv_uid_from_username(WvString username) { // FIXME not implemented return WVUID_INVALID; } wvuid_t wvgetuid() { // FIXME not implemented return WVUID_INVALID; } #else // not WIN32 WvString wv_username_from_uid(wvuid_t uid) { char buf[1024]; struct passwd pwbuf, *userinfo; if (getpwuid_r(uid, &pwbuf, buf, sizeof(buf), &userinfo) == 0) return userinfo->pw_name; else return WvString::null; } wvuid_t wv_uid_from_username(WvString username) { char buf[1024]; struct passwd pwbuf, *userinfo; if (getpwnam_r(username, &pwbuf, buf, sizeof(buf), &userinfo) != 0) return userinfo->pw_uid; else return WVUID_INVALID; } wvuid_t wvgetuid() { return getuid(); } #endif wvstreams-4.6.1/utils/complex-proc.sh0000755000175000001440000000102711036722347016706 0ustar wlachusers#!/bin/bash # A program that generates some subprograms. For testing WvSubProc. MAIN="$1-pid$$" go() { SUB="$1" trap "echo Exiting $SUB on TERM...; exit 0" SIGTERM trap "echo Exiting $SUB on INT...; exit 0" SIGINT for a in 1 2 3 4 5 6 7 8 9 10; do echo " $SUB.$a" sleep 1 done echo "Done $SUB." } trap "echo Exiting $MAIN on TERM...; exit 0" SIGTERM trap "echo Exiting $MAIN on INT...; exit 0" SIGINT for d in 1 2 3 4 5 6 7 8 9 10; do echo "Starting $MAIN.$d..." go $MAIN.$d & sleep 3 done echo "Done $MAIN." wvstreams-4.6.1/utils/wvfork.cc0000644000175000001440000000631111036722347015565 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * wvfork() just runs fork(), but it closes all file descriptors that * are flagged close-on-exec, since we don't necessarily always run * exec() after we fork()... * * This fixes the year-old mystery bug where WvTapeBackup caused * watchdog reboots because the CHILD process wasn't touching it, and * it was already open before the fork()... * * If you want to explicitly leave a file descriptor OPEN, even if * it's marked close-on-exec, then add the fd number to dontclose, and * pass that to wvfork(). This is mainly useful for WvLoopbacks -- * you may want certain ones open or closed depending on which call to * wvfork() you're making. (for WvTapeBackup, you want the three * backup loopbacks open, and, say, any WvResolver loopbacks closed.) */ #include #include "wvfork.h" #include "wvlinklist.h" #define MAX_FD sysconf(_SC_OPEN_MAX) + 1 DeclareWvList(WvForkCallback); static WvForkCallbackList *callbacks; class StupidWvForkDeallocator { public: ~StupidWvForkDeallocator() { if (callbacks) delete callbacks; } }; static StupidWvForkDeallocator sfd; // note: this shouldn't really be needed (it would be better to use a simple // static list), but might be needed if your dynamic linker (ld.so) runs // global constructors in the wrong order. static WvForkCallbackList &get_callbacks() { if (!callbacks) callbacks = new WvForkCallbackList; return *callbacks; } void add_wvfork_callback(WvForkCallback cb) { #if 0 // be sure we don't add this twice WvForkCallbackList::Iter i(get_callbacks()); for (i.rewind(); i.next(); ) if (*i == cb) return; #endif get_callbacks().append(new WvForkCallback(cb), true); } #if 0 void remove_wvfork_callback(WvForkCallback cb) { WvForkCallbackList::Iter i(get_callbacks()); for (i.rewind(); i.next(); ) if (*i == cb) i.xunlink(); } #endif pid_t wvfork(int dontclose1, int dontclose2) { intTable t(1); if (dontclose1 >= 0) t.add(&dontclose1, false); if (dontclose2 >= 0) t.add(&dontclose2, false); return (wvfork(t)); } pid_t wvfork_start(int *waitfd) { int waitpipe[2]; if (pipe(waitpipe) < 0) return -1; pid_t pid = fork(); WvForkCallbackList::Iter i(get_callbacks()); for (i.rewind(); i.next(); ) { WvForkCallback *cb = i.ptr(); (*cb)(pid); } if (pid < 0) return pid; else if (pid > 0) { // parent process. close its writing end of the pipe and wait // for its reading end to close. char buf; close(waitpipe[1]); read(waitpipe[0], &buf, 1); close(waitpipe[0]); } else { // child process. close its reading end of the pipe. close(waitpipe[0]); *waitfd = waitpipe[1]; } return pid; } pid_t wvfork(intTable &dontclose) { int waitfd = -1; pid_t pid = wvfork_start(&waitfd); if (pid != 0) { // parent or error return pid; } // child process // check the close-on-exec flag of all file descriptors for (int fd = 0; fd < MAX_FD; fd++) { if (!dontclose[fd] && fd != waitfd && (fcntl(fd, F_GETFD) & FD_CLOEXEC) > 0) close(fd); } close(waitfd); return pid; } wvstreams-4.6.1/utils/wvtclstring.cc0000644000175000001440000002222311122170511016617 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. */ #include "wvbackslash.h" #include "wvbuf.h" #include "wvstream.h" #include "wvstring.h" #include "wvstringmask.h" #include "wvtclstring.h" #include const WvStringMask WVTCL_NASTY_SPACES(WVTCL_NASTY_SPACES_STR); const WvStringMask WVTCL_NASTY_NEWLINES(WVTCL_NASTY_NEWLINES_STR); const WvStringMask WVTCL_SPLITCHARS(WVTCL_SPLITCHARS_STR); static size_t wvtcl_escape(char *dst, const char *s, size_t s_len, const WvStringMask &nasties, bool *verbatim = NULL) { if (verbatim) *verbatim = false; // NULL strings remain such if (s == NULL) return 0; // empty strings are just {} if (s_len == 0) { if (dst) { dst[0] = '{'; dst[1] = '}'; } return 2; } bool backslashify = false, inescape = false; int len = 0, unprintables = 0, bracecount = 0; const char *cptr, *cptr_end = s + s_len; // figure out which method we need to use: backslashify or embrace. // also count the number of unprintable characters we'll need to // backslashify, if it turns out that's necessary. for (cptr = s; cptr != cptr_end; cptr++) { // Assume we do nothing if (dst) dst[len] = *cptr; ++len; if (!inescape && *cptr == '{') bracecount++; else if (!inescape && *cptr == '}') bracecount--; if (bracecount < 0) backslashify = true; bool doit = false; switch (*cptr) { case WVTCL_ALWAYS_NASTY_CASE: doit = true; break; default: if (nasties[*cptr]) doit = true; } if (doit) unprintables++; if (*cptr == '\\') inescape = !inescape; else inescape = false; } // if the braces aren't balanced, backslashify if (bracecount != 0 || inescape) backslashify = true; if (!backslashify && !unprintables) { if (verbatim) *verbatim = true; return len; // no work needed! } if (backslashify) { if (dst) { len = 0; for (cptr = s; cptr != cptr_end; ++cptr) { bool doit = false; switch (*cptr) { case WVTCL_ALWAYS_NASTY_CASE: doit = true; break; default: if (nasties[*cptr]) doit = true; } if (doit) dst[len++] = '\\'; dst[len++] = *cptr; } return len; } else return len+unprintables; } else { // the embrace method: just take the string and put braces around it if (dst) { len = 0; dst[len++] = '{'; for (cptr = s; cptr != cptr_end; ++cptr) dst[len++] = *cptr; dst[len++] = '}'; return len; } else return len+2; } } WvString wvtcl_escape(WvStringParm s, const WvStringMask &nasties) { size_t s_len = s.len(); bool verbatim; size_t len = wvtcl_escape(NULL, s, s_len, nasties, &verbatim); if (verbatim) return s; WvString result; result.setsize(len); char *e = result.edit(); e += wvtcl_escape(e, s, s_len, nasties); *e = '\0'; return result; } static size_t wvtcl_unescape(char *dst, const char *s, size_t s_len, bool *verbatim = NULL) { //printf(" unescape '%s'\n", (const char *)s); // empty or NULL strings remain themselves if (!s) { if (verbatim) *verbatim = true; return 0; } if (verbatim) *verbatim = false; // deal with embraced strings by simply removing the braces if (s[0] == '{' && s[s_len-1] == '}') { if (dst) memcpy(dst, &s[1], s_len-2); return s_len - 2; } bool skipquotes = false; // deal with quoted strings by ignoring the quotes _and_ unbackslashifying. if (s[0] == '"' && s[s_len-1] == '"') skipquotes = true; // otherwise, unbackslashify it. const char *start = s, *end = &s[s_len]; if (skipquotes) { ++start; --end; } size_t len = 0; bool inescape = false; for (; start != end; ++start) { if (*start == '\\') { if (inescape) { if (dst) dst[len] = *start; len++; inescape = false; } else inescape = true; } else { inescape = false; if (dst) dst[len] = *start; len++; } } return len; } WvString wvtcl_unescape(WvStringParm s) { size_t s_len = s.len(); bool verbatim; size_t len = wvtcl_unescape(NULL, s, s_len, &verbatim); if (verbatim) return s; WvString result; result.setsize(len+1); char *e = result.edit(); e += wvtcl_unescape(e, s, s_len); *e = '\0'; return result; } WvString wvtcl_encode(WvList &l, const WvStringMask &nasties, const WvStringMask &splitchars) { int size = 0; WvList::Iter i(l); int count = 0; for (i.rewind(); i.next(); ) { size += wvtcl_escape(NULL, *i, i->len(), nasties); ++count; } WvString result; result.setsize(size+(count-1)+1); char *p = result.edit(); int j; for (i.rewind(), j=0; i.next(); ++j) { p += wvtcl_escape(p, *i, i->len(), nasties); if (j < count - 1) *p++ = splitchars.first(); } *p = '\0'; return result; } const size_t WVTCL_GETWORD_NONE (UINT_MAX); static size_t wvtcl_getword(char *dst, const char *s, size_t s_len, const WvStringMask &splitchars, bool do_unescape, size_t *end = NULL) { //printf(" used=%d\n", origsize); if (!s_len) return WVTCL_GETWORD_NONE; bool inescape = false, inquote = false, incontinuation = false; int bracecount = 0; const char *origend = s + s_len; const char *sptr, *eptr; // skip leading separators for (sptr = s; sptr != origend; sptr++) { if (!splitchars[*sptr]) break; } if (sptr == origend) // nothing left return WVTCL_GETWORD_NONE; // detect initial quote if (*sptr == '"') { inquote = true; eptr = sptr+1; } else eptr = sptr; // loop over string until something satisfactory is found for (; eptr != origend; eptr++) { char ch = *eptr; incontinuation = false; if (inescape) { if (ch == '\n') { // technically we've finished the line-continuation // sequence, but we require at least one more character // in order to prove that there's a next line somewhere // in the buffer. Otherwise we might stop parsing before // we're "really" done if we're given input line-by-line. // // A better way to do this would be for getword() to *never* // return a string unless it contains a separator character; // then we wouldn't need this weird special case. But it // don't work like that; we'll return the last word in the // buffer even if it *doesn't* end in a separator character. incontinuation = true; } inescape = false; } else if (ch == '\\') { inescape = true; // now we need a character to complete the escape } else // not an escape sequence { // detect end of a quoted/unquoted string if (bracecount == 0) { if (inquote) { if (ch == '"') { eptr++; break; } } else if (splitchars[ch]) break; } // match braces if (!inquote) { if (ch == '{') bracecount++; else if (bracecount > 0 && ch == '}') bracecount--; } } } if (bracecount || sptr==eptr || inquote || inescape || incontinuation) // not there yet... return WVTCL_GETWORD_NONE; //printf("len=%d, unget=%d\n", eptr - sptr, origend - eptr); if (end) *end = eptr - s; if (do_unescape) return wvtcl_unescape(dst, sptr, eptr-sptr); else { if (dst) memcpy(dst, sptr, eptr-sptr); return eptr - sptr; } } WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars, bool do_unescape) { int origsize = buf.used(); const char *origptr = (const char *)buf.get(origsize); size_t end; size_t len = wvtcl_getword(NULL, origptr, origsize, splitchars, do_unescape, &end); if (len == WVTCL_GETWORD_NONE) { buf.unget(origsize); return WvString::null; } WvString result; result.setsize(len+1); char *e = result.edit(); e += wvtcl_getword(e, origptr, origsize, splitchars, do_unescape); *e = '\0'; buf.unget(origsize - end); return result; } void wvtcl_decode(WvList &l, WvStringParm _s, const WvStringMask &splitchars, bool do_unescape) { const char *s = _s; size_t s_len = _s.len(); for (;;) { size_t end; size_t len = wvtcl_getword(NULL, s, s_len, splitchars, do_unescape, &end); if (len == WVTCL_GETWORD_NONE) break; WvString *word = new WvString(); word->setsize(len+1); char *e = word->edit(); e += wvtcl_getword(e, s, s_len, splitchars, do_unescape); *e = '\0'; l.append(word, true); s += end; s_len -= end; } } wvstreams-4.6.1/utils/wvbufferstore.cc0000644000175000001440000007245711036722347017170 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Defines basic buffer storage classes. * These are not intended for use directly by clients. * See "wvbufbase.h" for the public API. */ #include "wvbufstore.h" #include #include /** * An abstraction for memory transfer operations. * * This is in preparation for supporting buffers of full-blown * objects that have special copy and destruction semantics, * someday... */ struct MemOps { /** Copies initialized region to uninitialized region. */ inline void uninit_copy(void *target, const void *source, size_t count) { memcpy(target, source, count); } /** Copies initialized region to initialized region. */ inline void copy(void *target, const void *source, size_t count) { uninit(target, count); memcpy(target, source, count); } /** * Moves initialized region to uninitialized region. * Source data becomes uninitialized. */ inline void uninit_move(void *target, void *source, size_t count) { memmove(target, source, count); uninit(source, count); } /** Swaps initialized regions. */ inline void swap(void *target, void *source, size_t count) { register unsigned char *t1 = (unsigned char*)target; register unsigned char *t2 = (unsigned char*)source; while (count-- > 0) { register unsigned char temp; temp = *t1; *(t1++) = *t2; *(t2++) = temp; } } /** Uninitializes a region. */ inline void uninit(void *target, size_t count) { } /** Creates a new array. */ inline void *newarray(size_t count) { return new unsigned char[count]; } /** Deletes an uninitialized array. */ inline void deletearray(void *buf) { deletev (unsigned char*)buf; } } memops; /** Rounds the value up to the specified boundary. */ inline size_t roundup(size_t value, size_t boundary) { size_t mod = value % boundary; return mod ? value + boundary - mod : value; } /***** WvBufStore *****/ WvBufStore::WvBufStore(int _granularity) : granularity(_granularity) { } size_t WvBufStore::peekable(int offset) const { if (offset == 0) { return used(); } else if (offset < 0) { if (size_t(-offset) <= ungettable()) return size_t(-offset) + used(); } else { int avail = int(used()) - offset; if (avail > 0) return avail; } return 0; // out-of-bounds } void WvBufStore::move(void *buf, size_t count) { while (count > 0) { size_t amount = count; assert(amount != 0 || !"attempted to move() more than used()"); if (amount > count) amount = count; const void *data = get(amount); memops.uninit_copy(buf, data, amount); buf = (unsigned char*)buf + amount; count -= amount; } } void WvBufStore::copy(void *buf, int offset, size_t count) { while (count > 0) { size_t amount = optpeekable(offset); assert(amount != 0 || !"attempted to copy() with invalid offset"); if (amount > count) amount = count; const void *data = peek(offset, amount); memops.uninit_copy(buf, data, amount); buf = (unsigned char*)buf + amount; count -= amount; offset += amount; } } void WvBufStore::put(const void *data, size_t count) { while (count > 0) { size_t amount = optallocable(); assert(amount != 0 || !"attempted to put() more than free()"); if (amount > count) amount = count; void *buf = alloc(amount); memops.uninit_copy(buf, data, amount); data = (const unsigned char*)data + amount; count -= amount; } } void WvBufStore::fastput(const void *data, size_t count) { void *buf = alloc(count); memops.uninit_copy(buf, data, count); } void WvBufStore::poke(const void *data, int offset, size_t count) { int limit = int(used()); assert(offset <= limit || !"attempted to poke() beyond end of buffer"); int end = offset + count; if (end >= limit) { size_t tail = end - limit; count -= tail; put((const unsigned char*)data + count, tail); } while (count > 0) { size_t amount = optpeekable(offset); assert(amount != 0 || !"attempted to poke() with invalid offset"); if (amount > count) amount = count; void *buf = mutablepeek(offset, amount); memops.copy(buf, data, amount); data = (const unsigned char*)data + amount; count -= amount; offset += amount; } } void WvBufStore::merge(WvBufStore &instore, size_t count) { if (count == 0) return; if (usessubbuffers() && instore.usessubbuffers()) { // merge quickly by stealing subbuffers from the other buffer for (;;) { WvBufStore *buf = instore.firstsubbuffer(); if (! buf) break; // strange! size_t avail = buf->used(); if (avail > count) break; // move the entire buffer bool autofree = instore.unlinksubbuffer(buf, false); appendsubbuffer(buf, autofree); count -= avail; if (count == 0) return; } } // merge slowly by copying data basicmerge(instore, count); } void WvBufStore::basicmerge(WvBufStore &instore, size_t count) { // move bytes as efficiently as we can using only the public API if (count == 0) return; const void *indata = NULL; void *outdata = NULL; size_t inavail = 0; size_t outavail = 0; for (;;) { if (inavail == 0) { inavail = instore.optgettable(); assert(inavail != 0 || !"attempted to merge() more than instore.used()"); if (inavail > count) inavail = count; indata = instore.get(inavail); } if (outavail == 0) { outavail = optallocable(); assert(outavail != 0 || !"attempted to merge() more than free()"); if (outavail > count) outavail = count; outdata = alloc(outavail); } if (inavail < outavail) { memops.uninit_copy(outdata, indata, inavail); count -= inavail; outavail -= inavail; if (count == 0) { unalloc(outavail); return; } outdata = (unsigned char*)outdata + inavail; inavail = 0; } else { memops.uninit_copy(outdata, indata, outavail); count -= outavail; if (count == 0) return; inavail -= outavail; indata = (const unsigned char*)indata + outavail; outavail = 0; } } } /***** WvInPlaceBufStore *****/ WvInPlaceBufStore::WvInPlaceBufStore(int _granularity, void *_data, size_t _avail, size_t _size, bool _autofree) : WvBufStore(_granularity), data(NULL) { reset(_data, _avail, _size, _autofree); } WvInPlaceBufStore::WvInPlaceBufStore(int _granularity, size_t _size) : WvBufStore(_granularity), data(NULL) { reset(memops.newarray(_size), 0, _size, true); } WvInPlaceBufStore::~WvInPlaceBufStore() { if (data && xautofree) memops.deletearray(data); } void WvInPlaceBufStore::reset(void *_data, size_t _avail, size_t _size, bool _autofree = false) { assert(_data != NULL || _avail == 0); if (data && _data != data && xautofree) memops.deletearray(data); data = _data; xautofree = _autofree; xsize = _size; setavail(_avail); } void WvInPlaceBufStore::setavail(size_t _avail) { assert(_avail <= xsize); readidx = 0; writeidx = _avail; } size_t WvInPlaceBufStore::used() const { return writeidx - readidx; } const void *WvInPlaceBufStore::get(size_t count) { assert(count <= writeidx - readidx || !"attempted to get() more than used()"); const void *tmpptr = (const unsigned char*)data + readidx; readidx += count; return tmpptr; } void WvInPlaceBufStore::unget(size_t count) { assert(count <= readidx || !"attempted to unget() more than ungettable()"); readidx -= count; } size_t WvInPlaceBufStore::ungettable() const { return readidx; } void WvInPlaceBufStore::zap() { readidx = writeidx = 0; } size_t WvInPlaceBufStore::free() const { return xsize - writeidx; } void *WvInPlaceBufStore::alloc(size_t count) { assert(count <= xsize - writeidx || !"attempted to alloc() more than free()"); void *tmpptr = (unsigned char*)data + writeidx; writeidx += count; return tmpptr; } void WvInPlaceBufStore::unalloc(size_t count) { assert(count <= writeidx - readidx || !"attempted to unalloc() more than unallocable()"); writeidx -= count; } size_t WvInPlaceBufStore::unallocable() const { return writeidx - readidx; } void *WvInPlaceBufStore::mutablepeek(int offset, size_t count) { if (count == 0) return NULL; assert(((offset <= 0) ? size_t(-offset) <= readidx : size_t(offset) < writeidx - readidx) || ! "attempted to peek() with invalid offset or count"); return (unsigned char*)data + readidx + offset; } /***** WvConstInPlaceBufStore *****/ WvConstInPlaceBufStore::WvConstInPlaceBufStore(int _granularity, const void *_data, size_t _avail) : WvReadOnlyBufferStoreMixin(_granularity), data(NULL) { reset(_data, _avail); } void WvConstInPlaceBufStore::reset(const void *_data, size_t _avail) { assert(_data != NULL || _avail == 0); data = _data; setavail(_avail); } size_t WvConstInPlaceBufStore::used() const { return avail - readidx; } void WvConstInPlaceBufStore::setavail(size_t _avail) { avail = _avail; readidx = 0; } const void *WvConstInPlaceBufStore::get(size_t count) { assert(count <= avail - readidx || ! "attempted to get() more than used()"); const void *ptr = (const unsigned char*)data + readidx; readidx += count; return ptr; } void WvConstInPlaceBufStore::unget(size_t count) { assert(count <= readidx || ! "attempted to unget() more than ungettable()"); readidx -= count; } size_t WvConstInPlaceBufStore::ungettable() const { return readidx; } const void *WvConstInPlaceBufStore::peek(int offset, size_t count) { if (count == 0) return NULL; assert(((offset <= 0) ? size_t(-offset) <= readidx : size_t(offset) < avail - readidx) || ! "attempted to peek() with invalid offset or count"); return (const unsigned char*)data + readidx + offset; } void WvConstInPlaceBufStore::zap() { readidx = avail = 0; } /***** WvCircularBufStore *****/ WvCircularBufStore::WvCircularBufStore(int _granularity, void *_data, size_t _avail, size_t _size, bool _autofree) : WvBufStore(_granularity), data(NULL) { reset(_data, _avail, _size, _autofree); } WvCircularBufStore::WvCircularBufStore(int _granularity, size_t _size) : WvBufStore(_granularity), data(NULL) { reset(memops.newarray(_size), 0, _size, true); } WvCircularBufStore::~WvCircularBufStore() { if (data && xautofree) memops.deletearray(data); } void WvCircularBufStore::reset(void *_data, size_t _avail, size_t _size, bool _autofree = false) { assert(_data != NULL || _avail == 0); if (data && _data != data && xautofree) memops.deletearray(data); data = _data; xautofree = _autofree; xsize = _size; setavail(_avail); } void WvCircularBufStore::setavail(size_t _avail) { assert(_avail <= xsize); head = 0; totalused = totalinit = _avail; } size_t WvCircularBufStore::used() const { return totalused; } size_t WvCircularBufStore::optgettable() const { size_t avail = xsize - head; if (avail > totalused) avail = totalused; return avail; } const void *WvCircularBufStore::get(size_t count) { assert(count <= totalused || ! "attempted to get() more than used()"); size_t first = ensurecontiguous(0, count, false /*keephistory*/); const void *tmpptr = (const unsigned char*)data + first; head = (head + count) % xsize; totalused -= count; return tmpptr; } void WvCircularBufStore::unget(size_t count) { assert(count <= totalinit - totalused || !"attempted to unget() more than ungettable()"); head = (head + xsize - count) % xsize; totalused += count; } size_t WvCircularBufStore::ungettable() const { return totalinit - totalused; } void WvCircularBufStore::zap() { head = 0; totalused = totalinit = 0; } size_t WvCircularBufStore::free() const { return xsize - totalused; } size_t WvCircularBufStore::optallocable() const { size_t tail = head + totalused; if (tail >= xsize) return xsize - totalused; return xsize - tail; } void *WvCircularBufStore::alloc(size_t count) { assert(count <= xsize - totalused || !"attempted to alloc() more than free()"); totalinit = totalused; // always discard history size_t first = ensurecontiguous(totalused, count, false /*keephistory*/); void *tmpptr = (unsigned char*)data + first; totalused += count; totalinit += count; return tmpptr; } void WvCircularBufStore::unalloc(size_t count) { assert(count <= totalused || !"attempted to unalloc() more than unallocable()"); totalused -= count; totalinit -= count; } size_t WvCircularBufStore::unallocable() const { return totalused; } void *WvCircularBufStore::mutablepeek(int offset, size_t count) { if (count == 0) return NULL; assert(((offset <= 0) ? size_t(-offset) <= totalinit - totalused : size_t(offset) < totalused) || ! "attempted to peek() with invalid offset or count"); size_t first = ensurecontiguous(offset, count, true /*keephistory*/); void *tmpptr = (unsigned char*)data + first; return tmpptr; } void WvCircularBufStore::normalize() { // discard history to minimize data transfers totalinit = totalused; // normalize the buffer compact(data, xsize, head, totalused); head = 0; } size_t WvCircularBufStore::ensurecontiguous(int offset, size_t count, bool keephistory) { // determine the region of interest size_t start = (head + offset + xsize) % xsize; if (count != 0) { size_t end = start + count; if (end > xsize) { // the region is not entirely contiguous // determine the region that must be normalized size_t keepstart = head; if (keephistory) { // adjust the region to include history keepstart += totalused - totalinit + xsize; } else { // discard history to minimize data transfers totalinit = totalused; } keepstart %= xsize; // normalize the buffer over this region compact(data, xsize, keepstart, totalinit); head = totalinit - totalused; // compute the new start offset start = (head + offset + xsize) % xsize; } } return start; } void WvCircularBufStore::compact(void *data, size_t size, size_t head, size_t count) { if (count == 0) { // Case 1: Empty region // Requires 0 moves return; } if (head + count <= size) { // Case 2: Contiguous region // Requires count moves memops.uninit_move(data, (unsigned char*)data + head, count); return; } size_t headcount = size - head; size_t tailcount = count - headcount; size_t freecount = size - count; if (freecount >= headcount) { // Case 3: Non-contiguous region, does not require swapping // Requires count moves memops.uninit_move((unsigned char*)data + headcount, data, tailcount); memops.uninit_move(data, (unsigned char*)data + head, headcount); return; } // Case 4: Non-contiguous region, requires swapping // Requires count * 2 moves unsigned char *start = (unsigned char*)data; unsigned char *end = (unsigned char*)data + head; while (tailcount >= headcount) { memops.swap(start, end, headcount); start += headcount; tailcount -= headcount; } // Now the array looks like: |a|b|c|g|h|_|d|e|f| // FIXME: this is an interim solution void *buf = memops.newarray(tailcount); memops.uninit_move(buf, start, tailcount); memops.uninit_move(start, end, headcount); memops.uninit_move(start + headcount, buf, tailcount); memops.deletearray(buf); } /***** WvLinkedBufferStore *****/ WvLinkedBufferStore::WvLinkedBufferStore(int _granularity) : WvBufStore(_granularity), totalused(0), maxungettable(0) { } bool WvLinkedBufferStore::usessubbuffers() const { return true; } size_t WvLinkedBufferStore::numsubbuffers() const { return list.count(); } WvBufStore *WvLinkedBufferStore::firstsubbuffer() const { return list.first(); } void WvLinkedBufferStore::appendsubbuffer(WvBufStore *buffer, bool autofree) { list.append(buffer, autofree); totalused += buffer->used(); } void WvLinkedBufferStore::prependsubbuffer(WvBufStore *buffer, bool autofree) { list.prepend(buffer, autofree); totalused += buffer->used(); maxungettable = 0; } bool WvLinkedBufferStore::unlinksubbuffer(WvBufStore *buffer, bool allowautofree) { WvBufStoreList::Iter it(list); WvLink *link = it.find(buffer); assert(link); bool autofree = it.get_autofree(); totalused -= buffer->used(); if (buffer == list.first()) maxungettable = 0; if (! allowautofree) it.set_autofree(false); it.unlink(); // do not recycle the buffer return autofree; } size_t WvLinkedBufferStore::used() const { assert(!totalused || !list.isempty()); return totalused; } size_t WvLinkedBufferStore::optgettable() const { // find the first buffer with an optgettable() and return that size_t count; WvBufStoreList::Iter it(list); for (it.rewind(); it.next(); ) if ((count = it->optgettable()) != 0) return count; return 0; } const void *WvLinkedBufferStore::get(size_t count) { assert(!totalused || !list.isempty()); if (count == 0) return NULL; assert(count <= totalused); assert(count > 0); totalused -= count; assert(totalused >= 0); // search for first non-empty buffer WvBufStore *buf; size_t availused; WvBufStoreList::Iter it(list); for (;;) { it.rewind(); it.next(); buf = it.ptr(); assert(buf && "attempted to get() more than used()" && "totalused is wrong!"); availused = buf->used(); if (availused != 0) break; // unlink the leading empty buffer do_xunlink(it); } // return the data if (availused < count) buf = coalesce(it, count); maxungettable += count; return buf->get(count); } void WvLinkedBufferStore::unget(size_t count) { assert(!totalused || !list.isempty()); if (count == 0) return; assert(count > 0); assert(!list.isempty()); assert(count <= maxungettable); totalused += count; maxungettable -= count; list.first()->unget(count); } size_t WvLinkedBufferStore::ungettable() const { assert(!totalused || !list.isempty()); if (list.isempty()) { assert(maxungettable == 0); return 0; } // maxungettable and list.first()->ungettable() can get out of sync in two ways: // - coalescing moves data from later buffers to the first one, which // leaves it as ungettable in those buffers. So when we first start to // use a buffer, its ungettable() count may be too high. (This is the // reason maxungettable exists.) // - some calls (ie. alloc) may clear all ungettable data from the first // buffer without telling us. So there might be less data to unget than we // think. size_t avail = list.first()->ungettable(); if (avail > maxungettable) avail = maxungettable; return avail; } void WvLinkedBufferStore::zap() { totalused = 0; maxungettable = 0; WvBufStoreList::Iter it(list); for (it.rewind(); it.next(); ) do_xunlink(it); } size_t WvLinkedBufferStore::free() const { if (!list.isempty()) return list.last()->free(); return 0; } size_t WvLinkedBufferStore::optallocable() const { if (!list.isempty()) return list.last()->optallocable(); return 0; } void *WvLinkedBufferStore::alloc(size_t count) { if (count == 0) return NULL; assert(!list.isempty() && "attempted to alloc() more than free()"); totalused += count; return list.last()->alloc(count); } void WvLinkedBufferStore::unalloc(size_t count) { assert(count <= totalused); totalused -= count; while (count > 0) { assert(!list.isempty() && "attempted to unalloc() more than unallocable()" && "totalused is wrong"); WvBufStore *buf = list.last(); size_t avail = buf->unallocable(); if (count < avail) { buf->unalloc(count); break; } WvBufStoreList::Iter it(list); it.find(buf); do_xunlink(it); count -= avail; } } size_t WvLinkedBufferStore::unallocable() const { return totalused; } size_t WvLinkedBufferStore::optpeekable(int offset) const { // search for the buffer that contains the offset WvBufStoreList::Iter it(list); int newoffset = search(it, offset); WvBufStore *buf = it.ptr(); if (!buf) return 0; // out of bounds return buf->optpeekable(newoffset); } void *WvLinkedBufferStore::mutablepeek(int offset, size_t count) { if (count == 0) return NULL; // search for the buffer that contains the offset WvBufStoreList::Iter it(list); offset = search(it, offset); WvBufStore *buf = it.ptr(); assert(buf && "attempted to peek() with invalid offset or count"); // return data if we have enough size_t availpeek = buf->peekable(offset); if (availpeek < count) buf = coalesce(it, count); return buf->mutablepeek(offset, count); } WvBufStore *WvLinkedBufferStore::newbuffer(size_t minsize) { minsize = roundup(minsize, granularity); //return new WvInPlaceBufStore(granularity, minsize); return new WvCircularBufStore(granularity, minsize); } void WvLinkedBufferStore::recyclebuffer(WvBufStore *buffer) { delete buffer; } int WvLinkedBufferStore::search(WvBufStoreList::Iter &it, int offset) const { it.rewind(); if (it.next()) { if (offset < 0) { // inside unget() region WvBufStore *buf = it.ptr(); if (size_t(-offset) <= buf->ungettable()) return offset; it.rewind(); // mark out of bounds } else { // inside get() region do { WvBufStore *buf = it.ptr(); size_t avail = buf->used(); if (size_t(offset) < avail) return offset; offset -= avail; } while (it.next()); } } return 0; } WvBufStore *WvLinkedBufferStore::coalesce(WvBufStoreList::Iter &it, size_t count) { WvBufStore *buf = it.ptr(); size_t availused = buf->used(); if (count <= availused) return buf; // allocate a new buffer if there is not enough room to coalesce size_t needed = count - availused; size_t availfree = buf->free(); size_t mustskip = 0; if (availfree < needed) { // if this is the first buffer, then we need to unget as // much as possible to ensure it does not get discarded // during the coalescing phase if (buf == list.first() && totalused != 0) { // use ungettable() instead of buf->ungettable() because we might // have reset it to 0 // FIXME: uh... who might have reset it to 0, and why? mustskip = ungettable(); buf->unget(mustskip); } needed = count + mustskip; buf = newbuffer(needed); // insert the buffer before the previous link list.add_after(it.prev, buf, true); it.find(buf); } // coalesce subsequent buffers into the first while (it.next()) { WvBufStore *itbuf = it.ptr(); size_t chunk = itbuf->used(); if (chunk > 0) { if (chunk > needed) chunk = needed; buf->merge(*itbuf, chunk); needed -= chunk; if (needed == 0) { buf->skip(mustskip); return buf; } } do_xunlink(it); // buffer is now empty } assert(false && "invalid count during get() or peek()"); return NULL; } void WvLinkedBufferStore::do_xunlink(WvBufStoreList::Iter &it) { WvBufStore *buf = it.ptr(); if (buf == list.first()) maxungettable = 0; bool autofree = it.get_autofree(); it.set_autofree(false); it.xunlink(); if (autofree) recyclebuffer(buf); } /***** WvDynBufStore *****/ WvDynBufStore::WvDynBufStore(size_t _granularity, size_t _minalloc, size_t _maxalloc) : WvLinkedBufferStore(_granularity), minalloc(_minalloc), maxalloc(_maxalloc) { assert(maxalloc >= minalloc); } size_t WvDynBufStore::free() const { return UNLIMITED_FREE_SPACE; } size_t WvDynBufStore::optallocable() const { size_t avail = WvLinkedBufferStore::optallocable(); if (avail == 0) avail = UNLIMITED_FREE_SPACE; return avail; } void *WvDynBufStore::alloc(size_t count) { if (count > WvLinkedBufferStore::free()) { WvBufStore *buf = newbuffer(count); appendsubbuffer(buf, true); } return WvLinkedBufferStore::alloc(count); } WvBufStore *WvDynBufStore::newbuffer(size_t minsize) { // allocate a new buffer // try to approximate exponential growth by at least doubling // the amount of space available for immediate use size_t size = used(); if (size < minsize * 2) size = minsize * 2; if (size < minalloc) size = minalloc; else if (size > maxalloc) size = maxalloc; if (size < minsize) size = minsize; return WvLinkedBufferStore::newbuffer(size); } /***** WvNullBufStore *****/ WvNullBufStore::WvNullBufStore(size_t _granularity) : WvWriteOnlyBufferStoreMixin< WvReadOnlyBufferStoreMixin >(_granularity) { } /***** WvBufCursorStore *****/ WvBufCursorStore::WvBufCursorStore(size_t _granularity, WvBufStore *_buf, int _start, size_t _length) : WvReadOnlyBufferStoreMixin(_granularity), buf(_buf), start(_start), length(_length), shift(0) { } bool WvBufCursorStore::isreadable() const { return buf->isreadable(); } size_t WvBufCursorStore::used() const { return length - shift; } size_t WvBufCursorStore::optgettable() const { size_t avail = buf->optpeekable(start + shift); assert(avail != 0 || length == shift || ! "buffer cursor operating over invalid region"); if (avail > length) avail = length; return avail; } const void *WvBufCursorStore::get(size_t count) { assert(count <= length - shift || ! "attempted to get() more than used()"); const void *data = buf->peek(start + shift, count); shift += count; return data; } void WvBufCursorStore::skip(size_t count) { assert(count <= length - shift || ! "attempted to skip() more than used()"); shift += count; } void WvBufCursorStore::unget(size_t count) { assert(count <= shift || ! "attempted to unget() more than ungettable()"); shift -= count; } size_t WvBufCursorStore::ungettable() const { return shift; } void WvBufCursorStore::zap() { shift = length; } size_t WvBufCursorStore::peekable(int offset) const { offset += shift; offset -= start; if (offset < 0 || offset > int(length)) return 0; return length - size_t(offset); } size_t WvBufCursorStore::optpeekable(int offset) const { size_t avail = buf->optpeekable(start + shift + offset); assert(avail != 0 || length == shift || ! "buffer cursor operating over invalid region"); size_t max = peekable(offset); if (avail > max) avail = max; return avail; } const void *WvBufCursorStore::peek(int offset, size_t count) { offset += shift; assert((offset >= start && offset - start + count <= length) || ! "attempted to peek() with invalid offset or count"); return buf->peek(offset, count); } bool WvBufCursorStore::iswritable() const { // check if mutablepeek() is supported return buf->iswritable(); } void *WvBufCursorStore::mutablepeek(int offset, size_t count) { offset += shift; assert((offset >= start && offset - start + count <= length) || ! "attempted to peek() with invalid offset or count"); return buf->mutablepeek(offset, count); } wvstreams-4.6.1/utils/wvsubprocqueue.cc0000644000175000001440000000606111036722347017350 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A way to enqueue a series of WvSubProc objects. See wvsubprocqueue.h. */ #include "wvsubprocqueue.h" #include #include WvSubProcQueue::WvSubProcQueue(unsigned _maxrunning) { maxrunning = _maxrunning; } WvSubProcQueue::~WvSubProcQueue() { } void WvSubProcQueue::add(void *cookie, WvSubProc *proc) { assert(proc); assert(!proc->running); if (cookie) { // search for other enqueued objects with this cookie EntList::Iter i(waitq); for (i.rewind(); i.next(); ) { if (i->cookie == cookie) { // already enqueued; mark it as "redo" unless it's already // the last one. That way we guarantee it'll still run // in the future from now, and it'll come later than anything // else in the queue, but it won't pointlessly run twice at // the end. Ent *e = i.ptr(); if (i.next()) e->redo = true; delete proc; return; } } } waitq.append(new Ent(cookie, proc), true); } void WvSubProcQueue::add(void *cookie, const char *cmd, const char * const *argv) { WvSubProc *p = new WvSubProc; p->preparev(cmd, argv); add(cookie, p); } bool WvSubProcQueue::cookie_running() { EntList::Iter i(runq); for (i.rewind(); i.next(); ) if (i->cookie) return true; return false; } int WvSubProcQueue::go() { int started = 0; //fprintf(stderr, "go: %d waiting, %d running\n", // waitq.count(), runq.count()); // first we need to clean up any finished processes { EntList::Iter i(runq); for (i.rewind(); i.next(); ) { Ent *e = i.ptr(); e->proc->wait(0, true); if (!e->proc->running) { if (e->redo) { // someone re-enqueued this task while it was // waiting/running e->redo = false; i.xunlink(false); waitq.append(e, true); } else i.xunlink(); } } } while (!waitq.isempty() && runq.count() < maxrunning) { EntList::Iter i(waitq); for (i.rewind(); i.next(); ) { // elements with cookies are "sync points" in the queue; // they guarantee that everything before that point has // finished running before they run, and don't let anything // after them run until they've finished. if (i->cookie && !runq.isempty()) goto out; if (cookie_running()) goto out; // jump it into the running queue, but be careful not to // delete the object when removing! Ent *e = i.ptr(); i.xunlink(false); runq.append(e, true); e->proc->start_again(); started++; break; } } out: assert(runq.count() <= maxrunning); return started; } unsigned WvSubProcQueue::running() const { return runq.count(); } unsigned WvSubProcQueue::remaining() const { return runq.count() + waitq.count(); } bool WvSubProcQueue::isempty() const { return runq.isempty() && waitq.isempty(); } void WvSubProcQueue::finish() { while (!isempty()) { go(); if (!isempty()) usleep(100*1000); } } wvstreams-4.6.1/utils/wvdiriter.cc0000644000175000001440000001064711036722347016275 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Directory iterator. Recursively uses opendir and readdir, so you don't * have to. Basically implements 'find'. * */ #include "wvdiriter.h" #if defined(_WIN32) && !defined(S_ISDIR) #define S_ISDIR(x) (_S_IFDIR | (x)) #endif #ifdef _WIN32 #define lstat stat #endif WvDirIter::WvDirIter( WvStringParm _dirname, bool _recurse, bool _skip_mounts, size_t sizeof_stat ) : relpath(""), dir(dirs) /****************************************************************************/ { // if this assertion fails, then you probably used different compiler // options for the wvstreams library and the calling program. Check // for defines like _FILE_OFFSET_BITS=64 and _LARGEFILE_SOURCE. assert(sizeof_stat == sizeof(struct stat)); recurse = _recurse; go_up = false; skip_mounts = _skip_mounts; found_top = false; WvString dirname(_dirname); int dl = strlen(dirname); if (dl != 0 && dirname[dl-1] == '/') dirname.edit()[dl-1] = 0; DIR * d = opendir( dirname ); if( d ) { Dir * dd = new Dir( d, dirname ); dirs.prepend( dd, true ); } } WvDirIter::~WvDirIter() /*********************/ { dirs.zap(); } bool WvDirIter::isok() const /**************************/ { return( !dirs.isempty() ); } bool WvDirIter::isdir() const /***************************/ { return( S_ISDIR( info.st_mode ) ); } void WvDirIter::rewind() /**********************/ { // have to closedir() everything that isn't the one we started with, // and rewind that. while( dirs.count() > 1 ) { dir.rewind(); dir.next(); dir.unlink(); } if( isok() ) { dir.rewind(); dir.next(); rewinddir( dir->d ); } } bool WvDirIter::next() /********************/ // use readdir... and if that returns a directory, opendir() it and prepend // it to dirs, so we start reading it until it's done. { struct dirent * dent = NULL; if( !isok() ) return( false ); bool tryagain; do { bool ok = false; tryagain = false; // unrecurse if the user wants to if( go_up ) { go_up = false; if( dirs.count() > 1 ) { dir.unlink(); dir.rewind(); dir.next(); } else return( false ); } do { dent = readdir( dir->d ); if( dent ) { info.fullname = WvString( "%s/%s", dir->dirname, dent->d_name ); info.name = dent->d_name; if (relpath == "") info.relname = info.name; else info.relname = WvString("%s%s", relpath, info.name); ok = ( lstat( info.fullname, &info ) == 0 && strcmp( dent->d_name, "." ) && strcmp( dent->d_name, ".." ) ); if (ok && !found_top) { lstat(info.fullname, &topdir); topdir.fullname = info.fullname; topdir.name = info.name; topdir.relname = info.relname; found_top = true; } } } while( dent && !ok ); if( dent ) { // recurse? if( recurse && S_ISDIR( info.st_mode ) && ( !skip_mounts || info.st_dev == topdir.st_dev) ) { DIR * d = opendir( info.fullname ); if( d ) { relpath = WvString( "%s%s/", relpath, info.name ); Dir * dd = new Dir( d, info.fullname ); dirs.prepend( dd, true ); dir.rewind(); dir.next(); } } } else { // end of directory. if we recursed, unlink it and go up a // notch. if this is the top level, DON'T close it, so that // the user can ::rewind() again if he wants. if( dirs.count() > 1 ) { if (dirs.count() == 2) relpath = WvString(""); else relpath = WvString( "%s/", getdirname(relpath) ); dir.unlink(); dir.rewind(); dir.next(); tryagain = true; } } } while( tryagain ); return( dent != NULL ); } wvstreams-4.6.1/utils/wvregex.cc0000644000175000001440000000234211036722347015736 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Implementation of regular expression support though libc */ #include "wvregex.h" WvString WvRegex::__wvre_null_reg; const int WvRegex::default_cflags = WvRegex::EXTENDED; const int WvRegex::default_eflags = 0; void WvRegex::seterr(int errcode) { int error_desc_len = ::regerror(errcode, &preg, NULL, 0); if (error_desc_len > 0) { WvString error_desc; error_desc.setsize(error_desc_len); ::regerror(errcode, &preg, error_desc.edit(), error_desc_len); WvErrorBase::seterr_both(errcode, error_desc); } else WvErrorBase::seterr(errcode); } bool WvRegex::set(WvStringParm regex, int cflags) { if (have_preg) ::regfree(&preg); int errcode = ::regcomp(&preg, regex, cflags); if (errcode) { seterr(errcode); have_preg = false; } else have_preg = true; return have_preg; } WvRegex::~WvRegex() { if (have_preg) ::regfree(&preg); } bool WvRegex::match(WvStringParm string, int eflags, size_t nmatch, regmatch_t pmatch[]) const { if (!have_preg) return false; return ::regexec(&preg, string, nmatch, pmatch, eflags) == 0; } wvstreams-4.6.1/utils/strutils.cc0000644000175000001440000007373411253746065016161 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Various useful string-based utilities. * */ #include "strutils.h" #include "wvbuf.h" #include #include #include #include #include #ifndef _WIN32 //#include #include #include #include #else #undef errno #define errno GetLastError() #define strcasecmp _stricmp #include #include #ifndef EACCES #define EACCES 0xfff #endif #endif char *terminate_string(char *string, char c) /**********************************************/ // Add character c to the end of a string after removing crlf's. // NOTE: You need a buffer that's at least one character bigger than the // current length of the string, including the terminating NULL. { char *p; if (string == NULL) return NULL; p = string + strlen(string) - 1; while (p >= string) { if (*p == '\r' || *p == '\n') --p; else break; } *(++p) = c; *(++p) = 0; return string; } char *trim_string(char *string) /*********************************/ // Trims spaces off the front and end of strings. Modifies the string. // Specifically DOES allow string==NULL; returns NULL in that case. { char *p; char *q; if (string == NULL) return NULL; p = string; q = string + strlen(string) - 1; while (q >= p && isspace(*q)) *(q--) = 0; while (isspace(*p)) p++; return p; } char *trim_string(char *string, char c) // Searches the string for c and removes it plus everything afterwards. // Modifies the string and returns NULL if string == NULL. { char *p; if (string == NULL) return NULL; p = string; while (*p != 0 && *p != c) p++; while (*p) *(p++) = 0; return string; } // return the string formed by concatenating string 'a' and string 'b' with // the 'sep' character between them. For example, // spacecat("xx", "yy", ";") // returns "xx;yy", and // spacecat("xx;;", "yy", ";") // returns "xx;;;yy", and // spacecat("xx;;", "yy", ";", true) // returns "xx;yy". // // This function is much faster than the more obvious WvString("%s;%s", a, b), // so it's useful when you're producing a *lot* of string data. WvString spacecat(WvStringParm a, WvStringParm b, char sep, bool onesep) { size_t alen = strlen(a); size_t blen = strlen(b); // If we only want one separator, eat away at the back of string a if (onesep && alen) { while (a[alen-1] == sep) --alen; } // Create the destination string, and give it an appropriate size. // Then, fill it with string a. WvString s; s.setsize(alen + blen + 2); char *cptr = s.edit(); memcpy(cptr, a, alen); // Write the separator in the appropriate spot. cptr[alen] = sep; // If we only want one separator, eat away at the from of string b. size_t boffset = 0; if (onesep) { while (b[boffset] == sep) ++boffset; } // Now copy the second half of the string in and terminate with a NUL. memcpy(cptr+alen+1, b.cstr()+boffset, blen-boffset); cptr[alen+1+blen-boffset] = 0; return s; } // Replaces whitespace characters with nonbreaking spaces. char *non_breaking(const char * string) { if (string == NULL) return (NULL); WvDynBuf buf; while (*string) { if (isspace(*string)) buf.putstr(" "); else buf.putch(*string); string++; } WvString s(buf.getstr()); char *nbstr = new char[s.len() + 1]; return strcpy(nbstr, s.edit()); } // Searches _string (up to length bytes), replacing any occurrences of c1 // with c2. void replace_char(void *_string, char c1, char c2, int length) { char *string = (char *)_string; for (int i=0; i < length; i++) if (*(string+i) == c1) *(string+i) = c2; } // Snip off the first part of 'haystack' if it consists of 'needle'. char *snip_string(char *haystack, char *needle) { if(!haystack) return NULL; if(!needle) return haystack; char *p = strstr(haystack, needle); if(!p || p != haystack) return haystack; else return haystack + strlen(needle); } char *strlwr(char *string) { char *p = string; while (p && *p) { *p = tolower(*p); p++; } return string; } char *strupr(char *string) { char *p = string; while (p && *p) { *p = toupper(*p); p++; } return string; } // true if all the characters in "string" are isalnum(). bool is_word(const char *p) { assert(p); while (*p) { if(!isalnum(*p++)) return false; } return true; } // produce a hexadecimal dump of the data buffer in 'buf' of length 'len'. // it is formatted with 16 bytes per line; each line has an address offset, // hex representation, and printable representation. WvString hexdump_buffer(const void *_buf, size_t len, bool charRep) { const unsigned char *buf = (const unsigned char *)_buf; size_t count, count2, top; WvString out; out.setsize(len / 16 * 80 + 80); char *cptr = out.edit(); for (count = 0; count < len; count+=16) { top = len-count < 16 ? len-count : 16; cptr += sprintf(cptr, "[%03X] ", (unsigned int)count); // dump hex values for (count2 = 0; count2 < top; count2++) { if (count2 && !(count2 % 4)) *cptr++ = ' '; cptr += sprintf(cptr, "%02X", buf[count+count2]); } // print horizontal separation for (count2 = top; count2 < 16; count2++) { if (count2 && !(count2 % 4)) { strcat(cptr, " "); cptr += 3; } else { strcat(cptr, " "); cptr += 2; } } *cptr++ = ' '; // dump character representation if (charRep) { for (count2 = 0; count2 < top; count2++) { if (!(count2 % 4)) *cptr++ = ' '; *cptr++ = (isprint(buf[count+count2]) ? buf[count+count2] : '.'); } } *cptr++ = '\n'; } *cptr = 0; return out; } // return true if the character is a newline. bool isnewline(char c) { return c=='\n' || c=='\r'; } // ex: WvString foo = url_decode("I+am+text.%0D%0A"); WvString url_decode(WvStringParm str, bool no_space) { if (!str) return str; const char *iptr; char *optr; const char *idx1, *idx2; static const char hex[] = "0123456789ABCDEF"; WvString in, intmp(str), out; in = trim_string(intmp.edit()); out.setsize(strlen(in) + 1); optr = out.edit(); for (iptr = in, optr = out.edit(); *iptr; iptr++) { if (*iptr == '+' && !no_space) *optr++ = ' '; else if (*iptr == '%' && iptr[1] && iptr[2]) { idx1 = strchr(hex, toupper((unsigned char) iptr[1])); idx2 = strchr(hex, toupper((unsigned char) iptr[2])); if (idx1 && idx2) *optr++ = ((idx1 - hex) << 4) | (idx2 - hex); iptr += 2; } else *optr++ = *iptr; } *optr = 0; return out; } // And its magic companion: url_encode WvString url_encode(WvStringParm str, WvStringParm unsafe) { unsigned int i; WvDynBuf retval; for (i=0; i < str.len(); i++) { if (((!!unsafe && !strchr(unsafe, str[i])) || (!unsafe && (isalnum(str[i]) || strchr("_.!~*'()-", str[i])))) && str[i] != '%') { retval.put(&str[i], 1); } else { char buf[4]; sprintf(buf, "%%%02X", str[i] & 0xff); retval.put(&buf, 3); } } return retval.getstr(); } WvString diff_dates(time_t t1, time_t t2) { char out[25]; //Should be more then enough double diff = difftime(t1, t2); if(diff < 0) diff = -diff; if(diff > (60 * 60 * 24)) //give a touch more granularity then the rest sprintf(out, "%.1f day(s)", diff / (60 * 60 * 24)); else if(diff > (60 * 60)) sprintf(out, "%.0f hour(s)", diff / (60 * 60)); else if(diff > 60) sprintf(out, "%.0f minute(s)", diff / 60); else sprintf(out, "%.0f second(s)", diff); return out; } WvString rfc822_date(time_t when) { WvString out; out.setsize(80); if (when < 0) when = time(NULL); struct tm *tmwhen = localtime(&when); strftime(out.edit(), 80, "%a, %d %b %Y %H:%M:%S %z", tmwhen); return out; } WvString backslash_escape(WvStringParm s1) { // stick a backslash in front of every !isalnum() character in s1 if (!s1) return ""; WvString s2; s2.setsize(s1.len() * 2 + 1); const char *p1 = s1; char *p2 = s2.edit(); while (*p1) { if (!isalnum(*p1)) *p2++ = '\\'; *p2++ = *p1++; } *p2 = 0; return s2; } int strcount(WvStringParm s, const char c) { int n=0; const char *p = s; while ((p=strchr(p, c)) != NULL && p++) n++; return n; } WvString encode_hostname_as_DN(WvStringParm hostname) { WvString dn(""); WvStringList fqdnlist; WvStringList::Iter i(fqdnlist); fqdnlist.split(hostname, "."); for (i.rewind(); i.next(); ) dn.append("dc=%s,", *i); dn.append("cn=%s", hostname); return dn; } WvString nice_hostname(WvStringParm name) { WvString nice; char *optr, *optr_start; const char *iptr; bool last_was_dash; nice.setsize(name.len() + 2); iptr = name; optr = optr_start = nice.edit(); if (!isascii(*iptr) || !isalnum(*(const unsigned char *)iptr)) *optr++ = 'x'; // DNS names must start with a letter! last_was_dash = false; for (; *iptr; iptr++) { if (!isascii(*iptr)) continue; // skip it entirely if (*iptr == '-' || *iptr == '_') { if (last_was_dash) continue; last_was_dash = true; *optr++ = '-'; } else if (isalnum(*(const unsigned char *)iptr) || *iptr == '.') { *optr++ = *iptr; last_was_dash = false; } } if (optr > optr_start && !isalnum(*(const unsigned char *)(optr-1))) *optr++ = 'x'; // must _end_ in a letter/number too! *optr++ = 0; if (!nice.len()) return "UNKNOWN"; return nice; } WvString getfilename(WvStringParm fullname) { WvString tmp(fullname); char *cptr = strrchr(tmp.edit(), '/'); if (!cptr) // no slash at all return fullname; else if (!cptr[1]) // terminating slash { *cptr = 0; return getfilename(tmp); } else // no terminating slash return cptr+1; } WvString getdirname(WvStringParm fullname) { WvString tmp(fullname); char *cptr = strrchr(tmp.edit(), '/'); if (!cptr) // no slash at all return "."; else if (!cptr[1]) // terminating slash { *cptr = 0; return getdirname(tmp); } else // no terminating slash { *cptr = 0; return !tmp ? WvString("/") : tmp; } } // Programmatically determine the units. In order, these are: // bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, // exabytes, zettabytes, yottabytes. Note that these are SI // prefixes, not binary ones. // This structure allows us to choose between SI-prefixes which are // powers of 10, and IEC-prefixes which are powers of 2. struct prefix_t { const char *name; unsigned long long base; }; // SI-prefixes: // kilo, mega, giga, tera, peta, and exa. static const prefix_t si[] = { { "k", 1000ull }, { "M", 1000ull * 1000ull }, { "G", 1000ull * 1000ull * 1000ull }, { "T", 1000ull * 1000ull * 1000ull * 1000ull }, { "P", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull}, { "E", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull * 1000ull}, { "Z", 0 }, { "Y", 0 }, { NULL, 0 } }; // IEC-prefixes: // kibi, mebi, gibi, tebi, pebi, and exbi. static const prefix_t iec[] = { { "Ki", 1024ull }, { "Mi", 1024ull * 1024ull}, { "Gi", 1024ull * 1024ull * 1024ull }, { "Ti", 1024ull * 1024ull * 1024ull * 1024ull }, { "Pi", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull}, { "Ei", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull * 1024ull}, { "Zi", 0 }, { "Yi", 0 }, { NULL, 0 } }; // This function expects size to be ten-times the actual number. static inline unsigned long long _sizetoa_rounder(RoundingMethod method, unsigned long long size, unsigned long long remainder, unsigned long long base) { unsigned long long half = base / 2; unsigned long long significant_digits = size / base; switch (method) { case ROUND_DOWN: break; case ROUND_UP: if (remainder || (size % base)) ++significant_digits; break; case ROUND_UP_AT_POINT_FIVE: if ((size % base) >= half) ++significant_digits; break; case ROUND_DOWN_AT_POINT_FIVE: unsigned long long r = size % base; if ((r > half) || (remainder && (r == half))) ++significant_digits; break; } return significant_digits; } // This function helps sizetoa() and sizektoa() below. It takes a // bunch of digits, and the default unit (indexed by size); and turns // them into a WvString that's formatted to human-readable rounded // sizes, with one decimal place. // // You must be very careful here never to add anything to size. // Otherwise, you might cause an overflow to occur. Similarly, you // must be careful when you subtract or you might cause an underflow. static WvString _sizetoa(unsigned long long size, unsigned long blocksize, RoundingMethod rounding_method, const prefix_t *prefixes, WvStringParm unit) { assert(blocksize); // To understand rounding, consider the display of the value 999949. // For each rounding method the string displayed should be: // ROUND_DOWN: 999.9 kB // ROUND_UP_AT_POINT_FIVE: 999.9 kB // ROUND_UP: 1.0 MB // On the other hand, for the value 999950, the strings should be: // ROUND_DOWN: 999.9 kB // ROUND_DOWN_AT_POINT_FIVE: 999.9 kB // ROUND_UP_AT_POINT_FIVE: 1.0 MB // ROUND_UP: 1.0 MB // Deal with blocksizes without overflowing. const unsigned long long group_base = prefixes[0].base; int shift = 0; unsigned long prev_blocksize = 0; while (blocksize >= group_base) { prev_blocksize = blocksize; blocksize /= group_base; ++shift; } // If we have a very large blocksize, make sure to keep enough of // it to make rounding possible. if (prev_blocksize && prev_blocksize != group_base) { blocksize = prev_blocksize; --shift; } int p = -1; unsigned long long significant_digits = size * 10; unsigned int remainder = 0; if (significant_digits < size) { // A really big size. We'll divide by a grouping before going up one. remainder = size % group_base; size /= group_base; ++shift; } while (size >= group_base) { ++p; significant_digits = _sizetoa_rounder(rounding_method, size * 10, remainder, prefixes[p].base); if (significant_digits < (group_base * 10) || !prefixes[p + shift + 1].name) break; } // Correct for blocksizes that aren't powers of group_base. if (blocksize > 1) { significant_digits *= blocksize; while (significant_digits >= (group_base * 10) && prefixes[p + shift + 1].name) { significant_digits = _sizetoa_rounder(rounding_method, significant_digits, 0, group_base); ++p; } } // Now we can return our result. return WvString("%s.%s %s%s", significant_digits / 10, significant_digits % 10, prefixes[p + shift].name, unit); } WvString sizetoa(unsigned long long blocks, unsigned long blocksize, RoundingMethod rounding_method) { unsigned long long bytes = blocks * blocksize; // Test if we are dealing in just bytes. if (bytes < 1000 && bytes >= blocks) return WvString("%s bytes", bytes); return _sizetoa(blocks, blocksize, rounding_method, si, "B"); } WvString sizektoa(unsigned long long kbytes, RoundingMethod rounding_method) { if (kbytes < 1000) return WvString("%s kB", kbytes); return sizetoa(kbytes, 1000, rounding_method); } WvString sizeitoa(unsigned long long blocks, unsigned long blocksize, RoundingMethod rounding_method) { unsigned long long bytes = blocks * blocksize; // Test if we are dealing in just bytes. if (bytes < 1024 && bytes >= blocks) return WvString("%s bytes", bytes); return _sizetoa(blocks, blocksize, rounding_method, iec, "B"); } WvString sizekitoa(unsigned long long kbytes, RoundingMethod rounding_method) { if (kbytes < 1024) return WvString("%s KiB", kbytes); return sizeitoa(kbytes, 1024, rounding_method); } WvString secondstoa(unsigned int total_seconds) { WvString result(""); unsigned int days = total_seconds / (3600*24); total_seconds %= (3600*24); unsigned int hours = total_seconds / 3600; total_seconds %= 3600; unsigned int mins = total_seconds / 60; unsigned int secs = total_seconds % 60; int num_elements = (days > 0) + (hours > 0) + (mins > 0); if (days > 0) { result.append(days); result.append(days > 1 ? " days" : " day"); num_elements--; if (num_elements > 1) result.append(", "); else if (num_elements == 1) result.append(" and "); } if (hours > 0) { result.append(hours); result.append(hours > 1 ? " hours" : " hour"); num_elements--; if (num_elements > 1) result.append(", "); else if (num_elements == 1) result.append(" and "); } if (mins > 0) { result.append(mins); result.append(mins > 1 ? " minutes" : " minute"); } if (days == 0 && hours == 0 && mins == 0) { result.append(secs); result.append(secs != 1 ? " seconds" : " second"); } return result; } WvString strreplace(WvStringParm s, WvStringParm a, WvStringParm b) { WvDynBuf buf; const char *sptr = s, *eptr; while ((eptr = strstr(sptr, a)) != NULL) { buf.put(sptr, eptr-sptr); buf.putstr(b); sptr = eptr + strlen(a); } buf.put(sptr, strlen(sptr)); return buf.getstr(); } WvString undupe(WvStringParm s, char c) { WvDynBuf out; bool last = false; for (int i = 0; s[i] != '\0'; i++) { if (s[i] != c) { out.putch(s[i]); last = false; } else if (!last) { out.putch(c); last = true; } } return out.getstr(); } WvString rfc1123_date(time_t t) { struct tm *tm = gmtime(&t); WvString s; s.setsize(128); strftime(s.edit(), 128, "%a, %d %b %Y %H:%M:%S GMT", tm); return s; } int lookup(const char *str, const char * const *table, bool case_sensitive) { for (int i = 0; table[i]; ++i) { if (case_sensitive) { if (strcmp(str, table[i]) != 0) continue; } else { if (strcasecmp(str, table[i]) != 0) continue; } return i; } return -1; } WvString hostname() { int maxlen = 0; for (;;) { maxlen += 80; char *name = new char[maxlen]; int result = gethostname(name, maxlen); if (result == 0) { WvString hostname(name); deletev name; return hostname; } #ifdef _WIN32 assert(errno == WSAEFAULT); #else assert(errno == EINVAL); #endif } } WvString fqdomainname() { struct hostent *myhost; myhost = gethostbyname(hostname()); if (myhost) return myhost->h_name; else return WvString::null; } WvString wvgetcwd() { int maxlen = 0; for (;;) { maxlen += 80; char *name = new char[maxlen]; char *res = getcwd(name, maxlen); if (res) { WvString s(name); deletev name; return s; } if (errno == EACCES || errno == ENOENT) return "."; // can't deal with those errors assert(errno == ERANGE); // buffer too small } } WvString metriculate(const off_t i) { WvString res; int digits=0; int digit=0; long long int j=i; char *p; while (j) { digits++; j/=10; } j=i; // setsize says it takes care of the terminating NULL char res.setsize(digits + ((digits - 1) / 3) + ((j < 0) ? 1 : 0)); p = res.edit(); if (j < 0) { *p++ = '-'; j = -j; } p += digits + ((digits - 1) / 3); *p-- = '\0'; for (digit=0; digit line.len()-1) return ""; tmp += pos; WvString ret = tmp; char *tmp2 = ret.edit(); if (pos + len < line.len()) tmp2[len] = '\0'; return ret; } const CStrExtraEscape CSTR_TCLSTR_ESCAPES[3] = { { '{', "\\<" }, { '}', "\\>" }, { 0, NULL } }; static inline const char *cstr_escape_char(char ch) { static const char *xlat[256] = { "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a", "\\b", "\\t", "\\n", "\\v", "\\x0C", "\\r", "\\x0E", "\\x0F", "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17", "\\x18", "\\x19", "\\x1A", "\\x1B", "\\x1C", "\\x1D", "\\x1E", "\\x1F", " ", "!", "\\\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\\x7F", "\\x80", "\\x81", "\\x82", "\\x83", "\\x84", "\\x85", "\\x86", "\\x87", "\\x88", "\\x89", "\\x8A", "\\x8B", "\\x8C", "\\x8D", "\\x8E", "\\x8F", "\\x90", "\\x91", "\\x92", "\\x93", "\\x94", "\\x95", "\\x96", "\\x97", "\\x98", "\\x99", "\\x9A", "\\x9B", "\\x9C", "\\x9D", "\\x9E", "\\x9F", "\\xA0", "\\xA1", "\\xA2", "\\xA3", "\\xA4", "\\xA5", "\\xA6", "\\xA7", "\\xA8", "\\xA9", "\\xAA", "\\xAB", "\\xAC", "\\xAD", "\\xAE", "\\xAF", "\\xB0", "\\xB1", "\\xB2", "\\xB3", "\\xB4", "\\xB5", "\\xB6", "\\xB7", "\\xB8", "\\xB9", "\\xBA", "\\xBB", "\\xBC", "\\xBD", "\\xBE", "\\xBF", "\\xC0", "\\xC1", "\\xC2", "\\xC3", "\\xC4", "\\xC5", "\\xC6", "\\xC7", "\\xC8", "\\xC9", "\\xCA", "\\xCB", "\\xCC", "\\xCD", "\\xCE", "\\xCF", "\\xD0", "\\xD1", "\\xD2", "\\xD3", "\\xD4", "\\xD5", "\\xD6", "\\xD7", "\\xD8", "\\xD9", "\\xDA", "\\xDB", "\\xDC", "\\xDD", "\\xDE", "\\xDF", "\\xE0", "\\xE1", "\\xE2", "\\xE3", "\\xE4", "\\xE5", "\\xE6", "\\xE7", "\\xE8", "\\xE9", "\\xEA", "\\xEB", "\\xEC", "\\xED", "\\xEE", "\\xEF", "\\xF0", "\\xF1", "\\xF2", "\\xF3", "\\xF4", "\\xF5", "\\xF6", "\\xF7", "\\xF8", "\\xF9", "\\xFA", "\\xFB", "\\xFC", "\\xFD", "\\xFE", "\\xFF" }; return xlat[(unsigned char)ch]; } static inline int hex_digit_val(char ch) { static int val[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; return val[(unsigned char)ch]; } static inline bool cstr_unescape_char(const char *&cstr, char &ch) { if (*cstr == '\\') { ++cstr; switch (*cstr) { case '"': ch = '"'; break; case 't': ch = '\t'; break; case 'n': ch = '\n'; break; case '\\': ch = '\\'; break; case 'r': ch = '\r'; break; case 'a': ch = '\a'; break; case 'v': ch = '\v'; break; case 'b': ch = '\b'; break; case '0': ch = '\0'; break; case 'x': { int vals[2]; int i; for (i=0; i<2; ++i) { if ((vals[i] = hex_digit_val(*++cstr)) == -1) return false; } ch = (vals[0] << 4) | vals[1]; } break; default: return false; } ++cstr; return true; } else { ch = *cstr++; return true; } } WvString cstr_escape(const void *data, size_t size, const CStrExtraEscape extra_escapes[]) { if (!data) return WvString::null; const char *cdata = (const char *)data; WvString result; result.setsize(4*size + 3); // We could do better but it would slow us down char *cstr = result.edit(); *cstr++ = '\"'; while (size-- > 0) { const char *esc = NULL; if (extra_escapes) { const CStrExtraEscape *extra = &extra_escapes[0]; while (extra->ch && extra->esc) { if (*cdata == extra->ch) { esc = extra->esc; break; } ++extra; } } if (!esc) esc = cstr_escape_char(*cdata); ++cdata; while (*esc) *cstr++ = *esc++; } *cstr++ = '\"'; *cstr = '\0'; return result; } bool cstr_unescape(WvStringParm cstr, void *data, size_t max_size, size_t &size, const CStrExtraEscape extra_escapes[]) { const char *q = cstr; char *cdata = (char *)data; if (!q) goto misformatted; size = 0; for (;;) { while (isspace(*q)) q++; if (*q == '\0') break; if (*q++ != '\"') goto misformatted; while (*q && *q != '\"') { bool found = false; char unesc; if (extra_escapes) { const CStrExtraEscape *extra = &extra_escapes[0]; while (extra->ch && extra->esc) { size_t len = strlen(extra->esc); if (strncmp(extra->esc, q, len) == 0) { unesc = extra->ch; q += len; found = true; break; } ++extra; } } if (!found && !cstr_unescape_char(q, unesc)) goto misformatted; if (size++ < max_size && cdata) *cdata++ = unesc; } if (*q++ != '\"') goto misformatted; } return size <= max_size; misformatted: size = 0; return false; } WvString local_date(time_t when) { WvString out; out.setsize(80); if (when < 0) when = time(NULL); struct tm *tmwhen = localtime(&when); strftime(out.edit(), 80, "%b %d %I:%M:%S %p", tmwhen); return out; } WvString intl_time(time_t when) { WvString out; out.setsize(12); if (when < 0) when = time(NULL); struct tm *tmwhen = localtime(&when); strftime(out.edit(), 12, "%H:%M:%S", tmwhen); return out; } WvString intl_date(time_t when) { WvString out; out.setsize(16); if (when < 0) when = time(NULL); struct tm *tmwhen = localtime(&when); strftime(out.edit(), 16, "%Y-%m-%d", tmwhen); return out; } WvString intl_datetime(time_t when) { WvString out; out.setsize(24); if (when < 0) when = time(NULL); struct tm *tmwhen = localtime(&when); strftime(out.edit(), 24, "%Y-%m-%d %H:%M:%S", tmwhen); return out; } /** * Return the number of seconds by which localtime (at the given timestamp) * is offset from GMT. For example, in Eastern Standard Time, the offset * is (-5*60*60) = -18000. */ time_t intl_gmtoff(time_t t) { struct tm *l = localtime(&t); l->tm_isdst = 0; time_t local = mktime(l); time_t gmt = mktime(gmtime(&t)); return local-gmt; } // Removes any trailing punctuation ('.', '?', or '!') from the line WvString depunctuate(WvStringParm line) { WvString ret = line; char * edit = ret.edit(); int last = ret.len() - 1; if (edit[last] == '.' || edit[last] == '?' || edit[last] == '!') edit[last] = '\0'; return ret; } WvString ptr2str(void* ptr) { char buf[(sizeof(ptr) * 2) + 3]; int rv; rv = snprintf(buf, sizeof(buf), "%p", ptr); assert(rv != -1); return buf; } wvstreams-4.6.1/utils/wvbase64.cc0000644000175000001440000001165511036722347015717 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Functions for encoding and decoding strings in MIME's Base64 notation. * * Base 64 is pretty easy. The input is processed in groups of three bytes. * These 24 bits are split into 4 groups of 6 bits. Each group of six bits * is represented by one character in the base64 alphabet, in the encoded * output. The alphabet is as follows: * ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= * Where 'A' through '/' represent 000000 through 011111, the 64 different * combinations. The '=' (100000) is padding and has no value when decoded. */ #include "wvbase64.h" // maps codes to the Base64 alphabet static char alphabet[67] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"; // finds codes in the Base64 alphabet static int lookup(char ch) { if (ch >= 'A' && ch <= 'Z') return ch - 'A'; if (ch >= 'a' && ch <= 'z') return ch - 'a' + 26; if (ch >= '0' && ch <= '9') return ch - '0' + 52; if (ch == '+') return 62; if (ch == '/') return 63; if (ch == '=') return 64; // padding if (ch == '\n' || ch == ' ' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\v') return 65; // whitespace return -1; } /***** WvBase64Encoder *****/ WvBase64Encoder::WvBase64Encoder() { _reset(); } bool WvBase64Encoder::_reset() { state = ATBIT0; bits = 0; return true; } bool WvBase64Encoder::_encode(WvBuf &in, WvBuf &out, bool flush) { // base 64 encode the entire buffer while (in.used() != 0) { unsigned char next = in.getch(); bits = (bits << 8) | next; switch (state) { case ATBIT0: out.putch(alphabet[bits >> 2]); bits &= 0x03; state = ATBIT2; break; case ATBIT2: out.putch(alphabet[bits >> 4]); bits &= 0x0f; state = ATBIT4; break; case ATBIT4: out.putch(alphabet[bits >> 6]); out.putch(alphabet[bits & 0x3f]); bits = 0; state = ATBIT0; break; } } // do not consider the data flushed if we need padding if (flush && state != ATBIT0) return false; return true; } bool WvBase64Encoder::_finish(WvBuf &out) { // pad text if needed switch (state) { case ATBIT2: out.putch(alphabet[bits << 4]); out.putch('='); out.putch('='); break; case ATBIT4: out.putch(alphabet[bits << 2]); out.putch('='); break; case ATBIT0: break; } return true; } /***** WvBase64Decoder *****/ WvBase64Decoder::WvBase64Decoder() { _reset(); } bool WvBase64Decoder::_reset() { state = ATBIT0; bits = 0; return true; } bool WvBase64Decoder::_encode(WvBuf &in, WvBuf &out, bool flush) { // base 64 decode the entire buffer while (in.used() != 0) { unsigned char next = in.getch(); int symbol = lookup(next); switch (symbol) { case -1: // invalid character seterror("invalid character #%s in base64 input", next); return false; case 64: // padding // strip out any remaining padding // we are lenient in that we do not track how much padding we skip setfinished(); state = PAD; break; case 65: // whitespace break; default: // other symbol bits = (bits << 6) | symbol; switch (state) { case ATBIT0: state = ATBIT2; break; case ATBIT2: out.putch(bits >> 4); bits &= 0x0f; state = ATBIT4; break; case ATBIT4: out.putch(bits >> 2); bits &= 0x03; state = ATBIT6; break; case ATBIT6: out.putch(bits); bits = 0; state = ATBIT0; break; case PAD: seterror("invalid character #%s " "after base64 padding", next); return false; } break; } } // if flushing and we did not get sufficient padding, then fail if (flush && (state == ATBIT2 || state == ATBIT4 || state == ATBIT6)) return false; // insufficient padding to flush! return true; } wvstreams-4.6.1/utils/wvpam.cc0000644000175000001440000001555611202637334015410 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A WvStream that authenticates with PAM before allowing any reading or * writing. See wvpam.h. */ #include "wvlog.h" #include "wvpam.h" #include "wvautoconf.h" // If PAM not installed at compile time, stub this out #ifndef HAVE_SECURITY_PAM_APPL_H WvPam::WvPam(WvStringParm _appname) : log("PAM Auth", WvLog::Info), appname(_appname) { err.seterr("Compiled without PAM Support!\n"); } WvPam::WvPam(WvStringParm _appname, WvStringParm rhost, WvStringParm user, WvStringParm password) : log("PAM Auth", WvLog::Info), appname(_appname) { err.seterr("Compiled without PAM Support!\n"); } WvPam::~WvPam() { } bool WvPam::authenticate(WvStringParm rhost, WvStringParm user, WvStringParm password) { return false; } WvString WvPam::getuser() const { return WvString::null; } void WvPam::getgroups(WvStringList &l) const { } #else // HAVE_SECURITY_PAM_APPL_H #include #include #include #include #include "wvaddr.h" class WvPamData { public: pam_handle_t *pamh; int status; WvString failmsg, user; WvStringList groups; WvPamData() : pamh(NULL), status(PAM_SUCCESS), user("") { } WvPamData(WvStringParm _failmsg) : pamh(NULL), status(PAM_SUCCESS), failmsg(_failmsg) { } }; /** noconv: null PAM conversation function */ #if HAVE_BROKEN_PAM int noconv(int num_msg, struct pam_message **msgm, struct pam_response **response, void *userdata) #else int noconv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *userdata) #endif { // if you need to ask things, it won't work return PAM_CONV_ERR; } // The password gets passed in from userdata, and we simply echo it back // out in the response... *sigh* This is because pam expects this function // to actually interact with the user, and get their password. #if HAVE_BROKEN_PAM static int passconv(int num_msg, struct pam_message **msgm, struct pam_response **response, void *userdata) #else static int passconv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *userdata) #endif { struct pam_response *password_echo; password_echo = (struct pam_response *)calloc(num_msg, sizeof(struct pam_response)); password_echo->resp = (char *)userdata; password_echo->resp_retcode = 0; *response = password_echo; return PAM_SUCCESS; } WvPam::WvPam(WvStringParm _appname) : log("PAM Auth", WvLog::Info), appname(_appname) { init(); } WvPam::WvPam(WvStringParm _appname, WvStringParm rhost, WvStringParm user, WvStringParm password) : log("PAM Auth", WvLog::Info), appname(_appname) { if (init()) authenticate(rhost, user, password); } WvPam::~WvPam() { log(WvLog::Debug2, "Shutting down PAM Session for: %s\n", appname); if (d->status == PAM_SUCCESS) pam_close_session(d->pamh, 0); pam_end(d->pamh, d->status); d->groups.zap(); delete d; } bool WvPam::init() { d = new WvPamData(); log(WvLog::Debug2, "Starting up PAM Session for: %s\n", appname); err.seterr("Not yet authenticated..."); struct pam_conv c; c.conv = noconv; c.appdata_ptr = NULL; d->pamh = NULL; d->status = pam_start(appname, d->user, &c, &d->pamh); if (check_pam_status("pam_start")) return true; return false; } bool WvPam::authenticate(WvStringParm rhost, WvStringParm user, WvStringParm password) { // Just in case... assert(d); if (!!rhost) { d->status = pam_set_item(d->pamh, PAM_RHOST, rhost); if (!check_pam_status("rhost setup")) return false; } if (!!user) { d->user = user; d->status = pam_set_item(d->pamh, PAM_USER, user); if (!check_pam_status("user setup")) return false; } if (!!password) { struct pam_conv c; c.conv = passconv; c.appdata_ptr = strdup(password); d->status = pam_set_item(d->pamh, PAM_CONV, &c); if (!check_pam_status("conversation setup")) return false; d->status = pam_set_item(d->pamh, PAM_AUTHTOK, password); if (!check_pam_status("password setup")) return false; } #if HAVE_BROKEN_PAM void *x = NULL; #else const void *x = NULL; #endif d->status = pam_get_item(d->pamh, PAM_USER, &x); if (!check_pam_status("get username")) return false; d->user = (const char *)x; d->user.unique(); log("Starting Authentication for %s@%s\n", d->user, rhost); d->status = pam_authenticate(d->pamh, PAM_DISALLOW_NULL_AUTHTOK | PAM_SILENT); if (!check_pam_status("authentication")) return false; d->status = pam_acct_mgmt(d->pamh, PAM_DISALLOW_NULL_AUTHTOK | PAM_SILENT); if (!check_pam_status("account management")) return false; d->status = pam_setcred(d->pamh, PAM_ESTABLISH_CRED); if (!check_pam_status("credentials")) return false; d->status = pam_open_session(d->pamh, 0); if (!check_pam_status("session open")) return false; // Grab the current user name (now that we've authenticated) if (!d->user) { #ifdef SOLARIS void *x = NULL; #else const void *x = NULL; #endif d->status = pam_get_item(d->pamh, PAM_USER, &x); if (!check_pam_status("get username")) return false; d->user = (const char *)x; d->user.unique(); } log("Session open as user '%s'\n", d->user); // If we made it here, we're clear of everything, and we can go // to a no error status. err.noerr(); return true; } bool WvPam::check_pam_status(WvStringParm s) { if (d->status == PAM_SUCCESS) { log(WvLog::Debug2, "PAM %s succeeded.\n", s); return true; } else { WvString msg("PAM %s failed: %s\n", s, pam_strerror(d->pamh, d->status)); log(WvLog::Info, msg); err.seterr(msg); d->user = WvString::null; d->groups.zap(); return false; } } WvString WvPam::getuser() const { return d->user; } void WvPam::getgroups(WvStringList &l) const { assert(l.isempty()); // Cache after the first time... if (d->groups.isempty()) { setgrent(); struct group *gr; while ((gr = getgrent())) { for (char **i = gr->gr_mem; *i != NULL; i++) { if (strcmp(*i, d->user) == 0) { d->groups.append(new WvString(gr->gr_name), true); break; } } } endgrent(); } WvStringList::Iter i(d->groups); for (i.rewind(); i.next(); ) l.append(new WvString(*i), true); } #endif // HAVE_SECURITY_PAM_APPL_H wvstreams-4.6.1/utils/wvargs.cc0000644000175000001440000004773611205042556015573 0ustar wlachusers/* -*- Mode: C++ -*- * Copyright (C) 2004-2005 Net Integration Technologies, Inc. * * WvStreams interface for command-line argument processing */ #include "wvargs.h" #include "wvscatterhash.h" // Some screwy defines that show up in _WIN32 and cause problems #undef error_t #undef __error_t_defined #undef argc #undef argv #undef __argc #undef __argv #include #include class WvArgsOption { public: int short_option; WvString long_option; WvString desc; WvArgsOption(int _short_option, WvStringParm _long_option, WvStringParm _desc) : short_option(_short_option), long_option(_long_option), desc(_desc) { } virtual ~WvArgsOption() { } virtual WvString process(WvStringParm arg) { return WvString::null; } virtual void add_to_argp(WvArgsData &data); }; DeclareWvList(WvArgsOption); DeclareWvScatterDict(WvArgsOption, int, short_option); class WvArgsData { public: WvArgsData(); ~WvArgsData(); argp_option *argp() const; void *self() const; void add(WvArgsOption *option); void remove(char short_option, WvStringParm long_option); void zap(); void add_required_arg(); void subtract_required_arg(); const WvStringList &args() const; static error_t parser(int key, char *arg, argp_state *state); unsigned int flags; protected: friend class WvArgsOption; friend class WvArgsArgOption; friend class WvArgs; void argp_build(); bool argp_add(const char *name, int key, const char *arg, int flags, const char *doc, int group); private: void argp_init(size_t size = 0); bool argp_add(const argp_option &option); bool argp_double(); argp_option *argp_; size_t argp_index; // Last element in the options array size_t argp_size; // Size of the options array // I create two data-structures, only one of them actually owning // the objects, of course. The List is for ordered construction // of argp_. The Dict is for constant-time lookups when // process()ing options. WvArgsOptionList options_list; // An ordered list of WvArgsOptions WvArgsOptionDict options_dict; // A constant-time lookup of them WvStringList args_; // Arguments after all options have been parsed size_t required_args; // Number of these mandatory arguments. size_t maximum_args; // Number of maximum arguments. int last_no_key; // Last key for options with no short_option }; void WvArgsOption::add_to_argp(WvArgsData &data) { data.argp_add(long_option, short_option, 0, 0, desc, 0); } class WvArgsNoArgOption : public WvArgsOption { public: WvArgsNoArgOption(int _short_option, WvStringParm _long_option, WvStringParm _desc) : WvArgsOption(_short_option, _long_option, _desc) { } }; class WvArgsSetBoolOption : public WvArgsNoArgOption { private: bool &flag; public: WvArgsSetBoolOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, bool &_flag) : WvArgsNoArgOption(_short_option, _long_option, _desc), flag(_flag) { } virtual WvString process(WvStringParm arg) { flag = true; return WvString::null; } }; class WvArgsResetBoolOption : public WvArgsNoArgOption { private: bool &flag; public: WvArgsResetBoolOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, bool &_flag) : WvArgsNoArgOption(_short_option, _long_option, _desc), flag(_flag) { } virtual WvString process(WvStringParm arg) { flag = false; return WvString::null; } }; class WvArgsFlipBoolOption : public WvArgsNoArgOption { private: bool &flag; public: WvArgsFlipBoolOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, bool &_flag) : WvArgsNoArgOption(_short_option, _long_option, _desc), flag(_flag) { } virtual WvString process(WvStringParm arg) { flag = !flag; return WvString::null; } }; class WvArgsIncIntOption : public WvArgsNoArgOption { private: int &val; public: WvArgsIncIntOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, int &_val) : WvArgsNoArgOption(_short_option, _long_option, _desc), val(_val) { } virtual WvString process(WvStringParm arg) { val++; return WvString::null; } }; class WvArgsNoArgCallbackOption : public WvArgsNoArgOption { private: WvArgs::NoArgCallback cb; void *ud; public: WvArgsNoArgCallbackOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvArgs::NoArgCallback _cb, void *_ud) : WvArgsNoArgOption(_short_option, _long_option, _desc), cb(_cb), ud(_ud) { } virtual WvString process(WvStringParm arg) { if (cb(ud)) return WvString::null; else return WvString("invalid option `%s'", arg); } }; class WvArgsArgOption : public WvArgsOption { private: WvString arg_desc; public: WvArgsArgOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc) : WvArgsOption(_short_option, _long_option, _desc), arg_desc(_arg_desc) { } virtual void add_to_argp(WvArgsData &data) { data.argp_add(long_option, short_option, arg_desc, 0, desc, 0); } }; class WvArgsIntOption : public WvArgsArgOption { private: int &val; public: WvArgsIntOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, int &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { char *tailptr = NULL; errno = 0; long int tmp = strtol(arg, &tailptr, 10); if (errno == ERANGE || tmp > INT_MAX || tmp < INT_MIN ) { // Out of range return WvString("`%s': invalid number.", arg); } else if (*tailptr) { // Invalid number return WvString("`%s': invalid number.", arg); } else { val = tmp; return WvString::null; } } }; class WvArgsLongOption : public WvArgsArgOption { private: long &val; public: WvArgsLongOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, long &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { char *tailptr = NULL; errno = 0; long int tmp = strtol(arg, &tailptr, 10); if (errno == ERANGE) { // Out of range return WvString("`%s': invalid number.", arg); } else if (*tailptr) { // Invalid number return WvString("`%s': invalid number.", arg); } else { val = tmp; return WvString::null; } } }; class WvArgsFloatOption : public WvArgsArgOption { private: float &val; public: WvArgsFloatOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, float &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { char *tailptr = NULL; errno = 0; float tmp = strtof(arg, &tailptr); if (errno == ERANGE) { // Out of range return WvString("`%s': invalid number.", arg); } else if (*tailptr) { // Invalid number return WvString("`%s': invalid number.", arg); } else { val = tmp; return WvString::null; } } }; class WvArgsDoubleOption : public WvArgsArgOption { private: double &val; public: WvArgsDoubleOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, double &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { char *tailptr = NULL; errno = 0; double tmp = strtod(arg, &tailptr); if (errno == ERANGE) { // Out of range return WvString("`%s': invalid number.", arg); } else if (*tailptr) { // Invalid number return WvString("`%s': invalid number.", arg); } else { val = tmp; return WvString::null; } } }; class WvArgsStringOption : public WvArgsArgOption { private: WvString &val; public: WvArgsStringOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, WvString &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { val = arg; return WvString::null; } }; class WvArgsStringListAppendOption : public WvArgsArgOption { private: WvStringList &val; public: WvArgsStringListAppendOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, WvStringList &_val) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), val(_val) { } virtual WvString process(WvStringParm arg) { val.append(arg); return WvString::null; } }; class WvArgsArgCallbackOption : public WvArgsArgOption { private: WvArgs::ArgCallback cb; void *ud; public: WvArgsArgCallbackOption(int _short_option, WvStringParm _long_option, WvStringParm _desc, WvStringParm _arg_desc, WvArgs::ArgCallback _cb, void *_ud) : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc), cb(_cb), ud(_ud) { } virtual WvString process(WvStringParm arg) { if (cb(arg, ud)) return WvString::null; else return WvString("invalid option: `%s'", arg); } }; WvArgsData::WvArgsData() : flags(0), argp_(NULL), argp_index(0), argp_size(0), required_args(0), maximum_args(0), last_no_key(-1) { } WvArgsData::~WvArgsData() { if (argp_) free(argp_); } argp_option *WvArgsData::argp() const { return argp_; } void *WvArgsData::self() const { return (void *)this; } void WvArgsData::add(WvArgsOption *option) { if (!option) return; if (!option->short_option) option->short_option = last_no_key--; options_list.append(option, true); options_dict.add(option, false); } // This method removes both short_option and long_option from the // options_* structures. Completely. void WvArgsData::remove(char short_option, WvStringParm long_option) { // First, look through options_list, and remove them from // options_dict once we find them. WvArgsOptionList::Iter i(options_list); for (i.rewind(); i.next(); ) { bool matches_short = false; bool matches_long = false; if (short_option != '\0' && i->short_option == short_option) matches_short = true; if (!long_option.isnull() && i->long_option == long_option) matches_long = true; if ((matches_short && matches_long) || (matches_short && i->long_option.isnull()) || (matches_long && i->short_option == '\0')) { // Delete this item from the data-structures options_dict.remove(i.ptr()); i.xunlink(); if (argp_) { free(argp_); argp_ = NULL; } } else if (matches_short) { // Update the short description and change how it's filed // in the dictionary. i->short_option = '\0'; options_dict.remove(i.ptr()); options_dict.add(i.ptr(), false); } else if (matches_long) { // Update the long description only i->long_option = WvString::null; } } } void WvArgsData::zap() { options_dict.zap(); options_list.zap(); if (argp_) { free(argp_); argp_ = NULL; } } void WvArgsData::argp_init(size_t size) { argp_size = size; if (argp_size < 1) argp_size = 1; // I'm sorry to use malloc(), but this argp is a C library argp_ = (argp_option *)malloc(argp_size * sizeof(argp_option)); // Terminate the empty array memset(argp_, 0, sizeof(argp_option)); } void WvArgsData::argp_build() { if (!argp_) argp_init(options_list.count() + 2); WvArgsOptionList::Iter i(options_list); for (i.rewind(); i.next(); ) i->add_to_argp(*this); } bool WvArgsData::argp_add(const argp_option &option) { if (argp_index >= (argp_size - 1)) { if (!argp_double()) return false; } // Make a copy of the option that we're building. memcpy(argp_ + argp_index, &option, sizeof(argp_option)); // Terminate the array. ++argp_index; memset(argp_ + argp_index, 0, sizeof(argp_option)); return true; } bool WvArgsData::argp_add(const char *name, int key, const char *arg, int flags, const char *doc, int group) { if (argp_index >= (argp_size - 1)) { if (!argp_double()) return false; } // Set the elements. argp_option *option = argp_ + argp_index; option->name = name; option->key = key; option->arg = arg; option->flags = flags; option->doc = doc; option->group = group; // Terminate the array. ++argp_index; memset(argp_ + argp_index, 0, sizeof(argp_option)); return true; } bool WvArgsData::argp_double() { // We won't be able to fit the next entry into the array void *tmp = realloc(argp_, 2 * argp_size * sizeof(argp_option)); if (!tmp) return false; argp_ = (argp_option *)tmp; argp_size *= 2; return true; } void WvArgsData::add_required_arg() { ++required_args; } void WvArgsData::subtract_required_arg() { --required_args; } const WvStringList &WvArgsData::args() const { return args_; } error_t WvArgsData::parser(int key, char *arg, struct argp_state *state) { WvArgsData *data = (WvArgsData *)state->input; switch (key) { case ARGP_KEY_ARG: if (state->arg_num >= data->maximum_args) { // Too many arguments argp_usage(state); } data->args_.append(arg); break; case ARGP_KEY_NO_ARGS: case ARGP_KEY_END: if (state->arg_num < data->required_args) { // Too few arguments argp_usage(state); } break; default: WvArgsOption *option = data->options_dict[key]; if (option) { WvString error = option->process(arg); if (!error.isnull()) { argp_failure(state, argp_err_exit_status, 0, "%s", error.cstr()); return EINVAL; } } else return ARGP_ERR_UNKNOWN; } return 0; } WvArgs::WvArgs() : data(new WvArgsData()) { } WvArgs::~WvArgs() { if (data) delete data; } bool WvArgs::process(int argc, char **argv, WvStringList *remaining_args) { if (!data->argp()) data->argp_build(); // Setup --help headers and footers WvString prog_doc; if (header && footer) prog_doc = WvString("%s\v%s", header, footer); else if (header) prog_doc = WvString("%s", header); else if (footer) prog_doc = WvString(" \v%s", footer); // Setup the constant version number and e-mail address argp_program_version = version; argp_program_bug_address = email; struct argp argp = { data->argp(), &WvArgsData::parser, args_doc, prog_doc, 0, 0, 0 }; bool error = argp_parse(&argp, argc, argv, data->flags, 0, data->self()); if (remaining_args) { remaining_args->zap(); WvStringList::Iter i(data->args()); for (i.rewind(); i.next(); ) remaining_args->add(new WvString(*i), true); } return !error; } void WvArgs::set_version(WvStringParm version) { this->version = version; } void WvArgs::set_email(WvStringParm email) { this->email = email; } void WvArgs::set_help_header(WvStringParm header) { this->header = header; } void WvArgs::set_help_footer(WvStringParm footer) { this->footer = footer; } void WvArgs::print_usage(int argc, char **argv) { struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 }; argp_help(&argp, stdout, ARGP_HELP_STD_USAGE, argv[0]); } void WvArgs::print_help(int argc, char **argv) { struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 }; argp_help(&argp, stdout, ARGP_HELP_STD_HELP, argv[0]); } void WvArgs::add_set_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val) { data->remove(short_option, long_option); data->add(new WvArgsSetBoolOption(short_option, long_option, desc, val)); } void WvArgs::add_reset_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val) { data->remove(short_option, long_option); data->add(new WvArgsResetBoolOption(short_option, long_option, desc, val)); } void WvArgs::add_flip_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val) { data->remove(short_option, long_option); data->add(new WvArgsFlipBoolOption(short_option, long_option, desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, NoArgCallback cb, void *ud) { data->remove(short_option, long_option); data->add(new WvArgsNoArgCallbackOption(short_option, long_option, desc, cb, ud)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, int &val) { data->remove(short_option, long_option); data->add(new WvArgsIntOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, long &val) { data->remove(short_option, long_option); data->add(new WvArgsLongOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, float &val) { data->remove(short_option, long_option); data->add(new WvArgsFloatOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, double &val) { data->remove(short_option, long_option); data->add(new WvArgsDoubleOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, WvString &val) { data->remove(short_option, long_option); data->add(new WvArgsStringOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, WvStringList &val) { data->remove(short_option, long_option); data->add(new WvArgsStringListAppendOption(short_option, long_option, desc, arg_desc, val)); } void WvArgs::add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, ArgCallback cb, void *ud) { data->remove(short_option, long_option); data->add(new WvArgsArgCallbackOption(short_option, long_option, desc, arg_desc, cb, ud)); } void WvArgs::remove_option(char short_option) { data->remove(short_option, WvString::null); } void WvArgs::remove_option(WvStringParm long_option) { data->remove(0, long_option); } void WvArgs::remove_all_options() { data->zap(); } void WvArgs::add_required_arg(WvStringParm desc, bool multiple) { data->add_required_arg(); if (!!args_doc) args_doc.append(" "); args_doc.append(desc); if (multiple) { args_doc.append("..."); data->maximum_args = LONG_MAX; } else if (data->maximum_args < LONG_MAX) ++(data->maximum_args); } void WvArgs::add_optional_arg(WvStringParm desc, bool multiple) { // an optional arg is a required arg without the requirement :-) add_required_arg(WvString("[%s]", desc), multiple); data->subtract_required_arg(); } bool WvArgs::get_flag(const flags_t flag) const { switch (flag) { case NO_EXIT_ON_ERRORS: return data->flags & ARGP_NO_EXIT; default: return false; } } void WvArgs::set_flag(const flags_t flag, const bool value) { printf("set_flag(%d, %d)\n", flag, value); unsigned int mask; switch (flag) { case NO_EXIT_ON_ERRORS: mask = ARGP_NO_EXIT; break; default: return; } if (value) data->flags |= mask; else data->flags &= ~mask; printf("set_flag(%d, %d) = %d\n", flag, value, data->flags); } wvstreams-4.6.1/utils/wvtest.cc0000644000175000001440000002544611077364544015623 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * Part of an automated testing framework. See wvtest.h. */ #include "wvtest.h" #include "wvautoconf.h" #include #include #include #include #ifdef _WIN32 #include #else #include #include #endif #include #include #include #ifdef HAVE_VALGRIND_MEMCHECK_H # include # include #else # define VALGRIND_COUNT_ERRORS 0 # define VALGRIND_DO_LEAK_CHECK # define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0) #endif #define MAX_TEST_TIME 40 // max seconds for a single test to run #define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run #define TEST_START_FORMAT "! %s:%-5d %-40s " static int memerrs() { return (int)VALGRIND_COUNT_ERRORS; } static int memleaks() { int leaked = 0, dubious = 0, reachable = 0, suppressed = 0; VALGRIND_DO_LEAK_CHECK; VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed); printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n", leaked, dubious, reachable, suppressed); fflush(stdout); // dubious+reachable are normally non-zero because of globals... // return leaked+dubious+reachable; return leaked; } // Return 1 if no children are running or zombies, 0 if there are any running // or zombie children. // Will wait for any already-terminated children first. // Passes if no rogue children were running, fails otherwise. // If your test gets a failure in here, either you're not killing all your // children, or you're not calling waitpid(2) on all of them. static bool no_running_children() { #ifndef _WIN32 pid_t wait_result; // Acknowledge and complain about any zombie children do { int status = 0; wait_result = waitpid(-1, &status, WNOHANG); if (wait_result > 0) { char buf[256]; snprintf(buf, sizeof(buf) - 1, "%d", wait_result); buf[sizeof(buf)-1] = '\0'; WVFAILEQ("Unclaimed dead child process", buf); } } while (wait_result > 0); // There should not be any running children, so waitpid should return -1 WVPASSEQ(errno, ECHILD); WVPASSEQ(wait_result, -1); return (wait_result == -1 && errno == ECHILD); #endif return true; } WvTest *WvTest::first, *WvTest::last; int WvTest::fails, WvTest::runs; time_t WvTest::start_time; bool WvTest::run_twice = false; void WvTest::alarm_handler(int) { printf("\n! WvTest Current test took longer than %d seconds! FAILED\n", MAX_TEST_TIME); fflush(stdout); abort(); } static const char *pathstrip(const char *filename) { const char *cptr; cptr = strrchr(filename, '/'); if (cptr) filename = cptr + 1; cptr = strrchr(filename, '\\'); if (cptr) filename = cptr + 1; return filename; } WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slowness) : descr(_descr), idstr(pathstrip(_idstr)), main(_main), slowness(_slowness), next(NULL) { if (first) last->next = this; else first = this; last = this; } static bool prefix_match(const char *s, const char * const *prefixes) { for (const char * const *prefix = prefixes; prefix && *prefix; prefix++) { if (!strncasecmp(s, *prefix, strlen(*prefix))) return true; } return false; } int WvTest::run_all(const char * const *prefixes) { int old_valgrind_errs = 0, new_valgrind_errs; int old_valgrind_leaks = 0, new_valgrind_leaks; #ifdef _WIN32 /* I should be doing something to do with SetTimer here, * not sure exactly what just yet */ #else char *disable(getenv("WVTEST_DISABLE_TIMEOUT")); if (disable != NULL && disable[0] != '\0' && disable[0] != '0') signal(SIGALRM, SIG_IGN); else signal(SIGALRM, alarm_handler); alarm(MAX_TEST_TIME); #endif start_time = time(NULL); // make sure we can always start out in the same directory, so tests have // access to their files. If a test uses chdir(), we want to be able to // reverse it. char wd[1024]; if (!getcwd(wd, sizeof(wd))) strcpy(wd, "."); const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS"); const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS"); int min_slowness = 0, max_slowness = 65535; if (slowstr1) min_slowness = atoi(slowstr1); if (slowstr2) max_slowness = atoi(slowstr2); #ifdef _WIN32 run_twice = false; #else char *parallel_str = getenv("WVTEST_PARALLEL"); if (parallel_str) run_twice = atoi(parallel_str) > 0; #endif // there are lots of fflush() calls in here because stupid win32 doesn't // flush very often by itself. fails = runs = 0; for (WvTest *cur = first; cur; cur = cur->next) { if (cur->slowness <= max_slowness && cur->slowness >= min_slowness && (!prefixes || prefix_match(cur->idstr, prefixes) || prefix_match(cur->descr, prefixes))) { #ifndef _WIN32 // set SIGPIPE back to default, helps catch tests which don't set // this signal to SIG_IGN (which is almost always what you want) // on startup signal(SIGPIPE, SIG_DFL); pid_t child = 0; if (run_twice) { // I see everything twice! printf("Running test in parallel.\n"); child = fork(); } #endif printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr); fflush(stdout); cur->main(); chdir(wd); new_valgrind_errs = memerrs(); WVPASS(new_valgrind_errs == old_valgrind_errs); old_valgrind_errs = new_valgrind_errs; new_valgrind_leaks = memleaks(); WVPASS(new_valgrind_leaks == old_valgrind_leaks); old_valgrind_leaks = new_valgrind_leaks; fflush(stderr); printf("\n"); fflush(stdout); #ifndef _WIN32 if (run_twice) { if (!child) { // I see everything once! printf("Child exiting.\n"); _exit(0); } else { printf("Waiting for child to exit.\n"); int result; while ((result = waitpid(child, NULL, 0)) == -1 && errno == EINTR) printf("Waitpid interrupted, retrying.\n"); } } #endif WVPASS(no_running_children()); } } WVPASS(runs > 0); if (prefixes && *prefixes && **prefixes) printf("WvTest: WARNING: only ran tests starting with " "specifed prefix(es).\n"); else printf("WvTest: ran all tests.\n"); printf("WvTest: %d test%s, %d failure%s.\n", runs, runs==1 ? "" : "s", fails, fails==1 ? "": "s"); fflush(stdout); return fails != 0; } // If we aren't running in parallel, we want to output the name of the test // before we run it, so we know what happened if it crashes. If we are // running in parallel, outputting this information in multiple printf()s // can confuse parsers, so we want to output everything in one printf(). // // This function gets called by both start() and check(). If we're not // running in parallel, just print the data. If we're running in parallel, // and we're starting a test, save a copy of the file/line/description until // the test is done and we can output it all at once. // // Yes, this is probably the worst API of all time. void WvTest::print_result(bool start, const char *_file, int _line, const char *_condstr, bool result) { static char *file; static char *condstr; static int line; if (start) { if (file) free(file); if (condstr) free(condstr); file = strdup(pathstrip(_file)); condstr = strdup(_condstr); line = _line; for (char *cptr = condstr; *cptr; cptr++) { if (!isprint((unsigned char)*cptr)) *cptr = '!'; } } const char *result_str = result ? "ok\n" : "FAILED\n"; if (run_twice) { if (!start) printf(TEST_START_FORMAT "%s", file, line, condstr, result_str); } else { if (start) printf(TEST_START_FORMAT, file, line, condstr); else printf("%s", result_str); } fflush(stdout); if (!start) { if (file) free(file); if (condstr) free(condstr); file = condstr = NULL; } } void WvTest::start(const char *file, int line, const char *condstr) { // Either print the file, line, and condstr, or save them for later. print_result(true, file, line, condstr, 0); } void WvTest::check(bool cond) { #ifndef _WIN32 alarm(MAX_TEST_TIME); // restart per-test timeout #endif if (!start_time) start_time = time(NULL); if (time(NULL) - start_time > MAX_TOTAL_TIME) { printf("\n! WvTest Total run time exceeded %d seconds! FAILED\n", MAX_TOTAL_TIME); fflush(stdout); abort(); } runs++; print_result(false, NULL, 0, NULL, cond); if (!cond) { fails++; if (getenv("WVTEST_DIE_FAST")) abort(); } } bool WvTest::start_check_eq(const char *file, int line, const char *a, const char *b, bool expect_pass) { if (!a) a = ""; if (!b) b = ""; size_t len = strlen(a) + strlen(b) + 8 + 1; char *str = new char[len]; sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b); start(file, line, str); delete[] str; bool cond = !strcmp(a, b); if (!expect_pass) cond = !cond; check(cond); return cond; } bool WvTest::start_check_eq(const char *file, int line, int a, int b, bool expect_pass) { size_t len = 128 + 128 + 8 + 1; char *str = new char[len]; sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b); start(file, line, str); delete[] str; bool cond = (a == b); if (!expect_pass) cond = !cond; check(cond); return cond; } bool WvTest::start_check_lt(const char *file, int line, const char *a, const char *b) { if (!a) a = ""; if (!b) b = ""; size_t len = strlen(a) + strlen(b) + 8 + 1; char *str = new char[len]; sprintf(str, "[%s] < [%s]", a, b); start(file, line, str); delete[] str; bool cond = strcmp(a, b) < 0; check(cond); return cond; } bool WvTest::start_check_lt(const char *file, int line, int a, int b) { size_t len = 128 + 128 + 8 + 1; char *str = new char[len]; sprintf(str, "%d < %d", a, b); start(file, line, str); delete[] str; bool cond = a < b; check(cond); return cond; } wvstreams-4.6.1/utils/wvscatterhash.cc0000644000175000001440000001043211036722347017134 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A hash table container. */ #include "wvscatterhash.h" #include // Prime numbers close to powers of 2 const unsigned WvScatterHashBase::prime_numbers[] = {2u, 5u, 11u, 17u, 31u, 67u, 127u, 251u, 509u, 1021u, 2039u, 4093u, 8191u, 16381u, 32749u, 65521u, 131071u, 262139u, 524287u, 1048573u, 2097143u, 4194301u, 8388593u, 16777213u, 33554393u, 67108859u, 134217689u, 268435399u, 536870909u, 1073741789u, 2147483647u, 4294967281u}; // we do not accept the _numslots value directly. Instead, we find the // next number of xslots which is >= _numslots and take the closest prime // number WvScatterHashBase::WvScatterHashBase(unsigned _numslots) { num = 0; used = 0; if (_numslots == 0) prime_index = 0; else { prime_index = 1; while ((_numslots >>= 1) != 0) prime_index++; } numslots = prime_numbers[prime_index]; xslots = new Slot[numslots]; xstatus = new Status[numslots]; memset(xslots, 0, numslots * sizeof(xslots[0])); memset(xstatus, 0, numslots * sizeof(xstatus[0])); } size_t WvScatterHashBase::slowcount() const { unsigned count = 0; for (unsigned index = 0; index < numslots; index++) { if (IS_OCCUPIED(xstatus[index])) count++; } return count; } void WvScatterHashBase::rebuild() { if (!(numslots * REBUILD_LOAD_FACTOR <= used + 1)) return; unsigned oldnumslots = numslots; if (numslots * RESIZE_LOAD_FACTOR <= num + 1) numslots = prime_numbers[++prime_index]; Slot *tmpslots = xslots; Status *tmpstatus = xstatus; xslots = new Slot[numslots]; xstatus = new Status[numslots]; memset(xslots, 0, numslots * sizeof(xslots[0])); memset(xstatus, 0, numslots * sizeof(xstatus[0])); used = num = 0; for (unsigned i = 0; i < oldnumslots; i++) { if (IS_OCCUPIED(tmpstatus[i])) _add(tmpslots[i], IS_AUTO_FREE(tmpstatus[i])); } deletev tmpslots; deletev tmpstatus; } void WvScatterHashBase::_add(void *data, bool auto_free) { _add(data, do_hash(data), auto_free); } void WvScatterHashBase::_add(void *data, unsigned hash, bool auto_free) { rebuild(); unsigned slot = hash % numslots; if (IS_OCCUPIED(xstatus[slot])) { unsigned attempt = 0; unsigned hash2 = second_hash(hash); while (IS_OCCUPIED(xstatus[slot])) slot = curhash(hash, hash2, ++attempt); } num++; if (!IS_DELETED(xstatus[slot])) used++; xslots[slot] = data; xstatus[slot] = auto_free ? 3 : 2; } void WvScatterHashBase::_remove(const void *data, unsigned hash) { unsigned res = genfind(data, hash); if (res != null_idx) { if (IS_AUTO_FREE(xstatus[res])) do_delete(xslots[res]); xstatus[res] = 1; num--; } } void WvScatterHashBase::_zap() { for (unsigned i = 0; i < numslots; i++) { if (IS_AUTO_FREE(xstatus[i])) do_delete(xslots[i]); xstatus[i] = 0; } used = num = 0; } void WvScatterHashBase::_set_autofree(const void *data, unsigned hash, bool auto_free) { unsigned res = genfind(data, hash); if (res != null_idx) xstatus[res] = auto_free ? 3 : 2; } bool WvScatterHashBase::_get_autofree(const void *data, unsigned hash) { unsigned res = genfind(data, hash); if (res != null_idx) return IS_AUTO_FREE(xstatus[res]); assert(0 && "You checked auto_free of a nonexistant thing."); return false; } unsigned WvScatterHashBase::genfind(const void *data, unsigned hash) const { unsigned slot = hash % numslots; if (IS_OCCUPIED(xstatus[slot]) && compare(data, xslots[slot])) return slot; unsigned attempt = 0; unsigned hash2 = second_hash(hash); while (xstatus[slot]) { slot = curhash(hash, hash2, ++attempt); if (IS_OCCUPIED(xstatus[slot]) && compare(data, xslots[slot])) return slot; } return null_idx; } void *WvScatterHashBase::genfind_or_null(const void *data, unsigned hash) const { unsigned slot = genfind(data, hash); if (slot == null_idx) return NULL; else return xslots[slot]; } wvstreams-4.6.1/utils/wvglob.cc0000644000175000001440000003014011205042556015537 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * Implementation of globbing support through WvRegex */ #include "wvglob.h" WvGlob::WvGlob() : WvRegex() { } WvGlob::WvGlob(WvStringParm glob) : WvRegex() { set(glob); } bool WvGlob::set(WvStringParm glob) { WvString errstr; WvString regex = glob_to_regex(glob, &errstr); if (!!errstr) WvErrorBase::seterr(errstr); else if (!!regex) WvRegex::set(regex); else WvErrorBase::seterr("Failed to convert glob pattern to regex"); return isok(); } const bool WvGlob::normal_quit_chars[256] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false }; const bool WvGlob::brace_quit_chars[256] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true /* , */, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true /* } */, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false }; // // Known bugs: // // - If / is part of a range it will not be excluded in the resulting regex // eg. fred[.-0]joe will match fred/joe (this violates glob(7)) // However, explcit / in bracket expression results in error. // WvString WvGlob::glob_to_regex(const char *src, size_t &src_used, char *dst, size_t &dst_used, const bool quit_chars[256]) { enum { NORMAL, BACKSLASH, BRACKET, BRACKET_FIRST } state = NORMAL; src_used = 0; dst_used = 0; bool quit_now = false; while (!quit_now && src[src_used]) { switch (state) { case NORMAL: if (quit_chars[(unsigned char)src[src_used]]) { quit_now = true; break; } switch (src[src_used]) { case '\\': state = BACKSLASH; break; case '[': if (src[src_used+1] == '^' && src[src_used+2] == ']') { // Get rid of degenerate case: src_used += 2; if (dst) dst[dst_used] = '\\'; ++dst_used; if (dst) dst[dst_used] = '^'; ++dst_used; } else { if (dst) dst[dst_used] = '('; ++dst_used; state = BRACKET_FIRST; } break; case '*': if (dst) dst[dst_used] = '('; ++dst_used; if (dst) dst[dst_used] = '['; ++dst_used; if (dst) dst[dst_used] = '^'; ++dst_used; if (dst) dst[dst_used] = '/'; ++dst_used; if (dst) dst[dst_used] = ']'; ++dst_used; if (dst) dst[dst_used] = '*'; ++dst_used; if (dst) dst[dst_used] = ')'; ++dst_used; break; case '?': if (dst) dst[dst_used] = '('; ++dst_used; if (dst) dst[dst_used] = '['; ++dst_used; if (dst) dst[dst_used] = '^'; ++dst_used; if (dst) dst[dst_used] = '/'; ++dst_used; if (dst) dst[dst_used] = ']'; ++dst_used; if (dst) dst[dst_used] = ')'; ++dst_used; break; case '{': if (dst) dst[dst_used] = '('; ++dst_used; ++src_used; while (true) { size_t sub_src_used, sub_dst_used; WvString errstr = glob_to_regex(&src[src_used], sub_src_used, dst? &dst[dst_used]: NULL, sub_dst_used, brace_quit_chars); if (errstr) return errstr; src_used += sub_src_used; dst_used += sub_dst_used; if (src[src_used] == '}') break; else if (src[src_used] != ',') return WvString("Unfinished brace expression (index %s)", src_used); if (dst) dst[dst_used] = '|'; ++dst_used; ++src_used; } if (dst) dst[dst_used] = ')'; ++dst_used; break; case '^': case '.': case '$': case '(': case ')': case '|': case '+': if (dst) dst[dst_used] = '\\'; ++dst_used; if (dst) dst[dst_used] = src[src_used]; ++dst_used; break; default: if (dst) dst[dst_used] = src[src_used]; ++dst_used; break; } break; case BACKSLASH: switch (src[src_used]) { case '^': case '.': case '$': case '(': case ')': case '|': case '+': case '[': case '{': case '*': case '?': case '\\': if (dst) dst[dst_used] = '\\'; ++dst_used; // fall through.. default: if (dst) dst[dst_used] = src[src_used]; ++dst_used; break; } state = NORMAL; break; case BRACKET_FIRST: switch (src[src_used]) { case '!': if (dst) dst[dst_used] = '['; ++dst_used; if (dst) dst[dst_used] = '^'; ++dst_used; break; case '^': if (dst) dst[dst_used] = '\\'; ++dst_used; if (dst) dst[dst_used] = '^'; ++dst_used; if (dst) dst[dst_used] = '|'; ++dst_used; if (dst) dst[dst_used] = '['; ++dst_used; break; case '/': return WvString("Slash not allowed in bracket expression (index %s)", src_used); default: if (dst) dst[dst_used] = '['; ++dst_used; if (dst) dst[dst_used] = src[src_used]; ++dst_used; break; } state = BRACKET; break; case BRACKET: switch (src[src_used]) { case ']': if (dst) dst[dst_used] = ']'; ++dst_used; if (dst) dst[dst_used] = ')'; ++dst_used; state = NORMAL; break; case '/': return WvString("Slash not allowed in bracket expression (index %s)", src_used); default: if (dst) dst[dst_used] = src[src_used]; ++dst_used; break; } break; } if (!quit_now) ++src_used; } if (state == BRACKET || state == BRACKET_FIRST) return WvString("Unfinished bracket expression (index %s)", src_used); else if (state == BACKSLASH) return WvString("Unfinished backslash expression (index %s)", src_used); else return WvString::null; } WvString WvGlob::glob_to_regex(WvStringParm glob, WvString *errstr) { if (glob.isnull()) { if (errstr) *errstr = WvString("Glob is NULL"); return WvString::null; } size_t src_used, dst_used; WvString local_errstr = glob_to_regex(glob, src_used, NULL, dst_used, normal_quit_chars); if (!!local_errstr) { if (errstr) *errstr = local_errstr; return WvString::null; } WvString result; result.setsize(1+dst_used+1+1); char *dst = result.edit(); *dst++ = '^'; local_errstr = glob_to_regex(glob, src_used, dst, dst_used, normal_quit_chars); if (!!local_errstr) { if (errstr) *errstr = local_errstr; return WvString::null; } dst += dst_used; *dst++ = '$'; *dst++ = '\0'; return result; } wvstreams-4.6.1/utils/strcrypt.cc0000644000175000001440000000271011202637334016134 0ustar wlachusers#include "strutils.h" #ifndef MACOS #include #endif #include #include /**. * Before calling this function, you should call srandom(). * When 2 identical strings are encrypted, they will not return the same * encryption. Also, str does not need to be less than 8 chars as UNIX crypt * says, although it only works on the first 8 characters. */ WvString passwd_crypt(const char *str) { static char saltchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; char salt[3], *result; salt[0] = saltchars[random() % (sizeof(saltchars) - 1)]; salt[1] = saltchars[random() % (sizeof(saltchars) - 1)]; salt[2] = 0; result = crypt(str, salt); if (!result) return "*"; WvString s(result); return s; } /**. * Before calling this function, you should call srandom(). * When 2 identical strings are encrypted, they will not return the same * encryption. Also, str does not need to be less than 8 chars as we're * using the glibc md5 algorithm. */ WvString passwd_md5(const char *str) { static char saltchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; char salt[12], *result; salt[0] = '$'; salt[1] = '1'; salt[2] = '$'; for (int i = 3; i < 11; ++i) salt[i] = saltchars[random() % (sizeof(saltchars) - 1)]; salt[11] = 0; result = crypt(str, salt); if (!result) return "*"; WvString s(result); return s; } wvstreams-4.6.1/utils/wvmagiccircle.cc0000644000175000001440000000346411036722347017074 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A circular queue that can be accessed across fork(). */ #include "wvmagiccircle.h" #include WvMagicCircle::WvMagicCircle(size_t _size) : shm(_size + 1 + 2*sizeof(int)), head(((int*)shm.buf)[0]), tail(((int*)shm.buf)[1]) { assert((int)_size > 0); head = tail = 0; size = _size + 1; // a circular queue uses one extra byte circle = shm.cbuf + 2*sizeof(int); if (shm.geterr()) seterr(shm); } WvMagicCircle::~WvMagicCircle() { // nothing special } size_t WvMagicCircle::used() { int x = tail - head; if (x < 0) x += size; assert(x >= 0); assert(x < size); return x; } size_t WvMagicCircle::put(const void *data, size_t len) { size_t max = left(); size_t chunk1; if (len > max) len = max; chunk1 = size - tail; if (len < chunk1) chunk1 = len; #if 0 WvLog log("put", WvLog::Info); log("put: head %s, tail %s, size %s, len %s, chunk1 %s\n", head, tail, size, len, chunk1); #endif memcpy(circle + tail, data, chunk1); if (chunk1 < len) memcpy(circle, (char *)data + chunk1, len - chunk1); tail = (tail + len) % size; return len; } size_t WvMagicCircle::get(void *data, size_t len) { size_t max = used(); size_t chunk1; if (len > max) len = max; chunk1 = size - head; if (chunk1 > len) chunk1 = len; memcpy(data, circle + head, chunk1); if (chunk1 < len) memcpy((char *)data + chunk1, circle, len - chunk1); head = (head + len) % size; return len; } size_t WvMagicCircle::skip(size_t len) { size_t max = used(); if (len > max) len = max; head = (head + len) % size; return len; } wvstreams-4.6.1/utils/wvrateadjust.cc0000644000175000001440000000673311036722347017002 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvRateAdjust is a WvEncoder that makes sure data comes out of it at a * given average rate. * * See wvrateadjust.h. */ #include "wvrateadjust.h" WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base, int _orate) #if 0 : log("RateAdj", WvLog::Debug5) #endif { orate_n = _orate; orate_d = 1; match_rate = NULL; init(_sampsize, _irate_base); } WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base, WvRateAdjust *_match_rate) #if 0 : log("RateAdj", WvLog::Debug5) #endif { match_rate = _match_rate; assert(match_rate); orate_n = match_rate->irate_n; orate_d = match_rate->irate_d; init(_sampsize, _irate_base); } void WvRateAdjust::init(int _sampsize, int _irate_base) { sampsize = _sampsize; irate_n = _irate_base * 10; irate_d = 10; epoch = wvtime(); epoch.tv_sec--; bucket = 0; } // we always use all input samples and produce an appropriate number of // output samples. bool WvRateAdjust::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { if (!inbuf.used()) return true; assert((inbuf.used() % sampsize) == 0); // can't deal with partial samples WvTime now = wvtime(); unsigned isamps = inbuf.used() / sampsize; // match our output rate to another stream's input rate, if requested if (match_rate) { orate_n = match_rate->irate_n; orate_d = match_rate->irate_d; } // adjust the input rate estimate if (!epoch.tv_sec) epoch = now; irate_n += isamps * 10; irate_d = msecdiff(wvtime(), epoch) / 100; if (!irate_d) irate_d = 1; #if 0 log("irate=%s (%s/%s), orate=%s (%s/%s), bucket=%s\n", getirate(), irate_n, irate_d, getorate(), orate_n, orate_d, bucket); #endif // reduce the rate estimate if it's getting out of control FIXME: // this method is (almost) unbearably cheesy because it's very // "blocky" - it doesn't happen every time, so it'll cause sudden // jumps from one value to the next. Hopefully not a big deal, // since the input rate is supposed to be constant anyway. The // hardcoded constants are also rather weird. if (irate_d > 100) // ten seconds { epoch.tv_sec++; // time now starts one second later irate_n = irate_n * (irate_d - 10)/irate_d; irate_d -= 10; #if 0 log(" JUMP! new irate=%s (%s/%s)\n", getirate(), irate_n, irate_d); #endif } int plus = orate_n * irate_d, minus = irate_n * orate_d; //log("plus=%s, minus=%s, ", plus, minus); unsigned omax = isamps + isamps/2; //log("isamps=%s, omax=%s\n", isamps, omax); const unsigned char *iptr = inbuf.get(isamps * sampsize); unsigned char *ostart, *optr; ostart = optr = outbuf.alloc(omax * sampsize); // copy the buffers using the "Bresenham line-drawing" algorithm. for (unsigned s = 0; s < isamps; s++, iptr += sampsize) { bucket += plus; //log("s=%s, bucket=%s (+%s, -%s)\n", s, bucket, plus, minus); while (bucket >= minus) { // allocate more buffer space if needed if ((unsigned)(optr - ostart) >= omax * sampsize) ostart = optr = outbuf.alloc(omax * sampsize); for (int i = 0; i < sampsize; i++) optr[i] = iptr[i]; optr += sampsize; bucket -= minus; } } unsigned un = omax*sampsize - (optr - ostart); //log("unalloc %s/%s (%s)\n", un, omax*sampsize, optr-ostart); outbuf.unalloc(un); return true; } wvstreams-4.6.1/utils/wvattrs.cc0000644000175000001440000000326311044160724015756 0ustar wlachusers#include "wvattrs.h" WvAttrs::WvAttrs() : attrlist(NULL), attrlen(0) { } WvAttrs::WvAttrs(const WvAttrs ©) : attrlist(NULL), attrlen(copy.attrlen) { if (copy.attrlen) { attrlist = (char *)malloc((copy.attrlen + 1) * sizeof(char)); memcpy(attrlist, copy.attrlist, copy.attrlen + 1); } } WvAttrs::~WvAttrs() { free(attrlist); } char *WvAttrs::_get(WvStringParm name) const { if (!attrlist) return NULL; const char *curpos = attrlist; while (*curpos) { const char *const valoffset = curpos + strlen(curpos) + 1; if (!strcmp(curpos, name.cstr())) return (char *)valoffset; //value curpos = valoffset + strlen(valoffset) + 1; } return NULL; } void WvAttrs::set(WvStringParm name, WvStringParm value) { if (!name) return; const int namelen = name.len(); char *exists = _get(name); if (exists) { //We're trying to readd a key. Sigh. Oh well, delete and readd! const int toremove = namelen + strlen(exists) + 2; exists -= namelen + 1; //index of name, rather than value /* Length of part after what we want to remove */ const int endpart = attrlen - (exists - attrlist) - toremove + 1; memmove(exists, exists + toremove, endpart); attrlen -= toremove; attrlist = (char *)realloc(attrlist, (attrlen + 1) * sizeof(char)); } if (!value) /* Make a null or empty value a delete */ return; const unsigned int totallen = namelen + value.len() + 2; attrlist = (char *)realloc(attrlist, (attrlen + totallen + 1)*sizeof(char)); char *const beginloc = attrlist + attrlen; strcpy(beginloc, name.cstr()); strcpy(beginloc + namelen + 1, value.cstr()); attrlen += totallen; attrlist[attrlen] = 0; } wvstreams-4.6.1/utils/wvhash.cc0000644000175000001440000000125011036722347015544 0ustar wlachusers#include "wvhash.h" // Note: this hash function is case-insensitive since it ignores the // bit in ASCII that defines case. You may want to take advantage of this. unsigned int WvHash(const char *s) { unsigned hash = 0, slide, andval; if (!s) return 0; slide = sizeof(hash)*8 - 5; andval = 0x1F << slide; while (*s) hash = (hash<<4) ^ (*(s++) & 0x1F) ^ ((hash & andval) >> slide); return hash; } unsigned WvHash(WvStringParm s) { return !s ? 0 : WvHash((const char *)s); } // FIXME: does this suck? unsigned WvHash(const int &i) { return i; } unsigned WvHash(const void *p) { return reinterpret_cast(p); } wvstreams-4.6.1/utils/wvlinklist.cc0000644000175000001440000000476411036722347016467 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Implementation of a Linked List management class, or rather, macros that * declare arbitrary linked list management classes. * * wvlinklist.h does all the real work. */ #include "wvlinklist.h" WvLink::WvLink(void *_data, WvLink *prev, WvLink *&tail, bool _autofree, const char *_id) { data = _data; next = prev->next; if (!next) tail = this; prev->next = this; autofree = _autofree; id = _id; } size_t WvListBase::count() const { WvLink *l; size_t n = 0; for (l = head.next; l; l = l->next) n++; return n; } void WvListBase::reverse() { WvLink *prev, *curr, *next; if (!head.next || !head.next->next) return; prev = head.next; curr = prev->next; do { next = curr->next; curr->next = prev; prev = curr; curr = next; } while(curr); tail = head.next; tail->next = NULL; head.next = prev; } WvLink *WvListBase::IterBase::find(const void *data) { for (rewind(); next(); ) if (link->data == data) break; return link; } WvLink *WvListBase::IterBase::find_next(const void *data) { if (link) { if (link->data == data) return link; for (rewind(); next(); ) if (link->data == data) break; } return link; } #if 0 static WvListBase::SorterBase::CompareFunc *actual_compare = NULL; static int magic_compare(const void *_a, const void *_b) { WvLink *a = *(WvLink **)_a, *b = *(WvLink **)_b; return actual_compare(a->data, b->data); } void WvListBase::SorterBase::rewind(CompareFunc *cmp) { if (array) delete array; array = lptr = NULL; int n = list->count(); array = new WvLink * [n+1]; WvLink **aptr = array; // fill the array with data pointers for sorting, so that the user doesn't // have to deal with the WvLink objects. Put the WvLink pointers back // in after sorting. IterBase i(*list); aptr = array; for (i.rewind(); i.next(); ) { *aptr = i.cur(); aptr++; } *aptr = NULL; // sort the array. "Very nearly re-entrant" (unless the compare function // ends up being called recursively or something really weird...) CompareFunc *old_compare = actual_compare; actual_compare = cmp; qsort(array, n, sizeof(WvLink *), magic_compare); actual_compare = old_compare; lptr = NULL; // subsequent next() will set it to first element. } #endif wvstreams-4.6.1/utils/wvstringcache.cc0000644000175000001440000000364511036722347017125 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Definition for the WvStringCache class. See wvstringcache.h. */ #include "wvstringcache.h" #include "wvstringlist.h" WvStringTable *WvStringCache::t; int WvStringCache::refcount; size_t WvStringCache::clean_threshold; WvStringCache::WvStringCache() { refcount++; if (!t) { t = new WvStringTable; clean_threshold = 0; } } WvStringCache::~WvStringCache() { refcount--; if (!refcount) { delete t; t = NULL; clean_threshold = 0; } else clean(); } WvString WvStringCache::get(WvStringParm s) { // return s; // disable cache WvString *ret = (*t)[s]; if (ret) { // printf("found(%s)\n", s.cstr()); return *ret; } else { // printf(" new(%s)\n", s.cstr()); ret = new WvString(s); t->add(ret, true); return *ret; } } void WvStringCache::clean() { // do we actually need to clean yet? Skip it if we haven't added too // many items since the last clean, since cleaning is pretty slow. if (t->count() < clean_threshold) return; WvStringList l; // use a two-stage process so the iterator doesn't get messed up // FIXME: this might actually be unnecessary with WvScatterHash, but // someone should actually confirm that before taking this out. { WvStringTable::Iter i(*t); for (i.rewind(); i.next(); ) { if (i->is_unique()) // last remaining instance { // printf("CLEANUP(%s)\n", i->cstr()); l.append(i.ptr(), false); } } } // printf("CLEANUP-1: %d elements at start (%d to remove)\n", // (int)t->count(), (int)l.count()); { WvStringList::Iter i(l); for (i.rewind(); i.next(); ) t->remove(i.ptr()); } clean_threshold = t->count() + t->count()/10 + 1; // printf("CLEANUP-2: %d elements left (thres=%d).\n", // (int)t->count(), (int)clean_threshold); } wvstreams-4.6.1/utils/wvcrashread.sh0000777000175000001440000000000011123257330021025 2wvcrashreadustar wlachuserswvstreams-4.6.1/utils/wvwordwrap.cc0000644000175000001440000000522611036722347016475 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A very simple word wrapping encoder. */ #include "wvwordwrap.h" WvWordWrapEncoder::WvWordWrapEncoder(int _maxwidth) : maxwidth(_maxwidth) { line = new char[maxwidth]; _reset(); } WvWordWrapEncoder::~WvWordWrapEncoder() { deletev line; } bool WvWordWrapEncoder::_reset() { width = 0; curindex = wordindex = 0; inword = false; return true; } bool WvWordWrapEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) { while (inbuf.used() != 0) { int ch = inbuf.getch(); switch (ch) { case '\n': if (! inword) curindex = 0; flushline(outbuf); width = 0; outbuf.putch('\n'); break; case ' ': if (inword) flushline(outbuf); width += 1; if (width <= maxwidth) line[curindex++] = ch; break; case '\t': if (inword) flushline(outbuf); width = (width + 8) & ~7; if (width <= maxwidth) line[curindex++] = ch; break; default: if (width >= maxwidth) { if (! inword) { // discard trailing whitespace curindex = wordindex = 0; width = 0; } else if (wordindex == 0) { // insert hard line break flushline(outbuf); width = 0; } else { // insert soft line break curindex -= wordindex; memmove(line, line + wordindex, curindex); wordindex = 0; width = curindex; } outbuf.putch('\n'); } if (! inword) { inword = true; wordindex = curindex; } width += 1; line[curindex++] = ch; break; } } if (flush) flushline(outbuf); return true; } void WvWordWrapEncoder::flushline(WvBuf &outbuf) { outbuf.put(line, curindex); curindex = wordindex = 0; inword = false; } wvstreams-4.6.1/utils/wvcrashread0000755000175000001440000001513411036722347016202 0ustar wlachusers#!/usr/bin/perl # # Worldvisions Weaver Software: # Copyright (C) 2005 Net Integration Technologies, Inc. # # Post-process WvCrash output using GDB, to try to figure out exactly # which line things died upon. # # The advantage of using this programme over a plain stack dump is # that it is clever enough to figure out relative offsets to a # function, so you don't need the exact same object file as the one # that crashed. With extra cleverness, we even span symbol manging # across different versions of G++. use strict; use warnings; use Cwd; use File::Basename; use File::Find (); use FileHandle; use IPC::Open2; my $DEBUG = $ENV{DEBUG}; sub debug { print(STDERR @_) if $DEBUG; } sub find_programme($) { my $target = shift(@_); return $target if (-f $target && -x $target); my $result; my $endtime = time() + 20; # Stop searching after 20 seconds. my $cwd = cwd(); # Save the working dir so we can go back. my $wanted = sub { if ($_ eq $target && -f $_ && -x $_) { $result = $File::Find::name; die; # Break out of the File::Find::find. } elsif (time() > $endtime){ die; # Took too long. } }; # Traverse desired filesystems eval { File::Find::find({wanted => $wanted, follow_fast => 1, follow_skip => 2}, '.'); }; chdir($cwd); return $result; } sub gdb_init($) { my ($programme) = @_; my $gdb_prompt = qr/(?:\(gdb\) )+/; my $gdb_flush = "echo \\n\n"; # Flush gdb's stdout my $gdb_addr = sub ($$$) { my ($Reader, $Writer, $function) = @_; debug("-> info addr $function\n"); print($Writer "info addr $function\n"); print($Writer $gdb_flush); my $first = 0; while (<$Reader>) { debug("<- $_"); if (/^$gdb_prompt\s*Symbol "(.*?)" is .* (0x[0-9A-Fa-f]+)/) { return ($1, $2); } last if (/^$gdb_prompt$/ && $first); $first = 1; } # Returns the human-readable function name, and the starting address return ($function, undef); }; my $gdb_line = sub ($$$$) { my ($Reader, $Writer, $addr, $offset) = @_; debug("-> info line *$addr+$offset\n"); print($Writer "info line *$addr+$offset\n"); print($Writer $gdb_flush); my $first = 0; while (<$Reader>) { debug("<- $_"); if (/^$gdb_prompt\s*Line ([0-9]+) of "(.*?)" starts at /) { return ($2, $1); } last if (/^$gdb_prompt$/ && $first); $first = 1; } # Returns the filename and line number. return (undef, undef); }; # Initialise GDB my ($Reader, $Writer); debug("gdb '$programme'\n"); my $pid = open2($Reader, $Writer, "gdb '$programme' 2>&1") or die; print($Writer "set width 2000\n"); print($Writer "set height 20000\n"); print($Writer "break main\n"); print($Writer "run\n"); print($Writer $gdb_flush); while (<$Reader>) { debug("<- $_"); last if (/^$gdb_prompt$/); } return sub ($) { my ($string) = @_; # Parse the input string. my ($binary, $absolute) = ($string =~ /^(.*?)([\[\(].*)/); my ($function, $offset) = ($absolute =~ /^\((.*?)\+(.*?)\)/); $absolute =~ s/.*\[(.*?)\].*/$1/; my ($file, $line) = ("--", "--"); unless (defined($function)) { $function = "file: $binary"; } else { my $addr; # Try with the mangled function name ($function, $addr) = &$gdb_addr($Reader, $Writer, $function); unless (defined($addr)) { # Try with c++filt mangled function my $filtered = `c++filt '$function'` or return ($function, undef, undef); chomp($filtered); # Turn () into (void) for old GDB $filtered =~ s/(?) { chomp($string); # We drive a state machine here, to figure out what we should do next. STATE: for ($state) { if (/begin/) { undef $programme; undef $signum; # We will want to skip anything that isn't the beginning # of a WvCrash file. if ($string =~ / dying on signal \d+/) { $state = "new"; goto STATE; } } elsif (/new/) { # Extract the information out of the first line of the header. if ($string =~ /^(.*?) dying on signal (\d+)(.*)?/) { $programme = $1; $signum = $2; my $signame = $3 || ""; my $version = ""; if ($programme =~ s/\s+\((.*)\)//) { $version = " ($1)" if $1; } $programme = basename($programme); # Relative path print("$programme$version dying on signal $signum$signame\n"); if ($programme_path = find_programme($programme)) { $state = "header"; } else { $state = "missing"; } } } elsif (/header/) { # We don't actually have much of a header right now, so this # merely transitions to the backtrace. if ($string =~ /^Backtrace:/) { unless (defined($programme) && defined($signum)) { $state = "corrupt"; } else { $gdb_parse = gdb_init($programme_path); $state = "backtrace"; } } # Echo back header information. It's not important to parse, # but it might be nice to display. print "$string\n"; } elsif (/backtrace/) { # Keep reading backtrace information until we stop seeing # stack traces. if ($string =~ /\[0x[0-9A-Fa-f]+\]$/) { my ($function, $file, $line) = &$gdb_parse($string); # Eat up some extra spaces $function =~ s/,\s+/,/g; $function =~ s/\s+\*/*/g; $function =~ s/\s+&/&/g; $function =~ s/\s+&/&/g; $function =~ s/\s+\(/\(/g; $state = "backtrace"; if (not defined($file)) { printf("%-40s --:--\n", $function); } else { printf("%-40s %s:%s\n", $function, $file, $line); } } else { $state = "begin"; goto STATE; } } elsif (/missing/) { print(STDERR "Could not find the '$programme' program! ", "Aborting.\n"); exit(1); } elsif (/corrupt/) { print(STDERR "Unrecognized WvCrash output. Aborting.\n"); exit(1); } else { die("Internal wvcrashread error. Aborting."); } } } wvstreams-4.6.1/utils/wvcrash.cc0000644000175000001440000004100011122167564015716 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Routines to generate a stack backtrace automatically when a program * crashes. */ #include "wvcrash.h" #include "wvtask.h" #include #include #include #include #include #include #include #ifndef _WIN32 # include # include #endif #ifndef WVCRASH_USE_SIGALTSTACK # define WVCRASH_USE_SIGALTSTACK 1 #endif // FIXME: this file mostly only works in Linux #ifdef __linux # include #include #ifdef __USE_GNU static const char *argv0 = program_invocation_short_name; #else static const char *argv0 = "UNKNOWN"; #endif // __USE_GNU #if WVCRASH_USE_SIGALTSTACK static const size_t altstack_size = 1048576; // wvstreams can be a pig static char altstack[altstack_size]; #endif // Reserve enough buffer for a screenful of programme. static const int buffer_size = 2048 + wvcrash_ring_buffer_size; static char desc[buffer_size]; // write a string 'str' to fd static void wr(int fd, const char *str) { write(fd, str, strlen(str)); } // convert 'num' to a string and write it to fd. static void wrn(int fd, int num) { int tmp; char c; if (num < 0) { wr(fd, "-"); num = -num; } else if (num == 0) { wr(fd, "0"); return; } tmp = 0; while (num > 0) { tmp *= 10; tmp += num%10; num /= 10; } while (tmp > 0) { c = '0' + (tmp%10); write(fd, &c, 1); tmp /= 10; } } // convert 'addr' to hex and write it to fd. static void wra(int fd, const void *addr) { const unsigned int ptrbitsshift = (sizeof(ptrdiff_t) << 3) - 4; char digits[] = "0123456789ABCDEF"; write(fd, "0x", 2); for (int shift=ptrbitsshift; shift>=0; shift-=4) write(fd, &digits[(((ptrdiff_t)addr)>>shift)&0xF], 1); } static void wvcrash_real(int sig, int fd, pid_t pid) { static void *trace[64]; static char *signame = strsignal(sig); wr(fd, argv0); if (desc[0]) { wr(fd, " ("); wr(fd, desc); wr(fd, ")"); } wr(fd, " dying on signal "); wrn(fd, sig); if (signame) { wr(fd, " ("); wr(fd, signame); wr(fd, ")\n"); } // Write out the PID and PPID. static char pid_str[32]; wr(fd, "\nProcess ID: "); snprintf(pid_str, sizeof(pid_str), "%d", getpid()); pid_str[31] = '\0'; wr(fd, pid_str); wr(fd, "\nParent's process ID: "); snprintf(pid_str, sizeof(pid_str), "%d", getppid()); pid_str[31] = '\0'; wr(fd, pid_str); wr(fd, "\n"); #if WVCRASH_USE_SIGALTSTACK // Determine if this has likely been a stack overflow const void *last_real_stack_frame; for (;;) { last_real_stack_frame = __builtin_frame_address(0); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = __builtin_frame_address(1); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = __builtin_frame_address(2); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = __builtin_frame_address(3); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = __builtin_frame_address(4); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = __builtin_frame_address(5); if (last_real_stack_frame == NULL || last_real_stack_frame < &altstack[0] || last_real_stack_frame >= &altstack[altstack_size]) break; last_real_stack_frame = NULL; break; } if (last_real_stack_frame != NULL) { wr(fd, "\nLast real stack frame: "); wra(fd, last_real_stack_frame); const void *top_of_stack = WvTaskMan::current_top_of_stack(); wr(fd, "\nTop of stack: "); wra(fd, top_of_stack); size_t stack_size = size_t(top_of_stack) - size_t(last_real_stack_frame); wr(fd, "\nStack size: "); wrn(fd, int(stack_size)); size_t stack_size_limit = WvTaskMan::current_stacksize_limit(); if (stack_size_limit > 0) { wr(fd, "\nStack size rlimit: "); wrn(fd, int(stack_size_limit)); if (stack_size > stack_size_limit) wr(fd, " DEFINITE STACK OVERFLOW"); else if (stack_size + 16384 > stack_size_limit) wr(fd, " PROBABLE STACK OVERFLOW"); } wr(fd, "\n"); } #endif // Write out the contents of the ring buffer { const char *ring; bool first = true; while ((ring = wvcrash_ring_buffer_get()) != NULL) { if (first) { first = false; wr(fd, "\nRing buffer:\n"); } wr(fd, ring); } } // Write out the assertion message, as logged by __assert*_fail(), if any. { const char *assert_msg = wvcrash_read_assert(); if (assert_msg && assert_msg[0]) { wr(fd, "\nAssert:\n"); wr(fd, assert_msg); } } // Write out the note, if any. { const char *will_msg = wvcrash_read_will(); if (will_msg && will_msg[0]) { wr(fd, "\nLast Will and Testament:\n"); wr(fd, will_msg); wr(fd, "\n"); } } if (WvCrashInfo::in_stream_state != WvCrashInfo::UNUSED && WvCrashInfo::in_stream) { const char *state = NULL; switch (WvCrashInfo::in_stream_state) { case WvCrashInfo::UNUSED: // Can't possibly get here. break; case WvCrashInfo::PRE_SELECT: state = "\nStream in pre_select: "; break; case WvCrashInfo::POST_SELECT: state = "\nStream in post_select: "; break; case WvCrashInfo::EXECUTE: state = "\nStream in execute: "; break; } if (state) { static char ptr_str[32]; snprintf(ptr_str, sizeof(ptr_str), "%p", WvCrashInfo::in_stream); ptr_str[sizeof(ptr_str) - 1] = '\0'; wr(fd, state); wr(fd, WvCrashInfo::in_stream_id && WvCrashInfo::in_stream_id[0] ? WvCrashInfo::in_stream_id : "unknown stream"); wr(fd, " ("); wr(fd, ptr_str); wr(fd, ")\n"); } } wr(fd, "\nBacktrace:\n"); backtrace_symbols_fd(trace, backtrace(trace, sizeof(trace)/sizeof(trace[0])), fd); if (pid > 0) { // Wait up to 10 seconds for child to write wvcrash file in case there // is limited space availible on the device; wvcrash file is more // useful than core dump int i; struct timespec ts = { 0, 100*1000*1000 }; close(fd); for (i=0; i < 100; ++i) { if (waitpid(pid, NULL, WNOHANG) == pid) break; nanosleep(&ts, NULL); } } // we want to create a coredump, and the kernel seems to not want to do // that if we send ourselves the same signal that we're already in. // Whatever... just send a different one :) if (sig == SIGABRT) sig = SIGBUS; else if (sig != 0) sig = SIGABRT; signal(sig, SIG_DFL); raise(sig); } // Hint: we can't do anything really difficult here, because the program is // probably really confused. So we should try to limit this to straight // kernel syscalls (ie. don't fiddle with FILE* or streams or lists, just // use straight file descriptors.) // // We fork a subprogram to do the fancy stuff like sending email. // void wvcrash(int sig) { int fds[2]; pid_t pid; signal(sig, SIG_DFL); wr(2, "\n\nwvcrash: crashing!\n"); // close some fds, just in case the reason we're crashing is fd // exhaustion! Otherwise we won't be able to create our pipe to a // subprocess. Probably only closing two fds is possible, but the // subproc could get confused if all the fds are non-close-on-exec and // it needs to open a few files. // // Don't close fd 0, 1, or 2, however, since those might be useful to // the child wvcrash script. Also, let's skip 3 and 4, in case someone // uses them for something. But don't close fd numbers that are *too* // big; if someone ulimits the number of fds we can use, and *that's* // why we're crashing, there's no guarantee that high fd numbers are in // use even if we've run out. for (int count = 5; count < 15; count++) close(count); if (pipe(fds)) wvcrash_real(sig, 2, 0); // just use stderr instead else { pid = fork(); if (pid < 0) wvcrash_real(sig, 2, 0); // just use stderr instead else if (pid == 0) // child { close(fds[1]); dup2(fds[0], 0); // make stdin read from pipe fcntl(0, F_SETFD, 0); execlp("wvcrash", "wvcrash", NULL); // if we get here, we couldn't exec wvcrash wr(2, "wvcrash: can't exec wvcrash binary " "- writing to wvcrash.txt!\n"); execlp("dd", "dd", "of=wvcrash.txt", NULL); wr(2, "wvcrash: can't exec dd to write to wvcrash.txt!\n"); _exit(127); } else if (pid > 0) // parent { close(fds[0]); wvcrash_real(sig, fds[1], pid); } } // child (usually) _exit(126); } static void wvcrash_setup_alt_stack() { #if WVCRASH_USE_SIGALTSTACK stack_t ss; ss.ss_sp = altstack; ss.ss_flags = 0; ss.ss_size = altstack_size; if (ss.ss_sp == NULL || sigaltstack(&ss, NULL)) fprintf(stderr, "Failed to setup sigaltstack for wvcrash: %s\n", strerror(errno)); #endif //WVCRASH_USE_SIGALTSTACK } void wvcrash_add_signal(int sig) { #if WVCRASH_USE_SIGALTSTACK struct sigaction act; memset(&act,0,sizeof(act)); act.sa_handler = wvcrash; sigfillset(&act.sa_mask); act.sa_flags = SA_ONSTACK | SA_RESTART; if (sigaction(sig, &act, NULL)) fprintf(stderr, "Failed to setup wvcrash handler for signal %d: %s\n", sig, strerror(errno)); #else //!WVCRASH_USE_SIGALTSTACK signal(sig, wvcrash); #endif //WVCRASH_USE_SIGALTSTACK } // Secret symbol for initialising the will and assert buffers extern void __wvcrash_init_buffers(const char *program_name); void wvcrash_setup(const char *_argv0, const char *_desc) { if (_argv0) argv0 = basename(_argv0); __wvcrash_init_buffers(argv0); if (_desc) { strncpy(desc, _desc, buffer_size); desc[buffer_size - 1] = '\0'; } else desc[0] = '\0'; wvcrash_setup_alt_stack(); wvcrash_add_signal(SIGSEGV); wvcrash_add_signal(SIGBUS); wvcrash_add_signal(SIGABRT); wvcrash_add_signal(SIGFPE); wvcrash_add_signal(SIGILL); } #elif defined(_WIN32) #include #include #include inline char* last_part(char* in) { int len = strlen(in); char* tmp = in+len; while (tmp > in) { if (*tmp == '/' || *tmp == '\\') return tmp+1; tmp--; } return in; } /** * Call this with a thread context to get a nice callstack. You can get a * thread context either from an exception or by using this code: * CONTEXT ctx; * memset(&ctx, 0, sizeof(CONTEXT)); * ctx.ContextFlags = CONTEXT_FULL; * GetThreadContext(hThread, &ctx); */ int backtrace(CONTEXT &ctx) { HANDLE hProcess = (HANDLE)GetCurrentProcess(); HANDLE hThread = (HANDLE)GetCurrentThread(); SymInitialize(hProcess, NULL, TRUE); STACKFRAME sf; memset(&sf, 0, sizeof(STACKFRAME)); sf.AddrPC.Offset = ctx.Eip; sf.AddrPC.Mode = AddrModeFlat; sf.AddrFrame.Offset = ctx.Ebp; sf.AddrFrame.Mode = AddrModeFlat; sf.AddrStack.Offset = ctx.Esp; sf.AddrStack.Mode = AddrModeFlat; fprintf(stderr, "Generating stack trace......\n"); fprintf(stderr, "%3s %16s:%-10s %32s:%3s %s\n", "Num", "Module", "Addr", "Filename", "Line", "Function Name"); int i = 0; while (StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &sf, &ctx, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL)) { if (sf.AddrPC.Offset == 0) break; // info about module IMAGEHLP_MODULE modinfo; memset(&modinfo, 0, sizeof(IMAGEHLP_MODULE)); modinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE); SymGetModuleInfo(hProcess, sf.AddrPC.Offset, &modinfo); // get some symbols BYTE buffer[1024]; DWORD disp = 0; memset(buffer, 0, sizeof(buffer)); PIMAGEHLP_SYMBOL sym = (PIMAGEHLP_SYMBOL)buffer; sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); sym->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1; SymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &disp, sym); // line numbers anyone? IMAGEHLP_LINE line; SymSetOptions(SYMOPT_LOAD_LINES); DWORD disp2 = 0; memset(&line, 0, sizeof(IMAGEHLP_LINE)); line.SizeOfStruct = sizeof(IMAGEHLP_LINE); SymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &disp2, &line); // output some info now then fprintf(stderr, "%3d. %16s:0x%08X %32s:%-3d %s\n", ++i, modinfo.LoadedImageName[0]?modinfo.LoadedImageName:"unknown", (DWORD)sf.AddrPC.Offset, (line.FileName && line.FileName[0])?last_part(line.FileName):"unknown", (line.FileName && line.FileName[0])?line.LineNumber:0, sym->Name[0]?sym->Name:"unknown"); } SymCleanup(hProcess); return 1; } static void exception_desc(FILE *file, unsigned exception, unsigned data1, unsigned data2) { switch (exception) { case 0xC0000005: { switch (data1) { case 0: fprintf(file, "invalid memory read from address 0x%08X", data2); break; case 1: fprintf(file, "invalid memory write to address 0x%08X", data2); break; default: fprintf(file, "invalid memory access (unknown type %d) at address 0x%08X", data1, data2); break; } } break; case 0xC0000094: fprintf(file, "integer division by zero"); break; default: fprintf(file, "unknown exception (data1=0x%08X, data2=0x%08X)"); break; } } static LONG WINAPI ExceptionFilter( struct _EXCEPTION_POINTERS * pExceptionPointers ) { struct ExceptionInfo { unsigned exception; unsigned unknown[2]; void *ip; unsigned more_unknown; unsigned data1; unsigned data2; }; ExceptionInfo *info = *(ExceptionInfo **)pExceptionPointers; // handle a special exception. Number 3 = forced breakpoint // having __asm int 3; in code will cause windows to ask if // you want to debug the application nicely. if (info->exception==0x80000003) { fprintf(stderr, "Preparing to debug!\n"); return EXCEPTION_CONTINUE_SEARCH; } fprintf(stderr, "--------------------------------------------------------\n"); fprintf(stderr, "Exception 0x%08X:\n ", info->exception); exception_desc(stderr, info->exception, info->data1, info->data2); fprintf(stderr, "\n at instruction 0x%08X in thread 0x%08X\n", info->ip, GetCurrentThreadId()); backtrace(*pExceptionPointers->ContextRecord); fprintf(stderr, "--------------------------------------------------------\n"); return EXCEPTION_EXECUTE_HANDLER; } static bool have_global_exception_handler = false; void setup_console_crash() { if (!have_global_exception_handler) { SetUnhandledExceptionFilter(ExceptionFilter); have_global_exception_handler = true; } } void wvcrash(int sig) {} void wvcrash_setup(const char *_argv0, const char *_desc) {} #else // Not Linux void wvcrash(int sig) {} void wvcrash_add_signal(int sig) {} void wvcrash_setup(const char *_argv0, const char *_desc) {} #endif // Not Linux wvstreams-4.6.1/utils/wvglobdiriter.cc0000644000175000001440000000147211036722347017135 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Globbing directory iterator. * */ #include "wvglobdiriter.h" #include "wvglob.h" WvGlobDirIter::WvGlobDirIter( WvStringParm dirname, WvStringParm glob_str, bool _recurse, bool _skip_mounts, size_t sizeof_stat ) : WvDirIter(dirname, _recurse, _skip_mounts, sizeof_stat), glob(NULL) { if (!glob_str.isnull()) { glob = new WvGlob(glob_str); if (!glob->isok()) { delete glob; glob = NULL; } } } WvGlobDirIter::~WvGlobDirIter() { if (glob) delete glob; } bool WvGlobDirIter::next() { bool result; do { result = WvDirIter::next(); } while (result && glob && !glob->match(ptr()->relname)); return result; } wvstreams-4.6.1/utils/wvcrashbase.cc0000644000175000001440000001036411202637334016556 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Routines to save messages that can be logged when a program crashes. */ #include "wvcrash.h" #include #include #include #include IWvStream *WvCrashInfo::in_stream = NULL; const char *WvCrashInfo::in_stream_id = NULL; enum WvCrashInfo::InStreamState WvCrashInfo::in_stream_state = UNUSED; static const int ring_buffer_order = wvcrash_ring_buffer_order; static const int ring_buffer_size = wvcrash_ring_buffer_size; static const int ring_buffer_mask = ring_buffer_size - 1; static char ring_buffer[ring_buffer_size+1]; static int ring_buffer_start = 0, ring_buffer_used = 0; void wvcrash_ring_buffer_put(const char *str) { wvcrash_ring_buffer_put(str, strlen(str)); } void wvcrash_ring_buffer_put(const char *str, size_t len) { while (len > 0) { int pos = (ring_buffer_start + ring_buffer_used) & ring_buffer_mask; ring_buffer[pos] = *str++; --len; if (ring_buffer_used == ring_buffer_size) ring_buffer_start = (ring_buffer_start + 1) & ring_buffer_mask; else ++ring_buffer_used; } } const char *wvcrash_ring_buffer_get() { if (ring_buffer_used == 0) return NULL; const char *result; if (ring_buffer_start + ring_buffer_used >= ring_buffer_size) { ring_buffer[ring_buffer_size] = '\0'; result = &ring_buffer[ring_buffer_start]; ring_buffer_used -= ring_buffer_size - ring_buffer_start; ring_buffer_start = 0; } else { ring_buffer[ring_buffer_start + ring_buffer_used] = '\0'; result = &ring_buffer[ring_buffer_start]; ring_buffer_start += ring_buffer_used; ring_buffer_used = 0; } return result; } // FIXME: leaving of a will and catching asserts mostly only works in Linux #ifdef __linux #ifdef __USE_GNU static const char *argv0 = program_invocation_short_name; #else static const char *argv0 = "UNKNOWN"; #endif // __USE_GNU // Reserve enough buffer for a screenful of programme. static const int buffer_size = 2048; static char will_msg[buffer_size]; static char assert_msg[buffer_size]; extern "C" { // Support assert(). void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function) { // Set the assert message that WvCrash will dump. snprintf(assert_msg, buffer_size, "%s: %s:%u: %s: Assertion `%s' failed.\n", argv0, __file, __line, __function, __assertion); assert_msg[buffer_size - 1] = '\0'; // Emulate the GNU C library's __assert_fail(). fprintf(stderr, "%s: %s:%u: %s: Assertion `%s' failed.\n", argv0, __file, __line, __function, __assertion); abort(); } // Wrapper for standards compliance. void __assert(const char *__assertion, const char *__file, unsigned int __line, const char *__function) { __assert_fail(__assertion, __file, __line, __function); } // Support the GNU assert_perror() extension. void __assert_perror_fail(int __errnum, const char *__file, unsigned int __line, const char *__function) { // Set the assert message that WvCrash will dump. snprintf(assert_msg, buffer_size, "%s: %s:%u: %s: Unexpected error: %s.\n", argv0, __file, __line, __function, strerror(__errnum)); assert_msg[buffer_size - 1] = '\0'; // Emulate the GNU C library's __assert_perror_fail(). fprintf(stderr, "%s: %s:%u: %s: Unexpected error: %s.\n", argv0, __file, __line, __function, strerror(__errnum)); abort(); } } // extern "C" // This function is meant to support people who wish to leave a last will // and testament in the WvCrash. void wvcrash_leave_will(const char *will) { if (will) { strncpy(will_msg, will, buffer_size); will_msg[buffer_size - 1] = '\0'; } else will_msg[0] = '\0'; } const char *wvcrash_read_will() { return will_msg; } const char *wvcrash_read_assert() { return assert_msg; } void __wvcrash_init_buffers(const char *program_name) { if (program_name) argv0 = program_name; will_msg[0] = '\0'; assert_msg[0] = '\0'; } #else // this is NOT __linux void wvcrash_leave_will(const char *will) {} const char *wvcrash_read_will() { return NULL; } #endif // __linux wvstreams-4.6.1/utils/wvassert.cc0000644000175000001440000000177011036722347016131 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 2005 Net Integration Technologies, Inc. * * Helper classes and functions to add more information to WvCrashes. */ #include "wvassert.h" WvCrashWill::WvCrashWill(const char *will) : old_will(wvcrash_read_will()) { wvcrash_leave_will(will); } WvCrashWill::WvCrashWill(WVSTRING_FORMAT_DEFN) : old_will(wvcrash_read_will()) { // We use a WvFastString here, because it is a temporary. init() // will duplicate the string into a local buffer, so don't you // worry. wvcrash_leave_will(WvFastString(WVSTRING_FORMAT_CALL)); } void WvCrashWill::rewrite(const char *will) { // Don't touch old_will. wvcrash_leave_will(will); } void WvCrashWill::rewrite(WVSTRING_FORMAT_DEFN) { // Again, since wvcrash_leave_will will duplicate the string, we // can use a WvFastString. rewrite(WvFastString(WVSTRING_FORMAT_CALL)); } WvCrashWill::~WvCrashWill() { // Put the old will back. wvcrash_leave_will(old_will); } wvstreams-4.6.1/utils/wvhashtable.cc0000644000175000001440000000450611036722347016563 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Small, efficient, type-safe hash table class. See wvhashtable.h. */ #include "wvhashtable.h" #include "wvstring.h" // we do not accept the _numslots value directly. Instead, we find the // next number of slots which is >= _numslots and one less then a power // of 2. This usually results in a fairly good hash table size. WvHashTableBase::WvHashTableBase(unsigned _numslots) { int slides = 1; while ((_numslots >>= 1) != 0) slides++; numslots = (1 << slides) - 1; } // never returns NULL. If the object is not found, the 'previous' link // is the last one in the list. WvLink *WvHashTableBase::prevlink(WvListBase *wvslots, const void *data, unsigned hash) const { WvListBase::IterBase i(wvslots[hash % numslots]); WvLink *prev; i.rewind(); for (prev = i.cur(); prev->next; prev = i.next()) { if (compare(data, prev->next->data)) break; } return prev; } void *WvHashTableBase::genfind(WvListBase *wvslots, const void *data, unsigned hash) const { WvLink *prev = prevlink(wvslots, data, hash); if (prev->next) return prev->next->data; else return NULL; } size_t WvHashTableBase::count() const { size_t count = 0; for (unsigned i = 0; i < numslots; i++) count += wvslots[i].count(); return count; } bool WvHashTableBase::isempty() const { for (unsigned i = 0; i < numslots; i++) if (! wvslots[i].isempty()) return false; return true; } WvLink *WvHashTableBase::IterBase::next() { // In the best case, we can just look at the next item in the bucket. link = link->next; if (link) return link; // Keep local copies of information, so we don't have to poke into the // data structure. WvLink *_link = NULL; // we would have returned if link were non-NULL WvListBase *begin = tbl->wvslots; WvListBase *cur = begin + tblindex; WvListBase *end = begin + tbl->numslots - 1; // We'll go from the current bucket to the last bucket, in hopes that // one of them will contain something. while (cur < end) { ++cur; _link = cur->head.next; if (_link) break; } tblindex = cur - begin; // Compute the tblindex. link = _link; // Save the link return link; } wvstreams-4.6.1/utils/wvtimeutils.cc0000644000175000001440000000333411077124114016636 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Various little time functions... */ #include "wvtimeutils.h" #include #ifndef _MSC_VER #include #include #endif time_t msecdiff(const WvTime &a, const WvTime &b) { long long secdiff = a.tv_sec - b.tv_sec; long long usecdiff = a.tv_usec - b.tv_usec; long long msecs = secdiff * 1000 + usecdiff / 1000; time_t rval; if (msecs > INT_MAX) rval = INT_MAX; else if (msecs < INT_MIN) rval = INT_MIN; else rval = msecs; return rval; } WvTime wvtime() { struct timeval tv; gettimeofday(&tv, 0); return tv; } WvTime msecadd(const WvTime &a, time_t msec) { WvTime b; b.tv_sec = a.tv_sec + msec / 1000; b.tv_usec = a.tv_usec + (msec % 1000) * 1000; normalize(b); return b; } WvTime tvdiff(const WvTime &a, const WvTime &b) { WvTime c; c.tv_sec = a.tv_sec - b.tv_sec; c.tv_usec = a.tv_usec; if (b.tv_usec > a.tv_usec) { c.tv_sec--; c.tv_usec += 1000000; } c.tv_usec -= b.tv_usec; normalize(c); return c; } static WvTime wvstime_cur = wvtime(); const WvTime &wvstime() { return wvstime_cur; } static void do_wvstime_sync(bool forward_only) { if (!forward_only) { wvstime_cur = wvtime(); } else { WvTime now = wvtime(); if (wvstime_cur < now) wvstime_cur = now; } } void wvstime_sync() { do_wvstime_sync(false); } void wvstime_sync_forward() { do_wvstime_sync(true); } void wvstime_set(const WvTime &_new_time) { wvstime_cur = _new_time; } void wvdelay(int msec_delay) { #ifdef _WIN32 Sleep(msec_delay); #else usleep(msec_delay * 1000); #endif } wvstreams-4.6.1/qt/0000755000175000001440000000000011123776311013220 5ustar wlachuserswvstreams-4.6.1/qt/wvqthook.cc0000644000175000001440000000250011036722347015411 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * A Qt object that invokes its callback whenever it receives * an event. This is useful for deferring processing to the * Qt event loop. Use it to avoid problems resulting from the * non-reentrant nature of WvStream::execute(). */ #include "wvqthook.moc" WvQtHook::WvQtHook(WvQtHookCallback _callback) : callback(_callback) { } void WvQtHook::setcallback(WvQtHookCallback _callback) { callback = _callback; } bool WvQtHook::event(QEvent *event) { if (! callback) return false; QEvent::Type eventtype = event->type(); if (eventtype < QEvent::User || eventtype > QEvent::MaxUser) return false; QCustomEvent *ce = static_cast(event); callback(*this, eventtype - QEvent::User, ce->data()); return true; } void WvQtHook::post(int type, void *data) { // event must be allocated on heap for postEvent QEvent::Type eventtype = QEvent::Type(QEvent::User + type); QCustomEvent *event = new QCustomEvent(eventtype, data); QApplication::postEvent(this, event); } void WvQtHook::send(int type, void *data) { QEvent::Type eventtype = QEvent::Type(QEvent::User + type); QCustomEvent event(eventtype, data); QApplication::sendEvent(this, & event); } wvstreams-4.6.1/qt/tests/0000755000175000001440000000000011205042556014360 5ustar wlachuserswvstreams-4.6.1/qt/tests/qtstringtest.cc0000644000175000001440000000172711205042556017451 0ustar wlachusers/* * Test the WvString -> QString compatibility stuff */ #include #include "wvstring.h" #include "wvlog.h" WvString qf(const QString &q) { return q; } QString wf(WvStringParm w) { return (const char *)w; } int main() { WvLog test("qtstringtest", WvLog::Info); WvString a("hello a\n"); WvFastString b("bellow b\n"); const char *c = "yellow c\n"; QString z("mellow z\n"); QCString y("yellow y\n"); test(a); test(b); test(c); test(z); test(y); WvString z2(z), y2(y); WvFastString z3(z), y3(y); test(z2); test(y2); test(z3); test(y3); QString a2(a.cstr()), b2(b.cstr()), c2(c); QCString a3(a), b3(b), c3(c); test(a2); test(b2); test(c2); test(a3); test(b3); test(b3); test(qf("bonk\n")); test(wf("wonk\n")); test(qf(wf(qf(wf(qf(WvString("fishy %s %s %s %s %s wishy\n", a, b, c, z, y))))))); return 0; } wvstreams-4.6.1/qt/wvqtstring.cc0000644000175000001440000000230711036722347015764 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Helper(s) to make WvString co-operate better with QString. */ #include "wvstring.h" #include #include WvFastString::WvFastString(const QString &s) { // fprintf(stderr, "ffqs: '%s'\n", s.latin1()); #if 1 link(&nullbuf, NULL); *this = WvString(s); #else // just copy the pointer - no need to allocate memory! str = (char *)s.latin1(); // I promise not to change anything! buf = NULL; #endif } WvFastString::WvFastString(const QCString &s) { // fprintf(stderr, "ffqcs: '%s'\n", (const char *)s); #if 1 link(&nullbuf, NULL); *this = WvString(s); #else // just copy the pointer - no need to allocate memory! str = (char *)(const char *)s; // I promise not to change anything! buf = NULL; #endif } WvFastString::operator QString () const { return cstr(); } WvString::WvString(const QString &s) { // fprintf(stderr, "ssqs: '%s'\n", s.latin1()); link(&nullbuf, s); unique(); } WvString::WvString(const QCString &s) { // fprintf(stderr, "ssqcs: '%s'\n", (const char *)s); link(&nullbuf, s); unique(); } wvstreams-4.6.1/qt/wvqtstreamclone.cc0000644000175000001440000001451311036722347016774 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * Wraps another WvStream and attaches it to the normal Qt * event loop. If you are using this object to manage all of your * streams, then you do not need to have a normal WvStreams * select()/callback() loop in your application at all. * * However, should you leave the Qt event loop and wish to continue * using this WvStream, call qt_detach() first, then run a normal * WvStreams event loop. If you do not do this, events may be * lost!! You may resume the Qt event loop at any time after the * WvStreams event loop has exited by calling qt_attach(). * * Note: You do not need to add all of the WvStreams used in a Qt * application to a single WvStreamList wrapped by a * WvQtStreamClone so long as each top-level stream is wrapped * by a WvQtStreamClone to take care of calling select() * and callback() from within the Qt event loop. */ #include "wvqtstreamclone.moc" // number of slots used by the separate chaining hashtable // note: can store more than this number of elements in the table #define NUM_SLOTS 41 // must be prime WvQtStreamClone::WvQtStreamClone(IWvStream *_cloned, int msec_timeout) : WvStreamClone(_cloned), msec_timeout(msec_timeout), pending_callback(false), first_time(true), select_in_progress(false), last_max_fd(-1), notify_readable(NUM_SLOTS), notify_writable(NUM_SLOTS), notify_exception(NUM_SLOTS) { _cloned->addRef(); setclone(_cloned); notify_readable.setAutoDelete(true); notify_writable.setAutoDelete(true); notify_exception.setAutoDelete(true); qt_attach(); } WvQtStreamClone::~WvQtStreamClone() { } void WvQtStreamClone::pre_poll() { // prepare lists of file descriptors _build_selectinfo(si, msec_timeout, false, false, false, true); // set up a timer to wake us up to poll again (for alarms) // we don't try to catch the timer signal; we use it only to force // Qt's event loop to restart so our hook gets called again select_timer.stop(); if (si.msec_timeout >= 0) select_timer.start(si.msec_timeout, true /*singleshot*/); // set up necessary QSocketNotifiers, unfortunately there is no // better way to iterate over the set of file descriptors for (int fd = 0; fd <= si.max_fd; ++fd) { if (FD_ISSET(fd, &si.read)) { QSocketNotifier *n = notify_readable.find(fd); if (! n) { n = new QSocketNotifier(fd, QSocketNotifier::Read); notify_readable.insert(fd, n); QObject::connect(n, SIGNAL(activated(int)), this, SLOT(fd_readable(int))); } } else notify_readable.remove(fd); if (FD_ISSET(fd, &si.write)) { QSocketNotifier *n = notify_writable.find(fd); if (! n) { n = new QSocketNotifier(fd, QSocketNotifier::Write); notify_writable.insert(fd, n); QObject::connect(n, SIGNAL(activated(int)), this, SLOT(fd_writable(int))); } } else notify_writable.remove(fd); if (FD_ISSET(fd, &si.except)) { QSocketNotifier *n = notify_exception.find(fd); if (! n) { n = new QSocketNotifier(fd, QSocketNotifier::Exception); notify_exception.insert(fd, n); QObject::connect(n, SIGNAL(activated(int)), this, SLOT(fd_exception(int))); } } else notify_exception.remove(fd); } // remove stale notifiers for (int fd = si.max_fd + 1; fd <= last_max_fd; ++fd) { notify_readable.remove(fd); notify_writable.remove(fd); notify_exception.remove(fd); } last_max_fd = si.max_fd; // clear select lists FD_ZERO(&si.read); FD_ZERO(&si.write); FD_ZERO(&si.except); } void WvQtStreamClone::post_poll() { // cleanup and invoke callbacks bool sure = _process_selectinfo(si, true); if (sure || pending_callback) { pending_callback = false; callback(); if (globalstream) globalstream->callback(); } } void WvQtStreamClone::set_timeout(int msec_timeout) { this->msec_timeout = msec_timeout; } void WvQtStreamClone::qt_begin_event_loop_hook() { // select not done yet? if (select_in_progress) return; // finish the last polling stage if (! first_time) post_poll(); else first_time = false; // start the next polling stage pre_poll(); select_in_progress = true; } void WvQtStreamClone::qt_detach() { // finish the last polling stage if (! first_time) { select_in_progress = false; post_poll(); last_max_fd = -1; first_time = true; } // remove any remaining Qt objects select_timer.stop(); notify_readable.clear(); notify_writable.clear(); notify_exception.clear(); QObject::disconnect(qApp, SIGNAL(guiThreadAwake()), this, SLOT(qt_begin_event_loop_hook())); QObject::disconnect(& select_timer, SIGNAL(timeout()), this, SLOT(select_timer_expired())); } void WvQtStreamClone::qt_attach() { // hook into the Qt event loop before each iteration QObject::connect(qApp, SIGNAL(guiThreadAwake()), this, SLOT(qt_begin_event_loop_hook())); QObject::connect(& select_timer, SIGNAL(timeout()), this, SLOT(select_timer_expired())); } void WvQtStreamClone::select_timer_expired() { select_in_progress = false; } void WvQtStreamClone::fd_readable(int fd) { FD_SET(fd, &si.read); pending_callback = true; select_in_progress = false; } void WvQtStreamClone::fd_writable(int fd) { FD_SET(fd, &si.write); pending_callback = true; select_in_progress = false; } void WvQtStreamClone::fd_exception(int fd) { FD_SET(fd, &si.except); pending_callback = true; select_in_progress = false; } void WvQtStreamClone::execute() { WvStreamClone::execute(); } void WvQtStreamClone::setclone(IWvStream *newclone) { WvStreamClone::setclone(newclone); if (newclone != NULL) my_type = WvString("WvQtStreamClone:%s", newclone->wstype()); else my_type = "WvQtStreamClone:(none)"; } wvstreams-4.6.1/Docs/0000755000175000001440000000000011036722347013467 5ustar wlachuserswvstreams-4.6.1/Docs/vars.mk0000644000175000001440000000005211036722347014770 0ustar wlachusers GARBAGES+=Docs/doxy-html Docs/kdoc-html wvstreams-4.6.1/Docs/sgmlmanual/0000755000175000001440000000000011036722347015627 5ustar wlachuserswvstreams-4.6.1/Docs/sgmlmanual/wvapps.wvsgml0000644000175000001440000000052511036722347020412 0ustar wlachusersWVPART(wvapps, Weaver Applications, WVCHAPTER(blah, NONE OF THESE CHAPTERS ARE WRITTEN YET, None of these chapters are written yet. ) WVCHAPTER(webconfig, WebConfig,x) WVCHAPTER(lcdconfig, LCDConfig,x) WVCHAPTER(wvdial, The WvDial API,x) WVCHAPTER(tunnelv, The Tunnel Vision API,x) WVCHAPTER(fastforward, The Fast Forward API,x) ) wvstreams-4.6.1/Docs/sgmlmanual/Makefile0000644000175000001440000000742611036722347017300 0ustar wlachusers default: includes wvstreams.verify all: includes wvstreams.verify wvstreams.html wvstreams.ps wvstreams.pdf html: wvstreams.sgml wvstreams.html ps: wvstreams.ps pdf: wvstreams.pdf rtf: wvstreams.rtf IMGFILES=$(shell [ -d img ] && find img -type f) ALL_WVSGML=$(shell /bin/ls *.wvsgml 2>/dev/null) %.verify: %.sgml # Syntax check nsgmls $< >/dev/null # Syntax check passed %.sgml: %.wvsgml *.m4 $(ALL_WVSGML) Makefile @echo Preprocessing $< to $@... @M4PATH=egfiles:../weaver/src m4 sgmlmacros.m4 $< | awk ' \ BEGIN { \ paropen = 0; \ parready = 0; \ disabled = 0; \ autopunc = 0; \ } \ \ /^[ ]*--AUTOPUNC--[ ]*$$/ { \ autopunc = !autopunc; \ next; \ } \ \ /^[ ]*--SNIP--[ ]*$$/ { \ disabled = !disabled; \ next; \ } \ \ \ (autopunc==1) { \ gsub("&", "\\&"); \ gsub("<", "\\<"); \ gsub(">", "\\>"); \ } \ \ parready && !disabled && !paropen && /^[ ]*[-A-Za-z0-9]/ { \ print ""; \ print; \ parready = 0; \ paropen = 1; \ next; \ } \ \ paropen && !disabled && !parready && /^[ ]*$$/ { \ print ""; \ print; \ parready = 1; \ paropen = 0; \ next; \ } \ \ /^[ ]*$$/ { \ parready = 1; \ } \ \ { print; } \ ' | cat -s >$@ %.html: %.sgml HTML.dsl ${IMGFILES} ${MAKE} dirimages rm -rf $@ $*.html.tmp mkdir -p $*.html.tmp # Copy only the required .gif files set -e; \ for d in $$(grep '"[^"]*\.gif"' $*.sgml \ | sed 's,^.*"img/\([^"]*\.gif\)".*$$,\1,'); \ do \ mkdir -p "$*.html.tmp/img/$$(dirname $$d)"; \ ${MAKE} img.tmp/$$d; \ cp -v img.tmp/$$d $*.html.tmp/img/$$d; \ done # Generate html cd $*.html.tmp && jade -t sgml -d ../HTML.dsl ../$*.sgml mv $*.html.tmp $@ %.rtf: %.sgml ${IMGFILES} $(MAKE) dirimages htmlimages rm -f $@ jade -t rtf -o $*.rtf.tmp \ -d /usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/print/docbook.dsl $< cat $*.rtf.tmp | sed 's,"img/\(.*\)\.[^.]*","img.tmp/\1.gif",g' >$@ rm -f $*.rtf.tmp %.tex: %.sgml rm -f $@ jade -t tex -o $*.tex.tmp \ -d /usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/print/docbook.dsl $< cat $*.tex.tmp | sed 's,{img/\(.*\)\.[^.]*},{img.tmp/\1.eps},g' >$@ rm -f $*.tex.tmp %.dvi: jadetex.fmt %.tex ${IMGFILES} ${MAKE} teximages jadetex $*.tex /dev/null # generate .aux files for xrefs jadetex $*.tex /dev/null # actually generate output jadetex $*.tex /dev/null # actually generate output %.ps: %.dvi dvips -q -o $@ $< $@ img.tmp/%.eps img.tmp/%.ps: img.tmp/%.pnm pnmtops -dpi 100 -width 350 $< >$@ img.tmp/%.gif: img.tmp/%.ppm ppmtogif -interlace $< >$@ img.tmp/%.ppm: img.tmp/%.ps gs -q -dNOPAUSE -sDEVICE=ppm -r75x75 -sOutputFile=$@ $< -c quit includes: $(shell grep 'include(.*)' $(ALL_WVSGML) /dev/null clean: $(MAKE) -C egfiles clean rm -f *~ *.fmt *.tex *.ps *.pdf *.dvi *.aux *.log *.rtf HTML.manifest rm -rf *.html *.tmp rm -f $$(echo "$(ALL_WVSGML)" | sed 's/\.wvsgml/.sgml/g') wvstreams-4.6.1/Docs/sgmlmanual/wvstreams.wvsgml0000644000175000001440000000251611036722347021127 0ustar wlachusers Programmer's Guide to the WvStreams Libraries Net Integration Technologies R & D 2002 Net Integration Technologies, Inc. WVPREFACE(Introduction, This book describes the programming libraries used in the Net Integrator and related projects, collectively called the WvStreams ("Weave Streams") set of libraries. This is eternally a work-in-progress. WvStreams is a fast-moving target (Avery is never quite happy with the way things work!) and we update the manual whenever someone has time. Some parts remain unwritten or don't have enough detail; hopefully, someone will correct that problem over time. The last day someone updated this introduction was July 2002. So, in theory, this manual is mostly correct as of that date. If you aren't sure whether we're lying to you in this book, you had better look directly at the source code. The code itself is right, most of the time. ) skip_include(tutorial.wvsgml) include(utils.wvsgml) include(streams.wvsgml) include(ipstreams.wvsgml) include(configfile.wvsgml) include(netmap.wvsgml) skip_include(wvapps.wvsgml) wvstreams-4.6.1/Docs/sgmlmanual/ipstreams.wvsgml0000644000175000001440000001010711036722347021076 0ustar wlachusersWVPART(ipstreams, The IPStreams (TCP/IP sockets interface) Library, WVCHAPTER(basicip, Support Classes, WVSECT1(wvaddr, WvAddr - storing an arbitrary network address, Device-independent and device-specific hardware/protocol address classes that can store themselves efficiently as well as create a printable string version of themselves. WVEXAMPLE(wvhttpex.cc) ) WVSECT1(wvresolver, WvResolver - Background DNS name resolution, DNS name resolver with support for background lookups. It is an aSynchronous DNS resolver functions, so that we can do non-blocking lookups. WVEXAMPLE(wvresolverex.cc) ) ) WVCHAPTER(kernelip, Interfacing to Linux Kernel Features, WVSECT1(wvinterface, WvInterface - manipulating network interfaces, A WvInterface stores information about a particular network interface. It is _allowed_ to have more than one WvInterface instance referring to the same physical interface, because that is more convenient. Note that this file doesn't compile on anything other than Linux. ) WVSECT1(wviproute, WvIPRoute - manipulating the routing table, The WvIPRoute and WvIPRouteList classes, which can manipulate the kernel routing table in useful ways. ) WVSECT1(wvipfirewall, WvIPFirewall - basic ipchains firewall interface, WvIPFirewall is an extremely simple hackish class that handles the Linux 2.4 "iptables" firewall. It's okay to create more than one instance of this class; they'll co-operate. They need you to have created the appropriate firewall tables already, however, and call them from the right places in the Input and/or Forward firewalls. ) WVSECT1(wvipaliaser, WvIPAliaser - using Linux IP aliasing, WvIPAliaser handles IP aliasing in the Linux kernel. Multiple instances of the object can be created, and they will share aliases between them. Aliased addresses are only removed when all WvIPAliaser objects using that address give it up. (ie. the object is destroyed, or the Aliaser is reconfigured without including that address) ) WVSECT1(wvtundev, WvTunDev - using Linux tunnel devices, WvTunDev provides a convenient way of using Linux tunnel devices. If you don't have the /dev/net/tun device, try doing: mknod /dev/net/tun c 10 200 ) WVSECT1(wvdcp, WvDcp - , x) ) WVCHAPTER(wvudp, WvUDP - using udp datagrams, WvUDPStream can send and receive packets on a connectionless UDP socket. In the constructor, the socket is attached using bind() to the given _local address. If the address is 0.0.0.0, all addresses on the local host are used; if the port is 0, an available port number is chosen automatically. If the _rem address is 0.0.0.0, the port is not connect()ed. That means it can receive packets from anywhere and send them to anywhere. The src() and setdest() functions are useful for this. If _rem is not 0.0.0.0, connect() is called and the socket will only accept data to/from the specified remote UDP address. Buffering: all the usual WvStream-style input buffering is available, including getline(), but because input packets may get lost it is of limited usefulness. Buffering will cause particular confusion if the socket is not connect()ed. WVEXAMPLE(wvudpex.cc) ) WVCHAPTER(wvudp2, WvUDP2 - logically separate udp datagram connections, x) WVCHAPTER(wvtcp, WvTCP - using tcp streams, WvTCP is a WvStream-based TCP connection class. WVEXAMPLE(wvtcpex.cc) ) WVCHAPTER(wvhttp, WvHTTP - HTTP URL downloader, WvHTTPStream connects to an HTTP server and allows the requested file to be retrieved using the usual WvStream-style calls. WVEXAMPLE(wvhttpex.cc) ) WVCHAPTER(wvurl, WvURL , WvUrl is a simple URL-parsing class with built-in (though still somewhat inconvenient) DNS resolution. ) WVCHAPTER(wvunixconn, WvUnixConn , WvUnixConn is a WvStream-based Unix domain socket connection class. Unlike WvTCPConn, WvUnixConn makes connections synchronously because either the remote server is there, or it isn't. For convenience, we'll just ignore situations where it's a local server but still slow. ) ) wvstreams-4.6.1/Docs/sgmlmanual/utils.wvsgml0000644000175000001440000006636111036722347020244 0ustar wlachusers WVPART(utils, The Utilities Library, WVPREFACE(Introduction, The "utils" library contains fundamental support utilities used throughout WvStreams, or at least ones that we couldn't classify anywhere else. ) WVCHAPTER(basicutils, Basic String Handling, Here are some particularly simple C and C++ functions for manipulating strings. Most of these only sit in C++ files is to make it easier to link with our C++ functions--they don't use many C++ features. Functions that take or return WvStrings, however, are in C++. WVSECT1(strutils, String Utilities (strutils.cc), WVSECT2(backslashescape, backslash_escape(), WVCMD(WvString backslash_escape(WvStringParm s1)) Returns a WvString with a backslash in front of every non-alphanumeric character in s1. ) WVSECT2(encodehostnameasDN, encode_hostname_as_DN(), WVCMD(WvString encode_hostname_as_DN(WvStringParm hostname)) Takes a hostname and splits it into parts. For example, passing "www.fizzle.com" will return "dc=www,dc=fizzle,dc=com,cn=www.fizzle.com". ) WVSECT2(getfilename, getfilename(), WVCMD(WvString getfilename(WvStringParm fullname)) Returns the filename from a path. Together with getdirname(), separates the filename and directory name within a path. ) WVSECT2(getdirname, getdirname(), WVCMD(WvString getfilename(WvStringParm fullname)) Returns the directory name from a path. ) WVSECT2(hexdumpbuffer, hexdump_buffer(), WVCMD(WvString hexdump_buffer(const void *_buf, size_t len)) Produce a hexadecimal dump of the data buffer in 'buf' of length 'len'. It is formatted with 16 bytes per line; each line has an address offset, hex representation, and printable representation. This is used mostly for debugging purposes. You can send the returned WvString object directly to a WvLog or any other WvStream for output. ) WVSECT2(isnewline, isnewline(), WVCMD(bool isnewline(char c)) Returns true if 'c' is a newline or carriage return character. Increases code readability a bit. ) WVSECT2(isword, is_word(), WVCMD(bool is_word(char *string)) Returns true if all characters in 'string' are isalnum() (alphanumeric). ) WVSECT2(lookup, lookup(), WVCMD(int lookup(const char *str, const char * const *table, bool case_sensitive = false);) Finds a string in an array and returns its index. Returns -1 if not found. ) WVSECT2(nicehostname, nice_hostname(), WVCMD(WvString nice_hostname(WvStringParm name)) Converts a string into a proper hostname, if possible. It ensures that the hostname starts and ends with a letter or number, converts underscores to hyphens, and ensures that there aren't multiple hyphens in a row. If nice_hostname() can't convert name to a proper hostname, it returns the string "UNKNOWN". ) WVSECT2(nonbreaking, non_breaking(), WVCMD(char *non_breaking(char * string)) Replaces whitespace characters with nonbreaking spaces, for use with web stuff. ) WVSECT2(replacechar, replace_char(), WVCMD(void replace_char(void *string, char c1, char c2, int length)) Replace all instances of c1 with c2 for the first 'length' characters in 'string'. Ignores terminating NUL, so make sure you set 'length' correctly. ) WVSECT2(rfc1123date, rf1123_date(), WVCMD(WvString rfc1123_date(time_t _when);) Returns an RFC1123-compatible date made out of _when ) WVSECT2(rfc822date, rfc822_date(), WVCMD(WvString rfc822_date(time_t _when = -1)) Returns an RFC822-compatible date ("Mon, Thu 18 71 14:55:12 EST") made from _when or, if _when < 0, from the current time. ) WVSECT2(strcollsplit, strcoll_split(), WVCMD(void strcoll_split(StringCollection &coll, WvStringParm _s, const char *splitchars = " \t", int limit = 0)) Splits a string and adds each substring to a collection. coll : the collection of strings to add to _s : the string to split splitchars : the set of delimiter characters limit : the maximum number of elements to split ) WVSECT2(strcolljoin, strcoll_join(), WVCMD(WvString strcoll_join(const StringCollection &coll, const char *joinchars = " \t")) Concatenates all strings in a collection and returns the result. * coll : the collection of strings to read from * joinchars : the delimiter string to insert between strings ) WVSECT2(strcount, strcount(), WVCMD(int strcount(WvStringParm s, const char c)) Returns the number of occurrences of c in s. ) WVSECT2(strlwr, strlwr(), WVCMD(char *strlwr(char *string)) In-place modify a character string so that all contained letters are in lower case. Returns 'string'. ) WVSECT2(strreplace, strreplace(), WVCMD(WvString strreplace(WvStringParm s, WvStringParm a, WvStringParm b);) Replace any instances of 'a' with 'b' in 's'. ) WVSECT2(strupr, strupr(), WVCMD(char *strupr(char *string)) In-place modify a character string so that all contained letters are in upper case. Returns 'string'. ) WVSECT2(terminatestring, terminate_string(), WVCMD(char *terminate_string(char *string, char c)) Add character c to the end of a string after removing terminating carriage returns/linefeeds if any. You need a buffer that's at least one character bigger than the current length of the string, including the terminating NUL. ) WVSECT2(trimstring, trim_string(), WVCMD(char *trim_string(char *string)) Trims whitespace from the beginning and end of the character string, including carriage return / linefeed characters. Modifies the string in place. Returns the new first character of the string, which points either at 'string' itself or some character contained therein. string is allowed to be NULL; returns NULL in that case. WVCMD(char *trim_string(char *string, char c)) This is similar to the above, but in this case it trims off all characters starting at and including the first occurrence of c. ) WVSECT2(webunescape, web_unescape(), WVCMD(WvString web_unescape(const char *str)) Converts escaped characters from web URLs (such as "%20") into their normal ASCII representations. ) ) WVSECT1(verstring, Version String Manipulation (verstring.cc), These are version number and string manipulations, mostly specific to Net Integration software. Version numbers are 32-bit hexadecimal numbers such as 0x00012a00. The first 16 bits are the major version, and the second 16 bits are the (fractional) minor version. For example, the above example corresponds to version "1.2a" (which is the version string). You can numerically compare version numbers using the standard C < and > operators, which is what makes them useful. Verstring cannot deal with version numbers that contain more than four digits to the left or right of the decimal, letters greater than f, or more than one decimal. WVSECT2(vertostring, ver_to_string(), WVCMD(const char *ver_to_string(unsigned int ver)) Converts an integer, like 0x00012a00, to a string, like 1.2a. ) WVSECT2(stringtover, string_to_ver(), WVCMD(unsigned int string_to_ver(const char *str)) Converts a string, like 1.2a, to an integer, like 0x00012a00. ) ) WVSECT1(hex, Hexadecimal formating tools (WvHex.cc), WVSECT2(hexify, hexify(), WVCMD(void hexify(char *obuf, unsigned char *ibuf, size_t len)) Write the contents of the binary string of length 'len' pointed to by 'ibuf' into the output buffer 'obuf' in hexadecimal format. For example, if len==4, ibuf=="ABCDEF", then obuf will contain "41424344" with a terminating NUL character. This is useful to turn arbitrary binary into a simple printable format, so that it can (for example) be written to a WvConf configuration file. obuf must be a buffer with at least (len * 2) + 1 bytes available. (two digits for each byte of ibuf, plus a terminating NUL). ) WVSECT2(unhexify, unhexify(), WVCMD(void unhexify(unsigned char *obuf, char *ibuf)) Reverse the operation performed by hexify(). obuf must be a buffer large enough to contain the entire binary output string; you can calculate this size with (strlen(ibuf) / 2). obuf will NOT be automatically NUL-terminated. ) ) WVSECT1(crypto, Crypto stuff (strcrypt.cc), This short section contains only passwd_crypt(). WVSECT2(passwdcrypt, passwd_crypt(), WVCMD(WvString passwd_crypt(const char *str)) Similar to the Linux system call crypt(), but this function selects its own salt. ) ) ) WVCHAPTER(wvstring, WvString - dynamic character strings, WVSECT1(wvstringintro, Introduction, WvString is an implementation of a simple and efficient printable-string class. It leaves out many of the notational conveniences provided by other string classes because they waste too much CPU time and space. It does the one thing really missing from char* strings, that is, dynamic buffer management. When you copy one WvString to another, it does _not_ duplicate the buffer; it just creates another pointer to it. To really duplicate the buffer, call the unique() member function. However, if you assign a char* to a WvString, the entire string will be copied. This is sometimes wasteful, but it helps avoid _a lot_ of bugs. If you don't want it copied (say, if you want a WvString as a function parameter and don't intend on modifying it), use a WvStringParm. WvStringParms are more-or-less the same as WvStrings, but they don't copy char*s, and they don't have an edit() function. To change the contents of a WvString, you need to run its edit() member function, which executes unique() and then returns a char* pointer to the WvString contents. WvStrings will generally convert to const char*s when needed, but if you need to force a conversion (in case the function can't decide what type it wants, like printf()), use the cstr() member function. Be warned that some unscrupulous functions (such as strchr()) return char*s even though they take const char*s, so it is possible to edit a non-unique WvString (and hence the original WvString). These cases are pretty rare, but they occur. ) WVSECT1(wvstringexamples, WvString Examples, WVCMD(WvString x("fuzzy wazoo");) In this case, a WvString object 'x' is created. "fuzzy wazoo" is a static string, meaning a const char * is passed to the constructor of 'x', so a dynamic string is created inside of 'x', and "fuzzy wazoo" is copied over. No call to unique() is necessary in this case. When 'x' is destroyed (automatically upon exiting the C++ code block) the dynamic string will be deleted automatically. WVCMD(WvString output("fuzzy %-10.3s %5s\n", "abcdef", 12); WvString c(output); c.edit()[1] = 'a';) The first command above creates a WvString called 'output' which contains the string "fuzzy abc[seven spaces] [three spaces]12\n". This uses the printf-like string formatting feature built into WvString. Note that unlike printf, WvString's formatter is type-safe: you can't pass the wrong kind of object to the formatter. In fact, everything you format must use a '%s' format string - %d, %f, etc are not supported. The above function call works as follows: new WvStrings are allocated for the first two parameters ("fuzzy..." and "abcdef"). Then it turns '12' into a WvString using the WvString::WvString(int) constructor. All three operations require dynamic memory allocations. C++ then passes the new WvStrings on to the WvString "complex" constructor, which formats them according to the first string and generates an output string, which is always dynamically allocated. The second line above creates a WvString 'c' which is the same as 'output'. It does not cause any new dynamic memory allocations to occur and is very quick. The third line first makes 'c' unique (so that it has a separate copy of the output string), then changes the second character to 'a', so that now 'c' contains "fazzy abc 12" and output contains "fuzzy abc 12". WVCMD(WvString nul;) This command creates a null WvString. This is NOT simply a WvString containing a zero-length string, but a WvString that points to nothing. You very seldom want to leave a WvString this way, but if you do, you can test for this condition simply by comparing it to NULL: WVCMD((nul == NULL)) A zero-length WvString differs slightly from a null WvString. You can declare one as follows: WVCMD(WvString zerolen("");) The following expression will be true: WVCMD((zerolen == "")) However, 'zerolen' will not be equal to NULL. Conversely, a null WvString is not equal to the zero-length string, "". Most often, you will want to immediately fill a null WvString with an empty buffer with setsize(), as below. WVCMD(WvString newstr; newstr.setsize(128); sprintf(newstr.edit(), "blah blah %5.4f", floatval);) These commands first create a NULL WvString, then attach it to an uninitialized 128-byte buffer. We then use sprintf to fill the string buffer. ) WVSECT1(wvstringtable, WvStringTable, WVSECT2(wvstringtablejoin, join , WVCMD(WvString WvStringTable::join(const char *joinchars) const) returns a string that join all the elements in WvStringTable by the specified delimiter. If no delimiter is specified, it uses " \t" by default. ) WVSECT2(wvstringtablesplit, split, WVCMD(void WvStringTable::split(WvStringParm s, const char *splitchars,int limit)) adds an element to the table. Another way to do this is by making use of the fact that WvStringTable is really a WvHashTable, so we can do add() and append(). The difference is that add and append takes a reference instead of the constant string. Refer to WvHashTable for more details. Let's look at an example. WVEXAMPLE(wvstringtableex.cc) ) ) WVSECT1(wvstringlist, WvStringList , This is almost the same as WvStringTable. All the functions available for WvStringTable is available here. WVSECT2(wvstringlistjoin, join, WVCMD(WvString WvStringList::join(const char *joinchars) const) ) WVSECT2(wvstringlistsplit, split, WVCMD(void WvStringList::split(WvStringParm s, const char *splitchars, int limit)) the same as WvStringTable. In addition, we have: ) WVSECT2(wvstringlistfill, fill, WVCMD(void WvStringList::fill(const char * const *array)) which appends the array to the list. ) WVSECT2(wvstringlistpopstr, popstr, WVCMD(WvString WvStringList::popstr()) which get the first string in the list, or an empty string if the list is empty and removes the returned string from the list. WVEXAMPLE(wvstringlistex.cc) ) ) ) WVCHAPTER(wvlinklist, WvLinkList - type-safe linked lists and iterators, WvLinkList allows you to create type-safe lists of objects, along with appropriate iterators. Lists are used all over the Weaver and WvStreams, and the best way to learn about them is by example--so read the source code and look at the sample program in testlist.cc. WVSECT1(declarewvlinklist, How to create a WvLinkList?, You can create a WvLinkList of any data type you want. An example: WCVCMD(DeclareWvList(WvString);) This will create a linked list that will contain data of WvString type. To use it: WVCMD(WvStringList l;) To fill the list, you may use WVCMD(l.append(address of data, false);) which appends the element to the end of the list, or WVCMD(l.add(address of data, false);) which is exactly the same as append, or WVCMD(l.prepend(address of data, false);) which prepends the element to the beginning of the list. The false as the second argument is "autofree". If it is true, the list takes ownership of the element. The actual prototype of these functions are: WVCMD(void append(T *data, bool autofree, char *id = NULL) void add(T *data, bool autofree, char *id = NULL) void prepend(T *data, bool autofree, char *id = NULL)) To quickly determines if the list is empty, WVCMD(t.isempty();) returns true if empty. You can also count the number of words in the list with: WVCMD(l.count();) We also have an iterator through the list, which is declare as follows WVCMD(WvStringList::Iter i(l);) Before using, it must be reset using rewind(). WVCMD(i.rewind()) rewinds the iterator so that it points to the first element of the list. WVCMD(i.next()) moves the iterator along the list to point to the next element, returns: the current WvLink pointer, or null if there were no more elements remaining in the traversal sequence WCVCMD(l.cur()) returns a pointer to the WvLink at the iterator's current location. WVCMD(l.find(const void *data)) rewinds the iterator and repositions it over the element that matches the specified value, and returns the current WvLink pointer, or null if no such element was found WVCMD(l.zap()) destroys the list. WVCMD(l.zap(true)) destroys any elements that were added with autofree == true. WVCMD(l.first()) returns a pointer to the first element in the linked list, possibly null if it is empty. WVCMD(l.last()) returns a pointer to the last element in the linked list, possibly null if it is empty. WVCMD(l.add_after(WvLink *after, T *data, bool autofree, char *id = NULL )) adds the element after the specified link in the list. - "link" is the link preceeding the desired location of the element to be inserted, non-null - "data" is the element pointer, may be null - "autofree" is if true, takes ownership of the element - "id" is an optional string to associate with the element, or null WVCMD(l.unlink(address to data)) unlinks the specified element from the list. WVCMD(l.unlink_first()) unlinks the first element from the list. WVCMD(l.unlink_after(WvLink *after, bool destroy = true)) unlinks the element that follows the specified link in the list. You might also want to read the top of wvlinklist.h for some implementation details. A typical use of WvLinkList would be something like this: WVEXAMPLE(wvlistex.cc) The result is: WVCMD( blah blah bork bork Is the list empty? No The first element is: blah blah The last element is: bork bork) Here is another example, with a list of integers. WVEXAMPLE(intlistex.cc) Some rather horrible macros are used to declare actual concrete list types. List type construction is facilitated by the following macros: - DeclareWvList(Type): creates a subclass named WvListType that contains pointers to Type. - DeclareWvList2(name, Type): as the above, but calls the resulting class by the specified name. ) ) WVCHAPTER(wvhashtable, WvHashTable - type-safe hash tables and iterators, WvHashTable works a lot like WvLinkList, except it allows for fast indexing of objects in the table (or "dictionary") using the [] operator. We implement a hash table as a fixed-size array of WvLinkLists. Someday, we might change the implementation to use a self-resizing array instead. Iterators work with WvHashTable in exactly the same way as with WvLinkList. WvHashTable usage is described more fully, along with examples, in wvhashtable.h. WVSECT1(declarewvtable, How to create a WvHashTable?, You can create a WvHashTable of any data type you want. For example, a WvHashTable of WvString data type can be create like this: WVCMD(DeclareWvTable(WvString);) This will create a hashtable that will contain data of WvString type. It actually instantiates a WvStringTable class that inherits from a WvHashTable class that handles WvString data types. Or you can just use WvStringTable.h. You can set the size of your dictionary by invoking the constructor of the WvStringTable class, like this: WVCMD(WvStringTable t(100);) The WvString hashtable now has 100 slots. You can create some data of type WvString and put them in the dictionary like this: WVCMD(t.add(address of data, false);) Note that you have to pass the address of data as the first argument, and not the data itself. Here the second parameter 'false' means that you don't want the data to be automatically destroyed at the end of the program. This is used because some data types like WvString already has the automatic self-destroy feature. For some other data types, you may need to set the second parameter to 'true'. You may also use WVCMD(t.append(address of data, false);) or WVCMD(t.prepend(address of data, false);) to add to the dictionary. You can use the iterator to go through the hashtable and print it out if you like. WVCMD(WvStringTable::Iter i(t);) You can also count the number of words in the dictionary with: WVCMD(t.count();) To find out if a word is already in the dictionary, you can invoke the comparison by using the [] operator. For example, you want to know if the word 'bijoux' exists in the dictionary. So you declare a WvString variable that contains the string 'bijoux', like this: WVCMD(WvString sample("bijoux");) Then you can compare it like this: t[sample] returns NULL if 'bijoux' is NOT in the dictionary. t[sample] returns the word that matches 'bijoux' in the dictionary if 'bijoux is in the dictionary. To remove a word from the dictionary, do this: WVCMD(t.remove(address of data);) To empty the entire dictionary, do this: WVCMD(t.zap();) You may want to do an iterator with a sorted list, since it is a linked list. Here is how WVCMD(WvStringTable::Sorter s(t,);) The following example shows all the mentioned features of a hashtable. Please take a look and try compile and run it to see for yourself. WVEXAMPLE(wvhashtableex.cc) The result is: WVCMD(What words do we have in the dictionary? matin oui Bonjour bonsoir demain comment non aussi depanneur bien There are 10 words stored in the dictionary so far. Is 'Bonjour' in the dictionary? Yes Is 'Salut' in the dictionary? No Modified List: matin oui Bonjour bonsoir demain comment non depanneur bien Sorted modified List: bien Bonjour bonsoir comment demain depanneur matin non oui Empty List:) ) ) WVCHAPTER(wvbuffer, WvBuffer - dynamically-resizing binary buffers, A WvBuffer is a dynamically-sized buffer. It's often perfect for storing streamed data. WvBuffer is pretty simple to use. You can write data to it using put() and retrieve the data using get(). get() effectively deletes the data from the buffer, but you can use unget() to get it back if you haven't done any buffer operations in the meantime. WVCMD(WvBuffer buf; buf.put("borkle borkle\n"); printf(buf.get(14)); buf.unget(14); printf(buf.get(14));) The above code will print "borkle borkle" twice. WVSECT1(wvbuffercc, WvBuffer (WvBuffer.cc), WVSECT2(alloc, alloc(), WVCMD(unsigned char *alloc(size_t num)) allocates 'num' bytes in the buffer and returns a pointer to its start . Pointer is valid until next zap() or get(). ) WVSECT2(unalloc, unalloc(), WVCMD(void unalloc(size_t num)) unallocates the last 'num' bytes in the buffer that were previously al located using alloc() or put(), They are then available for a subseque nt alloc() or put(). ) WVSECT2(put, put(), WVCMD(void put(WvStringParm str)) Copy a WvString into the buffer, not including the terminating nul. WVCMD(void put(const void *data, size_t num)) Copy 'buf' into the next 'num' bytes of buffer. ) WVSECT2(get, get(), WVCMD(unsigned char *get(size_t num)) Return the next 'num' bytes in the buffer. Returns NULL if there are not enough bytes in the buffer. ) WVSECT2(unget, unget(), WVCMD(void unget(size_t num)) Undo all or part of the previous get(). You can unget() up to the numb er of bytes you did in the last get(), assuming you have not done any other buffer operation in the meantime. ) WVSECT2(match, match(), WVCMD(size_t match(const unsigned char chlist[], size_t numch, bool reverse = false)) Returns the number of leading bytes that match any in chlist. If rever se == trye, match bytes that are not in chlist. ) WVSECT2(merge, merge(), WVCMD(void merge(WvBuffer &buf)) Merges another WvBuffer into this one, simply move all of its objects into our own list. ) ) WVSECT1(wvbufferstore, WvBufferStore - basic buffer storage class, x ) ) WVCHAPTER(wvdiriter, WvDirIter, WvDirIter is a directory iterator. It basically implements WVCMD(find). WVCMD(WvDirIter( WvString dirname, bool _recurse=true );) where dirname is the directory name. A simple example: WVEXAMPLE(wvdiriterex.cc) ) WVCHAPTER(wvencoder, WvEncoder - A top-level data encoder class, The base encoder class. Encoders read data from an input buffer, transform it in some way, then write the results to an output buffer. The resulting data may be of a different size or data type, and may or may not depend on previous data. WVSECT1(wvbase64, An encoding tool (WvBase64.cc), Contains functions for encoding and decoding strings in MIME Base64 notation. WVSECT2(wvbase64encode, WvBase64Encoder(), Converts a string to base64 encoding. ) WVSECT2(wvbase64decode, WvBase64Decoder(), Converts a string from base64 format into a normal string format. An example of WvBase64Encoder: WVEXAMPLE(wvbase64ex.cc) ) ) WVSECT1(wvbackslash, Another encoding tool (WvBackSlash.cc), You almost never use this, but it's there if you need it. WvBackSlash performs C-style backslash escaping and unescaping of strings. WVEXAMPLE(backslashex.cc) ) ) WVCHAPTER(wvcrash, WvCrash - automatic stack backtrace generation, WvCrash is a simple way to get useful information when a program dies. It automatically generates a stack trace, including names of not only your program's functions but also library functions. Setting up WvCrash involves running wvcrash_setup() and passing it the name of your program (generally you'll want to pass argv[0]). When the program dies, it automatically executes the user-defined program "wvcrash", if it exists, and pipes the WvCrash stack trace to its stdin. If there's no program called "wvcrash" in the path, it writes the stack trace to a file named "wvcrash.txt" in the current directory. ) WVCHAPTER(wvtclstring, WvTclString, x ) ) wvstreams-4.6.1/Docs/sgmlmanual/sgmlmacros.m40000644000175000001440000000220211036722347020234 0ustar wlachuserschangequote(--<<-,->>--) define(skip_include, ) define(ZAPPY, ) undefine(--<<-format->>--) define(WVEXACTLY, --<<- --AUTOPUNC-- --SNIP-- WVCOMMAS($*) --SNIP-- --AUTOPUNC-- ->>--) define(WVEXAMPLE, --<<- WVEXACTLY(include($1)) ->>--) define(WVCOMMAS, --<<-ifelse($#, 1, $1, --<<-$1, WVCOMMAS(shift($*))->>--)->>--) define(WVPREFACE, --<<-$1 WVCOMMAS(shift($*)) ->>--) define(WVPART, --<<-$2 WVCOMMAS(shift(shift($*))) ->>--) define(WVPARTINTRO, --<<-$1 WVCOMMAS(shift($*)) ->>--) define(WVCHAPTER, --<<-$2 WVCOMMAS(shift(shift($*))) ->>--) define(WVSECT1, --<<-$2 WVCOMMAS(shift(shift($*))) ->>--) define(WVSECT2, --<<-$2 WVCOMMAS(shift(shift($*))) ->>--) define(WVSECT3, --<<-$2 WVCOMMAS(shift(shift($*))) ->>--) define(WVCMD, --<<- WVEXACTLY($*) ->>--) wvstreams-4.6.1/Docs/sgmlmanual/netmap.wvsgml0000644000175000001440000000215311036722347020355 0ustar wlachusersWVPART(netmap, Network Mapping and Intelligence - the NetMap Library, WVCHAPTER(wvnetcap, WvNetCap - network packet capture, WvStream-based network packet capture routines. ) WVCHAPTER(wvnetmap, WvNetMap - raw host information, The Weaver network map: here, we keep track of which network addresses are used, by whom, how often, and where. Correspondingly, the data structures are really sick looking. ) WVCHAPTER(wvnetintel, WvNetIntelligence - network map reduction, Weaver "Network Intelligence" takes data from the Network Map (WvNetMap) and synthesizes useful things from it. Currently, those useful things include suggested local IP addresses for a network device, and a reasonable routing table. ) WVCHAPTER(wvpingprobe, WvPingProbe - active probing, The WvPingProbe class lets you ping hosts creatively and easily, and then munge the results. ) WVCHAPTER(wvnetguide, WvNetGuide - route manipulation and overrides, WvNetGuide is a higher-level interface to the kernel routing table. We can tell it about "dynamic" routes, which come up automatically when they are needed. ) ) wvstreams-4.6.1/Docs/sgmlmanual/HTML.dsl0000644000175000001440000000072111036722347017077 0ustar wlachusers ]> ;; your stuff goes here... ;;(define %gentext-nav-use-ff% 1) (define %use-id-as-filename% 1) wvstreams-4.6.1/Docs/sgmlmanual/streams.wvsgml0000644000175000001440000005776211036722347020567 0ustar wlachusersWVPART(streams, The Streams Library, WVCHAPTER(wvstream, WvStream - communications fundamentals, WvStream is the base class from which (not surprisingly) most of the WvStreams library is derived. It defines the basic properties of a stream: a sequence of bytes that may or may not be ready for reading or writing at any given time. WvStream is a perfectly useful class all by itself; it can read, write, and wait on a Unix fd (file descriptor), which is sufficient for nearly all communications in Unix-like systems. The other WvStream classes do basically the same thing, but create and manipulate their fds automatically instead of requiring you to do it. WVSECT1(wvstreamsimple, Basic WvStream Examples, The following example program reads from stdin and echos the results back to stdout with a bit of added commentary. Remember that in Unix, fd 0 is stdin, and fd 1 is stdout. WVEXAMPLE(wvstreamex.cc) isok() ("is okay") returns true as long as the stream is still alive. If you press CTRL-D as the input to a program, this sends an end-of-file message and the stream becomes "not okay." (isok() == false). The getline() function reads a character string of arbitrary length using WvBuffer, up to but not including the first newline. The (-1) tells getline() to wait forever for the newline if necessary. Try changing it to 5000 (5 seconds) and see how that affects the operation of the program. Whenever possible, WvStreams tries to shelter you from weird Unix-specific information like fd 0 and fd 1. There is a special WvStream pointer called wvcon which points to both stdin and stdout. (Actually, since it points at both fd 0 and fd 1, wvcon needs to be a WvSplitStream object, but don't worry about that just yet.) You can reassign wvcon to any other stream if you like -- this will let you essentially redirect stdin and stdout for the WvStreams classes that use it. Here's an example of how you can use wvcon to simplify the above sample program. WVEXAMPLE(wvstreamex2.cc) ) WVSECT1(wvstreamrw, Reading and Writing, Here's a sample program that uses the read() and write() member functions. Usually, these functions are used more often than getline() because WvStreams are commonly used to manipulate binary data rather than line-by-line data. WVEXAMPLE(wvstreamex3.cc) Unlike getline(), read() isn't very smart. You must supply it with a buffer and tell it how large the buffer is. However, there's no guarantee that read() will fill the entire buffer or any of it -- you should _always_ check the return value (numread, in this case) to find out how many bytes were read. You'll find out later (when we talk about select()) that this is actually the right thing to do -- the last thing you want in most WvStreams programs is for read() to sit doing nothing until a buffer fills up. On the other hand, the write() function has a built-in buffer, so as long as the stream is alive, the return value of write() should always be the same as the length you provide as the second parameter. The print() function works sort of like printf(). It uses the complex constructor for WvString to type-safely format strings, and then the write() function to send them out to the stream. ) WVSECT1(wvstreamselect, Waiting on a stream with select(), The previous example was actually not completely correct -- it works, but depending on the wvcon implementation, it could accidentally use 100% CPU time. (The default wvcon implementation doesn't actually have this "problem," but that's a coincidence and might change in the future.) Remember that read() is not guaranteed to fill the input buffer. In fact, it's not even guaranteed to read any bytes at all. So in theory, the previous example might find itself endlessly looping, calling isok() and read() over and over until some input is received. That will work, of course, but it wastes a lot of CPU time. What we should really do is tell WvStream to wait until some data is available, and only then call read(). Here's how. WVEXAMPLE(wvstreamex4.cc) Note again that the (-1) parameter to select() means "wait forever." In this case, it doesn't really matter if you set it to 5000 (5 seconds), for example, because we'll simply wait five seconds and restart the loop. If we do select(0), select() doesn't wait at all. This isn't as pointless as it seems: select() returns true or false depending whether the stream was ready or not, so select(0) is a good way to test if a stream is ready without actually stopping your program. You can also select() to see if a stream is writable, but this is used much less often since WvStream now has write buffers anyway (so you can always write to a stream without delaying). Sometimes it can be useful, though: for example, a TCP connection is not "writable" until it's connected to the remote host. That makes sense, if you think about it. It's not readable either, of course, but it doesn't necessarily become readable as soon as it connects. A connected TCP stream is always writable. You can check for (or wait for) readability and writability at the same time. There is also a test for a stream "exception", but no one has ever used that, so I don't know what it does. The prototype for select() actually looks like this: WVCMD(bool select(time_t msec_timeout, bool readable=true, bool writable=false, bool isexception=false);) That means normally, we want to check whether a stream is readable, and we don't care if it's writable or has an exception. To check whether a stream is writable, for example, use a line like this: WVCMD(wvcon->select(0, false, true, false);) To wait up to 5 seconds until the stream is either readable or writable, try this: WVCMD(wvcon->select(5000, true, true, false);) Now, you're probably wondering why read() can't just wait for data and write() can't just send it out, saving us all a lot of trouble. Well, that's all fine and good for single-tasking one-stream programs, but WvStreams was designed to handle lots of simultaneous connections -- that's when select() really gets useful. We'll talk about that later, in the section about WvStreamList. ) WVSECT1(wvstreamcallbacks, Callback Functions, Unless you've skipped ahead to the WvStreamList section, this section will seem even more useless than the one on select(). But trust us, when you have lots of different streams talking to each other later on, you'll be really glad to have callback functions around. Here's a quick example, using one of the predefined stream callbacks called autoforward(). WVEXAMPLE(wvstreamex5.cc) The above program does almost exactly what the previous ones did, except that instead of manually reading and writing strings, we tell the stream that its "default operation" is to auto-forward its data to wvcon... which is, in this case, itself. The result is that we forward stdin to stdout as before, only without the extra text surrounding it. Almost all WvStreams programs end up using callbacks for most of their work. That's because with callbacks, each stream knows what to do with its own data, and you don't have to say it in the main program. That's what object-oriented programming is all about, after all. In fact, the main loop in most WvStreams programs ends up looking a lot like the main loop in the program above: wait until the stream is ready, then run its callback function. What does autoforward() do, exactly? Let's write a callback function ourselves and demonstrate one possibility. WVEXAMPLE(wvstreamex6.cc) Note that mycallback() calls getline() with a (0) delay parameter; you almost never want a callback function to wait for something (although it certainly can, if you really want). Instead, if getline can't find a whole line of text to read, we simply return from the callback and wait until next time. This brings up an interesting point about select() and getline(): select() might say yes, the stream is ready for reading, but getline() might still return NULL. Why? Because getline() looks for a terminating newline. If the only input is the letters "abcdefg" (without a trailing newline character) then the stream really is ready for reading, but getline hasn't retrieved a whole line of input. Don't worry, though, running getline() once clears the input-ready condition, so the callback will only get called again when more data is received. But whatever you do, don't be fooled into thinking that just because you're in the callback function, that data will always be returned on a read() or getline(). Always, _always_ check the return values first. ) WVSECT1(wvstreamdelay, Delays and Timeouts, We should mention that you can use the select() function for millisecond-resolution delays, or to timeout when no data is received for a certain amount of time. The following example babbles something at you after every second of no input, and exits if you don't say anything for ten seconds. WVEXAMPLE(wvstreamex7.cc) ) ) WVCHAPTER(somesimplestreams, Some Simple Streams, Let's look at a few streams that are only slightly more complicated than WvStream itself: WvFile, WvFileWatcher, and WvPipe. WVSECT1(wvfile, WvFile - accessing Unix files, WvFile is the simplest WvStream-derivative around. All it does is open a Unix file for you given a filename, so you don't have to supply the fd yourself. WVEXAMPLE(wvfileex.cc) Need we say more? Oh, since Unix devices are just files, you can use them with WvFile just as easily. For example, if your modem is /dev/ttyS2, you can connect to it by creating a WvFile that refers to /dev/ttyS2. Of course, the WvModem class is probably more useful for that particular job. ) WVSECT1(wvwatcher, WvFileWatcher - waiting for a file to change, WvFileWatcher is a bit more interesting than WvFile: it reads to the end of a file, and then if the file grows, select() returns true and you can read more data; if the file shrinks (which presumably means it was rewritten from scratch), it starts again at the top of the file. To think of it another way: WvFileWatcher makes select() make sense on regular files. Normally, select() is always true for a file, since all the data is always immediately available. (Note that this isn't true if your WvFile is connected to a Unix device; then select() makes sense already, and WvFileWatcher will just mess you up.) WvFileWatcher is very seldom used except as a WvStreams test, so we won't bother to give an example here. ) WVSECT1(wvpipe, WvPipe - talking to subtasks, WvPipe will certainly be very interesting to anyone who writes programs that need to spawn off sub-programs, and read and possibly write to that programs input and output. WvPipe makes this rediculously easy, by making the application call look exactly like any other stream. No more messy exec() calls, and best yet, no more blocking - if you just need to send a program off to do something, then you don't need to fork at all, you can just create a WvPipe stream which ignores any input, output, or error messages, and add it to your WvStreamList. If you do need to access input or output, you can easily just select() on this pipe, which will return true when the program has something interesting for you. WvPipes allow you to create a new process, and attaching its stdin/stdout to a WvStream. Insert Example Here... ) WVSECT1(wvmodem, WvModem - baud rates and terminal modes, Definition of the WvModemBase and WvModem classes. Inherit from WvFile, but do various important details related to modems, like setting baud rates and dropping DTR and the like. ) ) WVCHAPTER(logs, Dealing with Log Messages, WVSECT1(wvlog, WvLog - printing log messages, A generic data-logger class with support for multiple receivers. If no WvLogRcv objects have been created (see wvlogrcv.h) the default is to log to stderr. WvLog supports partial- and multiple-line log messages. For example, WVCMD(log.print("test "); log.print("string\nfoo");) will print: WVCMD(appname(lvl): test string appname(lvl): foo) See also, WvLogRcv. ) WVSECT1(wvlogrcv, WvLogRcv - receiving and disposing of log messages, WvLogRcv is an enhanced "Log Receiver" classes for WvLog. WvLogRcv-derived classes support automatic formatting of log lines with a prefix, removing control characters, and so on, to keep track of line-prefix-printing and other formatting information. WvLogRcv supports partial- and multiple-line log messages, like WvLog. An example: WVEXAMPLE(wvlogex.cc) ) WVSECT1(wvlogbuffer, WvLogBuffer - saving log messages to a buffer, WvLogBuffer is a descendant of WvLogRcv that buffers log messages for later use. It only keeps up to max_lines log entries for every source/debug level, s.t. debug level <= max_level WVEXAMPLE(wvlogbufex.cc) ) WVSECT1(wvlogfile, WvLogFile - sending log messages to a file, A "Log Receiver" that logs messages to a file. WVEXAMPLE(wvlogfileex.cc) ) WVSECT1(wvsyslog, WvSyslog - sending log messages to syslog, WvSyslog is a descendant of WvLogRcv that sends messages to the syslogd daemon. ) WVSECT1(pipelogex, An example of WvPipe and WvLog together, WVEXAMPLE(wvpipelogex.cc) ) ) WVCHAPTER(wvstreamlist, WvStreamList - dealing with multiple streams, WvStreamList is one of the most important parts of the WvStreams library. Almost every real WvStreams program (in contrast with all the preceding examples) involves at least one WvStreamList. We would have mentioned it much sooner, but we thought it would be nice to have a few different kinds of streams to play with before we started creating lots of them at a time. Fundamentally, what WvStreamList does is allow you to select() on more than one stream at a time. That way you can, for example, wait for multiple TCP connections to send you data, and wake up immediately as soon as any one of them is available. Without the magic of WvStreamList, there is no good way to wait for multiple streams simultaneously. There are, however, a couple of bad ways, which we will mention shortly just so you don't try them. WVSECT1(wvstreamlistbadidea, Don't do this, Don't try this: WVEXAMPLE(wvstreamlistex.cc) It will fail in three different ways depending on the value of X. If X==-1, each select() statement waits forever for data. That means in order to print a snorkle (which should appear once per second), you must first print a foo (which only happens once every three seconds). That's bad enough, but some streams might be almost completely idle, so you certainly can't get away with doing that. If X==0, we never wait at all. This will appear to work properly -- if you run the program, the snorkles and foos will show up at the right time. But unfortunately, your program will spin in the main loop, and take 100% of the CPU unnecessarily. We can compromise by making X==1000 instead. That way, each select() statement will give up after 1 second. Since the snorkles only happen once per second, that should be okay. However, it's not perfect -- the snorkles should appear _exactly_ one second apart, but you can't guarantee that using this technique. It'll be somewhere between zero and one seconds, depending on random luck. Besides, the whole point of this chapter is there's a better way, so don't write programs like the one above. ) WVSECT1(wvstreamlistgood, Do this instead, Here's a better way to choose between two lists, using WvStreamList. As you might have guessed, WvStreamList is a type of WvLinkList that contains WvStreams. It's also a stream itself, so (among other things) you can select() on a WvStreamList and include one WvStreamList inside another. But let's keep it simple for now: WVEXAMPLE(wvstreamlistex2.cc) A streamlist is always okay (isok() == true) because you can always add and remove streams from it. That's why our main loop is checking for "okayness" of the two main streams, rather of the list. But also notice the contents of the main loop. We select() on the list, and if it returns true, we then callback() the list. What's happening there? What happens is this. WvStreamList::select() will return true if the select() of any of its member streams would return true. (It doesn't actually _call_ the select() function of each of its member streams, but the idea is the same. That's why WvStreamList is magic.) When you run WvStreamList::callback(), it calls back all the member streams that would have returned true to a select() call. If you give select() a delay (in this case, infinity), it will wait until any one of the member streams is ready. This mechanism increases fairness between streams, in case you have a lot of high-bandwidth streams and you're having trouble keeping up. If more than one stream is ready, callback() will call each one sequentially before it returns. That way, no one stream will get priority over the others. ) WVSECT1(wvstreamlistfun, An Interesting Example, Now that we've introduced all the pieces, we can have our first interesting WvStream example by throwing several pieces together. Here's a program that prints messages every once in a while through a WvPipe and using timeouts, while you talk to your modem device via the console. WVEXAMPLE(wvstreamfunex.cc) ) ) WVCHAPTER(magicstreams, Some Magical Streams, WVSECT1(wvstreamclone, WvStreamClone - a stream within a stream, WvStreamclone is probably one of the coolest, and most confusing parts within the WvStream library. Almost everyone who has ever encountered this stream the first time has had to stop and go over it a few times before they can wrap their head around what is going on. Ok.. now that I've scared you... I'm going to tell you that it is really quite easy. Most of the time, when you are using a WvStreamClone, you will be doing something like the following: 1. Start a Stream on a TCP Connection 2. Change this Stream into something else (like an SSL Stream) 3. And then talk some sort of high level protocol (like HTTP) So you have one stream (a TCP Connection), that morphs into another stream TYPE (an SSL Stream), that then becomes another stream (talking HTTP). All the while, not changing the stream that was started and added to the original WvStreamList. WvStreamClone simply forwards all requests to the "cloned" stream. A class derived from WvStreamClone can contain a WvStream as a dynamically allocated data member, but act like the stream itself. This is useful for classes that need to create/destroy WvPipes while they run, for example, yet do not want users to know about the member variable. WvStreamClone _does_ attempt to close the cloned stream in the destructor. Insert Example here... ) WVSECT1(wvsplitstream, WvSplitStream - separating read and write streams, x) WVSECT1(wvloopback, WvLoopback - talking to yourself across fork(), WvLoopback uses a socketpair() to create a stream that allows you to read() everything written to it, even (especially) across a fork() call. ) ) WVCHAPTER(unusualstreams, Some Unusual Streams, WVSECT1(wvtimestream, WvTimeStream - timed events, WvTimeStream causes select() to be true after a configurable number of milliseconds. Because programs using WvStream make no guarantees about how often select() will be called, WvTimeStream tries to adjust its timing to a correct _average_ number of milliseconds per tick. For example, if ms_per_tick=100, WvTimeStream will tick 10 times in one second. However, there may be a few milliseconds of difference ("jitter") for each individual tick, due to random system delays. WVEXAMPLE(wvtimeex.cc) ) WVSECT1(wvtimeoutstream, WvTimeOutStream - timed out, WvTimeoutStream is a stream that becomes !isok() after a configurable number of milliseconds. It will wake up a select(). It will return true if select()ed and that the timeout has expired. But using it in a WvStreamList will not have it call the callback/execute because the WvStreamList checks whether isok() is true before doing the select(). WVEXAMPLE(wvtimeoutex.cc) ) WVSECT1(wvprotostream, WvProtoStream - a protocol state machine, WvProtoStream is a framework that makes it easy to communicate using common command-response driven protocols. This is supposed to be flexible enough to handle FTP, HTTP, SMTP, tunnelv, Weaver rcmd, and many others. ) ) WVCHAPTER(wvcallback, The Magic of WvCallBack, WVSECT1(wvcallback2, WvCallback - What does it do?, WvCallback calls a member function inside a class when certain event has happened or when certain task has been finished. The key point of WvCallback is that it can be used in a function that is not in the same class as the function that will be invoked after the event has occurred. WvCallback can operate as: 1. a function pointer when the invoked function is not part of any class or as 2. a member function pointer when the invoked function belongs to a class ) WVSECT1(wvcallback3, WvCallback - How to create your own WvCallback?, First, you have to declare a new type of WvCallback using DeclareWvCallback. DeclareWvCallback is a macro that helps to create a new type of WvCallback. Note: The macro of DeclareWvCallback is written in ~src/niti/src/wvstreams/include/wvcallback.h The syntax of DeclareWvCallback is as follows: DeclareWvCallback (n, ret, type, parms...) WVSECT2(declarewvcallback, The input parameters of DeclareWvCallback are explained as follows:, Reminder: WvCallback = function pointer or member function pointer n - the number of parameters that the function pointed to by the WvCallback takes. ret - the return type of the function pointed to by the WvCallback (e.g.: int, void, ...) type - the name of the callback type (e.g.: WvConfCallback). This is the type with which you will declare your WvCallback with. parms... - the types of the parameters that the function pointed to by the WvCallback. To create your own WvCallback, you need to include wvcallback.h. Then you need to declare your own WvCallback type at the top level. You cannot run DeclareWvCallback inside a class; otherwise, it causes an internal compiler error (g++ 2.95.4). See the following simple example: WVSECT3(funcptr, WvCallback - As a function pointer - function not inside any class, WVEXAMPLE(wvcallbackex.cc) ) WVSECT3(functptr2, WvCallback - As a member function pointer - function inside a class, WVEXAMPLE(wvcallbackex2.cc) ) ) ) ) ) wvstreams-4.6.1/Docs/sgmlmanual/egfiles/0000755000175000001440000000000011036722347017245 5ustar wlachuserswvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex5.cc0000644000175000001440000000034211036722347022045 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include int main() { wvcon->autoforward(*wvcon); while (wvcon->isok()) { if (wvcon->select(-1)) wvcon->callback(); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex3.cc0000644000175000001440000000056611036722347022053 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include int main() { char buffer[10]; size_t numread; while (wvcon->isok()) { numread = wvcon->read(buffer, sizeof(buffer)); if (numread) { wvcon->print("You said: "); wvcon->write(buffer, numread); wvcon->print(" (%s bytes)\n", numread); } } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvfileex.cc0000644000175000001440000000041211036722347021402 0ustar wlachusers/* * A WvFile example. * * Some text about this example... */ #include int main() { WvFile infile("/etc/passwd", O_RDONLY); char *s; while (infile.isok() && (s = infile.blocking_getline(-1)) != NULL) wvcon->print("%s\n", s); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/backslashex.cc0000644000175000001440000000127611036722347022052 0ustar wlachusers#include "wvbackslash.h" #include "wvbufbase.h" int main() { WvBackslashEncoder *enc; enc = new WvBackslashEncoder("abcd"); // enc contains the letters you want to escape (add a backslash to) // If you want a decoder, then enc has to be initialiazed like this: // enc = new WvBackslashDecoder(); WvInPlaceBuf to_encode(20); WvInPlaceBuf out(40); to_encode.put("Test abcdefg",12); // to_encode contains the string to be encoded // (added a backslash at the correct spot) if (enc->encode(to_encode, out, true,true)) printf ("This is the result: %s\n", (char *) out.get(1)); // Displayed on screen: // This is the result: Test \a\b\c\defg return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvlogfileex.cc0000644000175000001440000000136311036722347022112 0ustar wlachusers/* * A WvLogFile example. * * This program creates 2 log files. */ #include "wvlogfile.h" #include static bool want_to_die = false; static void sighandler_die(int sig) { want_to_die = true; fprintf(stderr,"Exited on Signal: %d\n",sig); } int main() { signal(SIGTERM, sighandler_die); signal(SIGINT, sighandler_die); signal(SIGXFSZ, sighandler_die); WvLogFile logger("./logtest", WvLog::Debug5); WvLog log("WvLogFile Test", WvLog::Info); while(!want_to_die) { log.print("This is a logging test................................\n"); log.print("Some more testing.....................................\n"); log.print("Even more testing.....................................\n"); } return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstringlistex.cc0000644000175000001440000000400711036722347022671 0ustar wlachusers#include "wvstringlist.h" #include "wvhashtable.h" #include int main() { WvStringList l; // WvStringList is essentially a WvHashTable WvString s("one"), s2("two"), s3("three"), foo("a : b : c : d"); l.append(&s, false); l.append(&s2, false); l.append(&s3, false); WvStringList::Iter i(l); // iterator i can go through the list for (i.rewind(); i.next();) printf("The list: %s\n", i().cstr()); l.zap(); // clean the list l.split(foo, ": "); // split the variable foo with the delimiter ": " and append to the list for (i.rewind(); i.next();) printf("Split foo: %s\n", i().cstr()); //prints: //Split foo: a //Split foo: b //Split foo: c //Split foo: d l.zap(); l.split(foo, ": ", 2); // split the variable foo with the delimiter ": " and limit = 2 // and append to the list for (i.rewind(); i.next();) printf("Split foo (2): %s\n", i().cstr()); //prints: //Split foo (2): a //Split foo (2): b : c : d l.zap(); l.split(foo, ": ", 3); // split the variable foo with the delimiter ": " and limit = 3 // and append to the list for (i.rewind(); i.next();) printf("Split foo (3): %s\n", i().cstr()); //prints: //Split foo (3): a //Split foo (3): b //Split foo (3): c : d /************************************************** Up until here, all is the same as WvStringTable Now we'll use popstr() and fill() ***************************************************/ printf("Popping: %s\n", l.popstr().cstr()); //prints: //Popping: a printf("Popping: %s\n", l.popstr().cstr()); //prints: //Popping: b l.zap(); char const *p = "hello"; char const *p2 = "world"; char const * const array[] = {p, p2, NULL}; l.fill(array); printf("After fill: %s\n", l.join(",").cstr()); //prints: After fill: hello l.zap(); l.append(&s, false); l.append(&s2, false); l.append(&s3, false); l.fill(array); printf("After fill: %s\n", l.join(",").cstr()); //prints: After fill: one,two,three,hello,world return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvudpex.cc0000644000175000001440000000220211036722347021252 0ustar wlachusers/* * A WvUDP example. * * WvUDPStream example. Waits for data on port 19. * Print something like: * udp: Local address is 0.0.0.0:33234 , and waits */ #include "wvistreamlist.h" #include "wvlog.h" #include "wvudp.h" int main(int argc, char **argv) { WvLog err("udp", WvLog::Error); WvIPPortAddr nothing; WvIPPortAddr remaddr(argc > 1 ? argv[1] : "127.0.0.1:19"); WvUDPStream sock(nothing, nothing); sock.enable_broadcasts(); err(WvLog::Info, "Local address is %s.\n", *sock.local()); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.add_after(l.tail, wvcon, false); l.add_after(l.tail, &sock, false); while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvcallbackex2.cc0000755000175000001440000000147311036722347022314 0ustar wlachusers #include "wvcallback.h" #include //Declare a new type of WvCallback called WvMath //This WvCallbak can point to functions that take 2 input parameters, both of //type integer, and returns an integer value. DeclareWvCallback(2, int, WvMath, int, int); class Math { public: int addition(int a, int b); }; int Math::addition(int a, int b) { return a+b; } int main() { WvMath callback(NULL); //Declare a WvCallback of type WvMath Math object; callback = wvcallback(WvMath, object, Math::addition); //Here callback becomes a pointer //to the member function (addition) that belongs to the WvMath class int answer = callback(5, 6); //Bind input parameter values to callback, //same way as we bind values to the addition function. printf("answer = %d\n", answer); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex6.cc0000644000175000001440000000064711036722347022056 0ustar wlachusers/* * A WvStream example * * Some text about this example... */ #include void mycallback(WvStream &s, void *userdata) { WvStream *outstream = (WvStream *)userdata; char *str = s.getline(); if (str) outstream->print("You said: %s\n", str); } int main() { wvcon->setcallback(mycallback, wvcon); while (wvcon->isok()) { if (wvcon->select(-1)) wvcon->callback(); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvresolverex.cc0000644000175000001440000000244511036722347022334 0ustar wlachusers /* * A WvResolver example. * * Tries to look up two host names given on the command line. * The expected output: * resolver: 1 not in DNS. * resolver: 2 not in DNS. * resolver: 1 not in DNS. * resolver: 2 not in DNS. * resolver: 1 not in DNS. * resolver: 2 not in DNS. * */ #include "wvresolver.h" #include "wvlog.h" void test(WvResolver &dns, int argc, char **argv) { WvLog log("resolver", WvLog::Info); const WvIPAddr *addr; int res1, res2; res1 = res2 = -1; while (res1 < 0 || res2 < 0) { if (res1 < 0) { res1 = dns.findaddr(100, argc > 1 ? argv[1] : "abyss.cnss.ca", &addr); if (res1 > 0) log.print("Found address for 1: %s\n", (WvString)(*addr)); else if (res1 < 0) log.print("[1] "); else log(WvLog::Error, "1 not in DNS.\n"); } if (res2 < 0) { res2 = dns.findaddr(100, argc > 2 ? argv[2] : "frank.foxnet.net", &addr); if (res2 > 0) log.print("Found address for 2: %s\n", (WvString)(*addr)); else if (res2 < 0) log.print("[2] "); else log(WvLog::Error, "2 not in DNS.\n"); } } } int main(int argc, char **argv) { { WvResolver dns; test(dns, argc, argv); test(dns, argc, argv); } { WvResolver dns; test(dns, argc, argv); } return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvlogbufex.cc0000644000175000001440000000364311036722347021752 0ustar wlachusers/* * A WvLogBuf example. * * The expected output is : * * 1043174856 logA<*1>: a message+ * 1043174856 logB<*2>: b message+ * 1043174856 logC<*3>: c message with extra newline+ * 1043174856 logC<*4>: c2 message+ * 1043174856 logA: a info message+ * 1043174856 logA<*1>: a normal message with [07][08] control chars+ * 1043174856 logA<*1>: a split+ * 1043174856 logB<*2>: message with stuff+ * 1043174856 logB: and other stuff.+ * 1043174856 logC<*3>: another split message.+ * * * 1043174856 logA<*1>: a message+ * 1043174856 logB<*2>: b message+ * 1043174856 logC<*3>: c message with extra newline+ * 1043174856 logC<*4>: c2 message+ * 1043174856 logA: a info message+ * 1043174856 logA<*1>: a normal message with [07][08] control chars+ * 1043174856 logA<*1>: a split+ * 1043174856 logB<*2>: message with stuff+ * 1043174856 logB: and other stuff.+ * 1043174856 logC<*3>: another split message.+ * 1043174856 logC<*3>: .. and it's wonky!+ * */ #include "wvlogbuffer.h" int main() { WvLogBuffer rc(4); WvLog a("logA", WvLog::Debug), b("logB", WvLog::Debug2); WvLog c("logC", WvLog::Debug3), c2 = c.split(WvLog::Debug4); a("a message\n"); b("b message\n"); c("c message with extra newline\n\n\n"); // extra newline discarded c2("c2 message\n"); // the second line should be back at WvLog::Debug a(WvLog::Info, "a info message\n"); a("a normal message with \a\b control chars\r\n"); // should display like this: // a split // message with stuff // and other stuff a("a split "); b("message "); b("with stuff "); b(WvLog::Info, "and other stuff.\n"); // should display all on one line c("another split "); c2(WvLog::Debug3, "message."); // should auto-terminate line on display rc.dump(*wvcon); wvcon->print("\n\n"); c2(WvLog::Debug3, " .. and it's wonky! \n"); rc.dump(*wvcon); return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvpipelogex.cc0000644000175000001440000000162611036722347022132 0ustar wlachusers/* * A WvPipe and WvLog example. * * This program allows you to enter bash commands, runs them, and pipes the * output back to you */ #include "wvpipe.h" #include "wvlog.h" int main(int argc, char **argv) { const char *_av[] = { "/bin/bash", NULL }; const char **av = (argc < 2) ? _av : (const char **)(argv + 1); WvLog log(av[0]); WvPipe p(av[0], av, true, false, false); wvcon->autoforward(p); p.autoforward(*wvcon); p.write("test string\r\n"); while (p.isok() && wvcon->isok()) { if (p.select(100)) p.callback(); if (wvcon->select(100)) wvcon->callback(); } p.flush_then_close(50000); while (p.isok()) { log("Flushing...\n"); if (p.select(1000)) p.callback(); } if (p.child_exited()) log(WvLog::Notice, "Exited (return code == %s)\n", p.exit_status()); _exit(0); // don't kill the subtask return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/Makefile0000644000175000001440000000063511036722347020711 0ustar wlachusers#Remember to set TOPDIR to a directory containing wvrules.mk! ifeq ($(TOPDIR),) TOPDIR=../../.. WVSTREAMS_SRC=$(TOPDIR) endif STATIC=1 include $(TOPDIR)/wvrules.mk LIBS=-L$(TOPDIR) -lwvstreams -lwvutils -lcrypto XPATH=$(TOPDIR)/include LD_LIBRARY_PATH+=:$(TOPDIR) export LD_LIBRARY_PATH PROGS = $(shell echo *.cc | sed 's/\.cc//g') default: all all: $(PROGS) $(PROGS): $(XFILES) clean: rm -f $(PROGS) wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvhttpex.cc0000644000175000001440000000242311036722347021446 0ustar wlachusers/* * A WvHttpStream example. * * This program downloads a file via http. * The expected result is: * http: Now in state 0 * http: Now in state 1 * http: [ 0] * http: Now in state 2 * http: [ 0] * http: Now in state 3 * http: [ 0][ 0][ 0][ 0][ 0][ 0][ 0][ 0][ 0] * http: Now in state 4 * http: [ 751][ 922][ 0] * */ #include "wvhttp.h" #include "wvistreamlist.h" #include "wvlog.h" #include "wvfile.h" int main(int argc, char **argv) { WvLog log("http", WvLog::Info); WvURL url("http://www.net-itech.com/"); WvHTTPStream http(url); WvFile out("http.out", O_WRONLY | O_TRUNC | O_CREAT); WvHTTPStream::State last_state = WvHTTPStream::Done; static char buf[10240]; size_t len; WvIStreamList l; l.add_after(l.tail, &http, false); while (http.isok() && out.isok()) { if (last_state != http.state) { log("\nNow in state %s\n", http.state); last_state = http.state; } if (l.select(100)) l.callback(); if (http.select(0)) { len = http.read(buf, sizeof(buf)); out.write(buf, len); log("[%6s]", len); } } if (!http.isok() && http.geterr()) log("http: %s\n", http.errstr()); return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvtimeex.cc0000644000175000001440000000112611036722347021424 0ustar wlachusers/* * A WvTimeStream example. * * This program should take exactly ten seconds to run, but * tests how well the time stream handles being executed in bursts. */ #include "wvtimestream.h" #include "wvlog.h" #include int main() { WvLog log("time", WvLog::Info); WvTimeStream t; int count; log("Artificial burstiness - should take exactly 10 seconds\n"); t.set_timer(100); for (count = 0; count < 100; count++) { if (!(count % 10)) log("\n"); while (!t.select(5*(100-count))) ; t.callback(); log("%02s ", count); } return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamlistex.cc0000644000175000001440000000125211036722347022655 0ustar wlachusers/* * A WvPipe example. * * Some text about this example... */ #include int X = -1; // int X = 0; // int X = 1000; int main() { const char *argv1[] = { "sh", "-c", "while :; do echo foo; sleep 3; done", NULL }; const char *argv2[] = { "sh", "-c", "while :; do echo snorkle; sleep 1; done", NULL }; WvPipe stream1(argv1[0], argv1, false, true, false); WvPipe stream2(argv2[0], argv2, false, true, false); stream1.autoforward(*wvcon); stream2.autoforward(*wvcon); while (stream1.isok() || stream2.isok()) { if (stream1.select(X)) stream1.callback(); if (stream2.select(X)) stream2.callback(); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvbase64ex.cc0000644000175000001440000000166011036722347021555 0ustar wlachusers/* * A WvBase64 example. * */ #include "wvbase64.h" #include "wvstream.h" #include "wvistreamlist.h" #include "wvencoderstream.h" #include "wvbufbase.h" int main() { WvEncoder *enc; enc = new WvBase64Encoder(); WvInPlaceBuf to_encode(100); WvInPlaceBuf encoded(100); to_encode.put("123",3); // to_encode contains the string to be encoded in base64 if (enc->encode(to_encode, encoded, true,true)) printf ("This is the result: %s\n", (char *) encoded.get(1)); // Displayed on screen: // This is the result: MTIz WvEncoder *dec; dec = new WvBase64Decoder(); WvInPlaceBuf to_decode(100); WvInPlaceBuf decoded(100); to_decode.put("MTIz",4); // to_encode contains the string to be encoded in base64 if (dec->encode(to_decode, decoded, true)) printf ("This is the result: %s\n", (char *) decoded.get(1)); // Displayed on screen: // This is the result: 123 return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamlistex2.cc0000644000175000001440000000127011036722347022737 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include #include int main() { const char *argv1[] = { "sh", "-c", "while :; do echo foo; sleep 3; done", NULL }; const char *argv2[] = { "sh", "-c", "while :; do echo snorkle; sleep 1; done", NULL }; WvPipe stream1(argv1[0], argv1, false, true, false); WvPipe stream2(argv2[0], argv2, false, true, false); stream1.autoforward(*wvcon); stream2.autoforward(*wvcon); WvIStreamList l; l.append(&stream1, false); l.append(&stream2, false); while (stream1.isok() || stream2.isok()) { if (l.select(-1)) l.callback(); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvhashtableex.cc0000755000175000001440000000554511036722347022435 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * WvHashTable sample program. * Suppose you are learning a new language that is alphabetical and you want * to register all the words you added to your vocabulary in that * language. So you will need a dictionary where you can look up on words * that you have learned. * Assuming that you will not forget any word you had previously learned, * this dictionary shall not contain repetitive words. */ #include "wvhashtable.h" #include "wvstring.h" #include "wvlinklist.h" #include // Declare a HashTable class that handles WvString data types DeclareWvTable(WvString); /*this subfunction ascending is used for sorting*/ int ascending(const WvString *a, const WvString *b) { return strncasecmp(*a, *b, strlen(a->cstr())); } int main() { // This is a dictionary that can contain at most 10 words WvStringTable t(100); // Here's a list of new words in your vocabulary WvString s1("aussi"), s2("Bonjour"), s3("comment"); WvString s4("demain"), s5("non"), s6("oui"); WvString s7("matin"), s8("bonsoir"), s9("bien"); WvString s10("depanneur"); // Add the list of new words to the dictionary // false = do not autofree the WvString t.add(&s1, false); t.add(&s2, false), t.add(&s3, false); t.add(&s4, false); t.add(&s5, false), t.add(&s6, false); t.add(&s7, false); t.add(&s8, false), t.add(&s9, false), t.add(&s10, false); // Using an iterator, we can print out the entire content of the hashtable printf("What words do we have in the dictionary?\n"); WvStringTable::Iter i(t); for( i.rewind(); i.next(); ) { printf("%s\n", i->cstr() ); } printf("There are %d words stored in the dictionary so far.\n", t.count()); // To look up words in the dictionary, put the WvString data inside the [] // and do the following to print it out WvString sample1("Bonjour"); printf("Is 'Bonjour' in the dictionary? %s\n", t[sample1]?"Yes":"No"); WvString sample2("Salut"); printf("Is 'Salut' in the dictionary? %s\n", t[sample2]?"Yes":"No"); // To remove a word from the dictionary // For example, if you want to remove the word "aussi" in your dictionary t.remove(&s1); // Then print out the list of words in the dictionary again printf("Modified List:\n"); for( i.rewind(); i.next(); ) { printf("%s\n", i->cstr() ); } WvStringTable::Sorter s(t,ascending); printf("Sorted modified List:\n"); for( s.rewind(); s.next(); ) { printf("%s\n", s->cstr() ); } // You can empty the entire dictionary by doing this: t.zap(); // Then print out the list of words in the dictionary again printf("Empty List:\n"); for( i.rewind(); i.next(); ) { printf("%s\n", i->cstr() ); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvpipeex.cc0000644000175000001440000000015111036722347021420 0ustar wlachusers/* * A WvPipe example. * * Some text about this example... */ #include "wvpipe.h" int main() { } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvlistex.cc0000644000175000001440000000245011036722347021442 0ustar wlachusers/* * A WvStringList example. * * Some text about this example... */ #include "wvstring.h" #include "wvlinklist.h" DeclareWvList(WvString); // creates class WvStringList int main() { WvStringList l; WvStringList::Iter i(l); WvString autostr("bork bork"); l.append(new WvString("blah blah"), true); // auto-free enabled l.append(&autostr, false); // auto-free disabled: C++ will do this one // etc for (i.rewind(); i.next(); ) { // we will learn a nicer way to do this with WvStream later. // we could typecast i() to (const char *), but the cstr() member // function is nicer (we all avoid typecasts when possible, right?) printf("%s\n", i().cstr()); } printf("Is the list empty? %s\n",l.isempty() ? "Yes" : "No"); printf("The first element is: %s\n", l.first()->cstr()); printf("The last element is: %s\n", l.last()->cstr()); // exiting this function will have C++ auto-free the list, which // causes the list to auto-free the "blah blah" string. C++ also // auto-frees the "bork bork" string automatically. It doesn't matter // that "bork bork" is freed before the list destructor is called; the // list doesn't refer to its members during destruction, unless it // needs to free the elements by itself. } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex2.cc0000644000175000001440000000030311036722347022037 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include int main() { while (wvcon->isok()) wvcon->print("You said: %s\n", wvcon->blocking_getline(-1)); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamfunex.cc0000644000175000001440000000236511036722347022500 0ustar wlachusers/* * A fun WvStream example. * * Some text about this example... */ #include #include #include #include void concallback(WvStream &con, void *userdata) { WvStream &modem = *(WvStream *)userdata; char *str = con.getline(); if (str) modem.print("%s\r", str); // modems like CR, not newline } int main() { const char *argv1[] = { "sh", "-c", "while :; do echo foo; sleep 3; done", NULL }; const char *argv2[] = { "sh", "-c", "while :; do echo snorkle; sleep 2; done", NULL }; WvLog log("logger", WvLog::Info); WvLog modemlog("modem", WvLog::Info); WvPipe pipe1(argv1[0], argv1, false, true, false); WvPipe pipe2(argv2[0], argv2, false, true, false); WvModem modem("/dev/ttyS2", O_RDWR); pipe1.autoforward(log); pipe2.autoforward(log); wvcon->setcallback(concallback, &modem); modem.autoforward(modemlog); WvIStreamList l; l.append(&pipe1, false); l.append(&pipe2, false); l.append(&modem, false); l.append(wvcon, false); if (!modem.isok()) modemlog(WvLog::Error, "%s\n", modem.errstr()); while (wvcon->isok()) { if (l.select(1000)) l.callback(); else log("[TICK]\n"); } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstringtableex.cc0000644000175000001440000000154011036722347023004 0ustar wlachusers#include "wvstringtable.h" #include "wvhashtable.h" #include int main() { WvStringTable t(10); // size: 10 elements // WvStringTable is essentially a WvHashTable WvString s("one"), s2("two"), s3("three"); t.add(&s, false); t.add(&s2,false); t.add(&s3,false); // t.add("foo") is not allowed // refer to WvHashTable for more information printf("%s\n", t.join(",").cstr()); //prints out: one,two,three printf("%s\n", t.join().cstr()); // By default, t.join() is using " \t" as a delimiter // prints out: one two three t.zap(); //erasing all contents of t t.split("a : b : c : d ", ":"); printf("%s\n", t.join(",").cstr()); // prints out: a , b , c , d t.split("x"); t.split("y"); t.split("z"); printf("%s\n", t.join(",").cstr()); // prints out: a , b , c , d ,x,y,z return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex4.cc0000644000175000001440000000063311036722347022047 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include int main() { char buffer[10]; size_t numread; while (wvcon->isok()) { if (wvcon->select(-1)) { numread = wvcon->read(buffer, sizeof(buffer)); if (numread) { wvcon->print("You said: "); wvcon->write(buffer, numread); wvcon->print(" (%s bytes)\n", numread); } } } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvcallbackex.cc0000755000175000001440000000140311036722347022223 0ustar wlachusers/* * A WvCallback example. * */ #include "wvcallback.h" #include //Declare a new type of WvCallback called WvMath //This WvCallbak can point to functions that take 2 input parameters, both of type //integer, and returns an integer value. DeclareWvCallback(2, int, WvMath, int, int); int addition(int a, int b) { return a+b; } int main() { WvMath callback(NULL); //Declare a WvCallback of type WvMath //callback = wvcallback(WvMath, *this, Math::addition); callback = addition; // Now callback becomes a function pointer to the addition function int answer = callback(5, 6); //Bind input parameter values to callback, same //way as we bind values to the addition function. printf("answer = %d\n", answer); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvlogex.cc0000644000175000001440000000233611036722347021253 0ustar wlachusers/* * A WvLogRcv example. * * Expected output: * logA<*1>: a message * logB<*2>: b message * logB<*2>: b message * logC<*3>: c message with extra newline * logC<*4>: c2 message * logA: a info message * logA<*1>: a normal message with [07][08] control chars * logA<*1>: a split * logB<*2>: message with stuff * logB: and other stuff. * logC<*3>: another split message. */ #include "wvlogrcv.h" int main() { WvLog a("logA", WvLog::Debug), b("logB", WvLog::Debug2); WvLog c("logC", WvLog::Debug3), c2 = c.split(WvLog::Debug4); a("a message\n"); b("b message\n"); // prints twice -- once for rc, once for rc2 c("c message with extra newline\n\n"); // extra newline discarded c2("c2 message\n"); // the second line should be back at WvLog::Debug a(WvLog::Info, "a info message\n"); a("a normal message with \a\b control chars\r\n"); // should display like this: // a split // message with stuff // and other stuff a("a split "); b("message "); b("with stuff "); b(WvLog::Info, "and other stuff.\n"); // should display all on one line c("another split "); c2(WvLog::Debug3, "message."); // should auto-terminate line on exit return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex.cc0000644000175000001440000000030611036722347021760 0ustar wlachusers/* * A WvStream example. * * Some documentation for WvStreams... */ #include int main() { while (wvin->isok()) wvout->print("You said: %s\n", wvin->blocking_getline(-1)); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstreamex7.cc0000644000175000001440000000066011036722347022052 0ustar wlachusers/* * A WvStream example. * * Some text about this example... */ #include int main() { int nothing_count = 0; wvcon->autoforward(*wvcon); while (wvcon->isok()) { if (wvcon->select(1000)) { nothing_count = 0; wvcon->callback(); } else { nothing_count++; wvcon->print("[TICK]"); if (nothing_count == 10) { wvcon->print("[TIMEOUT]\n"); break; } } } } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvtimeoutex.cc0000644000175000001440000000074511036722347022162 0ustar wlachusers/* * A WvTimeOut example. * * Should only fire once. */ #include "wvtimeoutstream.h" #include "wvlog.h" #include WvLog log("timeout", WvLog::Info); void timeout(WvStream &s, void *userdata) { static int count = 0; count++; log("Fire %s\n", count); } int main() { WvTimeoutStream t(1000); t.setcallback(timeout, NULL); for (int i = 0; i < 3 && t.isok(); i++) { if (t.select(-1)) t.callback(); } return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvstringex.cc0000644000175000001440000000355311036722347022002 0ustar wlachusers/* * A WvString example. * * Some text about this example... */ #include "wvstring.h" #include #include int main() { const char *mystring = "Cool!"; // Creates x as a wrapper for mystring WvStringParm x(mystring); // ...x's internal string buffer points to mystring assert(x.cstr() == mystring); assert(strcmp(x, mystring) == 0); // Creates y as a copy of mystring WvString y(mystring); // ...y's internal string buffer points to a copy of mystring assert(y.cstr() != mystring); assert(strcmp(y, mystring) == 0); // Creates z as a copy of y WvString z(y); // ...z's internal string buffer points to y's assert(z.cstr() == y.cstr()); // ...prove it by modifying y // (dangerous use of const_cast<>, see below for example of edit()) const_cast(y.cstr())[0] = 'Z'; // change first char to Z assert(z.cstr()[0] == 'Z'); // ...and make it point to a unique copy of the string z.unique(); // could also write z.edit() assert(z.cstr() != y.cstr()); // ...prove it by modifying y again const_cast(y.cstr())[0] = 'Y'; // change first char to Y assert(z.cstr()[0] == 'Z'); // but z points to a different string // Notice that cstr() deliberately returns a const char* to make // it hard to accidentally modify an internal string buffer that // is shared by multiple WvStrings. That is why the use of edit() // is preferred. This automatically performs unique() then returns // a non-const pointer to the internal string buffer. // Consider: WvString w(z); // ...w's internal string buffer points to z's assert(w.cstr() == z.cstr()); // ...but not anymore w.edit()[0] = 'W'; assert(w.cstr() != z.cstr()); assert(w.cstr()[0] == 'W'); assert(z.cstr()[0] == 'Z'); puts("Success!"); return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvtcpex.cc0000644000175000001440000000135411036722347021257 0ustar wlachusers/* * A WvTCP example. * * Telnets to your local SMTP port, or any other port given * on the command line. */ #include "wvtcp.h" #include "wvistreamlist.h" #include "wvlog.h" int main(int argc, char **argv) { WvLog err("tcp", WvLog::Error); WvTCPConn sock(WvString(argc==2 ? argv[1] : "0.0.0.0:25")); wvcon->autoforward(sock); sock.autoforward(*wvcon); WvIStreamList l; l.add_after(l.tail, wvcon, false); l.add_after(l.tail, &sock, false); while (wvcon->isok() && sock.isok()) { if (l.select(-1)) l.callback(); } if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", wvcon->errstr()); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", sock.errstr()); return 0; } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/wvdiriterex.cc0000644000175000001440000000106711036722347022134 0ustar wlachusers/* * A WvDirIter example. * * Takes a directory on the command line, and * prints everything it sees. * */ #include "wvdiriter.h" int main() { WvString dirname("."); // or WvString dirname("/home/user/"); // dirname contains the directory you want to list bool recurse = false; // If true, do recursively WvDirIter i( dirname, recurse ); for( i.rewind(); i.next(); ) { printf( "%s \n", (const char *) i->fullname); } // prints something like: // ./a.txt // ./b.txt // ./c.txt return( 0 ); } wvstreams-4.6.1/Docs/sgmlmanual/egfiles/intlistex.cc0000644000175000001440000000057011036722347021601 0ustar wlachusers#include "wvstringlist.h" #include "wvhashtable.h" #include DeclareWvList(int); //Declaration of list of integers int main() { int a=5, b=6; intList l; //the list intList::Iter i(l); //the iterator l.add(&a, false); l.add(&b, false); for (i.rewind(); (i.next()) ; ) printf("Foo: %d\n", i()); //prints: //Foo: 5 //Foo: 6 return 0; }wvstreams-4.6.1/Docs/sgmlmanual/configfile.wvsgml0000644000175000001440000000565511036722347021210 0ustar wlachusersWVPART(configfile, The ConfigFile (.ini manager) Library, WVCHAPTER(cfgentry, Configuration Entries, This is a config entry class, called WvConfigEntry. WVCMD(WvConfigEntry (WvStringParm _name, WvStringParm _value)) to initialize. WVCMD(void WvConfigEntry::set(WvStringParm _value)) sets the value of a particular entry to "_value". ) WVCHAPTER(cfgsection, Configuration Sections, The WvConfigSection class. WVCMD(const char *WvConfigSection::get(WvStringParm entry, const char *def_val)) gets the value of "entry", return "def_val" if not set. WVCMD(void WvConfigSection::set(WvStringParm entry, WvStringParm value)) sets the value of "entry". If the entry doesn't exist, add it. WVCMD(void WvConfigSection::quick_set(WvStringParm entry, WvStringParm value)) add "entry" to the end of the section, assuming no duplicates exist. WVCMD(void WvConfigSection::dump(WvStream &fp)) prints out all entries available in the section and their corresponding values. ) WVCHAPTER(wvconf, Configuration Files (The WvConf Class), WvConf is a file management class used to read/write config files that are formatted in the style of Windows .ini files. The most common used functions are: WVCMD(WvConf cfg("filename.ini")) for initialization. WVCMD(const char *WvConf::get(WvStringParm section, WvStringParm entry, const char *def_val)) gets the value of variable "entry" in section "section". If it is not set, return the default value "def_val". WVCMD(int WvConf::getint(WvStringParm section, WvStringParm entry, int def_val)) This "int" version of get is smart enough to interpret words like on/off, true/false, and yes/no. WVCMD(void WvConf::set(WvStringParm section, WvStringParm entry, const char *value)) set the value of [section]entry to be "value". WVCMD(void WvConf::setint(WvStringParm section, WvStringParm entry, int value)) set the value of [section]entry to be "value". It just converts "value" to a string. WVCMD(WvString WvConf::getraw(WvString wvconfstr, int &parse_error)) Gets an entry, given a string in the form [section]entry=value. Returns the value or NULL if not found. The parameter parse_error is set to the return value of parse_wvconf_request. WVCMD(void WvConf::setraw(WvString wvconfstr, const char *&xvalue, int &parse_error)) Takes a string in the form [section]entry=value and sets it. Returns an error code as defined in parse_wvconf_request. The value parameter is also set to the value (useful in rcommand, when we display the value after it has been set). WVCMD(void WvConf::maybeset(WvStringParm section, WvStringParm entry, const char *value)) only set the value if it isn't already in the config file. WVCMD(void WvConf::maybesetint(WvStringParm section, WvStringParm entry, int value)) only set the value if it isn't already in the config file. WVCMD(void WvConf::delete_section(WvStringParm section)) deletes the entire section. ) ) wvstreams-4.6.1/Docs/sgmlmanual/tutorial.wvsgml0000644000175000001440000000147211036722347020737 0ustar wlachusersWVPART(tutorial, Getting Started (Really Fast), WVPARTINTRO(A WvStreams Tutorial, In this part, we dive quickly into some example programs that will give you a feel for the concepts behind WvStreams before you need to deal with all the gory details. We'll show you how to compile your own applications, then we'll write a network client and server, and demonstrate how to read and write some config files. In later chapters, we'll go into more detail about the techniques used to write these programs, and why they really work. For now, just try out the programs as we present them and think about how the different parts might fit together. ) WVCHAPTER(telnet, A Cheesy Replacement for Telnet,x) WVCHAPTER(chat, A Multi-User Chat Program,x) WVCHAPTER(cfgexample, Configuration (.ini) Files,x) ) wvstreams-4.6.1/win32/0000755000175000001440000000000011077124114013532 5ustar wlachuserswvstreams-4.6.1/win32/wvwinstreamclone.cc0000644000175000001440000001121211042636572017455 0ustar wlachusers #define WINVER 0x0500 #include "wvwinstreamclone.h" ATOM WvWinStreamClone::s_aClass = 0; WvWinStreamClone::WndVector WvWinStreamClone::s_wndpool; WvWinStreamClone::WndStreamMap WvWinStreamClone::s_wndmap; HWND WvWinStreamClone::alloc_wnd() { if (s_wndpool.empty()) { HWND hWnd = CreateWindow( "WvWinStreamClone", "WvWinStreamWindowName", WS_POPUP | WS_DISABLED, CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x extent CW_USEDEFAULT, // initial y extent HWND_MESSAGE, NULL, NULL, NULL ); assert(hWnd); s_wndpool.push_back(hWnd); } HWND hWnd = s_wndpool.back(); s_wndpool.pop_back(); // associate window with this instance s_wndmap[hWnd] = this; return hWnd; } void WvWinStreamClone::free_wnd(HWND w) { s_wndpool.push_back(w); } DWORD WvWinStreamClone::Initialize() { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WvWinStreamClone::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = GetModuleHandle(NULL); wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "WvWinStreamClone"; s_aClass = RegisterClass(&wc); if (!s_aClass) { DWORD error = GetLastError(); return error; } return 0; } WvWinStreamClone::WvWinStreamClone(WvStream * _cloned) : WvStreamClone(_cloned), m_pending_callback(false), m_select_in_progress(false), m_msec_timeout(500) { memset(&m_si, 0, sizeof(m_si)); m_hWnd = alloc_wnd(); pre_poll(); } WvWinStreamClone::~WvWinStreamClone() { free_wnd(m_hWnd); } // for each socket in "set", add the "event" to the its associated mask in sockmap void WvWinStreamClone::select_set(SocketEventsMap &sockmap, fd_set *set, long event ) { for (unsigned i=0; ifd_count; i++) { SOCKET &socket = set->fd_array[i]; sockmap[socket] |= event; } FD_ZERO(set); } void WvWinStreamClone::pre_poll() { this->_build_selectinfo(m_si, m_msec_timeout, false, false, false, true); // We must only call WSAAsyncSelect once per socket, so we need // to collect all the events from each set first, grouping them by // socket rather than by event SocketEventsMap sockmap; this->select_set(sockmap, &m_si.read, FD_READ); this->select_set(sockmap, &m_si.write, FD_WRITE); this->select_set(sockmap, &m_si.except, FD_OOB); // Call WSAAsyncSelect, asking the OS to send us a message when the socket // becomes readable | writable | exceptional for (SocketEventsMap::iterator i = sockmap.begin(); i!=sockmap.end(); ++i) { SOCKET socket = (*i).first; long events = (*i).second; int result = ::WSAAsyncSelect(socket, m_hWnd, WM_SELECT, events | FD_CONNECT | FD_CLOSE | FD_ACCEPT); assert(result == 0); } // alarm ::KillTimer(m_hWnd, TIMER_ID); if (m_si.msec_timeout >= 0) { ::SetTimer(m_hWnd, TIMER_ID, m_si.msec_timeout, NULL); } m_select_in_progress = true; } void WvWinStreamClone::post_poll() { bool sure = this->_process_selectinfo(m_si, true); if (sure || m_pending_callback) { m_pending_callback = false; callback(); if (globalstream) globalstream->callback(); } } void WvWinStreamClone::select_callback(SOCKET socket, int events, int error) { if (events | FD_READ) FD_SET(socket, &m_si.read); if (events | FD_WRITE) FD_SET(socket, &m_si.write); if (events | FD_OOB) FD_SET(socket, &m_si.except); m_pending_callback = true; if (m_select_in_progress) { ::PostMessage(m_hWnd, WM_DONESELECT, 0, 0); m_select_in_progress = false; } } LRESULT CALLBACK WvWinStreamClone::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DONESELECT: { WvWinStreamClone *_this = s_wndmap[hwnd]; assert(_this); _this->post_poll(); _this->pre_poll(); break; } case WM_SELECT: { WvWinStreamClone *_this = s_wndmap[hwnd]; assert(_this); SOCKET socket = wParam; int events = WSAGETSELECTEVENT(lParam); int error = WSAGETSELECTERROR(lParam); _this->select_callback( socket, events, error ); break; } case WM_TIMER: { ::PostMessage(hwnd, WM_DONESELECT, 0, 0); break; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } void WvWinStreamClone::setclone(IWvStream *newclone) { WvStreamClone::setclone(newclone); if (newclone != NULL) my_type = WvString("WvWinStreamClone:%s", newclone->wstype()); else my_type = "WvWinStreamClone:(none)"; } wvstreams-4.6.1/win32/streams.cc0000644000175000001440000002421711077124114015525 0ustar wlachusers#include "streams.h" #include "wvstring.h" #include #include #include #include #include #if _MSC_VER // MS Visual C++ doesn't support varags preproc macros # define DPRINTF #else #if 0 # define DPRINTF(x, args...) do { \ printf(x, ## args); fflush(stdout); \ } while (0) #else # define DPRINTF(x, args...) do { } while(0) #endif #endif // this class changes the default libc stdout buffering to "line buffered" // and stderr to "unbuffered", like they should be in any sane system. // Apparently they start off as "fully buffered" in most Windows systems. class FixLibcIoBuffers { public: FixLibcIoBuffers() { setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IONBF, 0); } }; static FixLibcIoBuffers fixbufs; // these versions of close/read/write try to work with both sockets and // msvcrt file descriptors! (I hope we never get a socket with the same // VALUE as a file descriptor!) static void errcode(int err) { if (err == EIO) err = EBADF; // sometimes we get EIO when Unix would be EBADF if (err == WSAENOTSOCK) err = EBADF; // if it's not a socket, it's also not a fd SetLastError(err); errno = err; } static bool is_socket(int fd) { // if _get_osfhandle doesn't work, it must not be a fd, so assume it's // a socket. return (HANDLE)_get_osfhandle(fd) == INVALID_HANDLE_VALUE; } int close(int fd) { int ret; if (is_socket(fd)) { ret = closesocket(fd); errcode(GetLastError()); } else { ret = _close(fd); errcode(errno); } return ret; } int read(int fd, void *buf, size_t count) { int ret; if (is_socket(fd)) { ret = recv(fd, (char *)buf, count, 0); errcode(GetLastError()); } else { ret = _read(fd, buf, count); errcode(errno); } return ret; } int write(int fd, const void *buf, size_t count) { int ret; if (is_socket(fd)) { ret = send(fd, (char *)buf, count, 0); errcode(GetLastError()); } else { ret = _write(fd, buf, count); errcode(errno); } return ret; } int socketpair(int family, int type, int protocol, int *sb) { SOCKET insock, outsock, newsock; struct sockaddr_in sock_in; if (type != SOCK_STREAM) return -1; newsock = socket(AF_INET, type, 0); if (newsock == INVALID_SOCKET) return -1; sock_in.sin_family = AF_INET; sock_in.sin_port = 0; sock_in.sin_addr.s_addr = INADDR_ANY; if (bind(newsock, (struct sockaddr *) &sock_in, sizeof (sock_in)) < 0) return -1; int len = sizeof (sock_in); if (getsockname(newsock, (struct sockaddr *)&sock_in, &len) < 0) return -1; if (listen(newsock, 2) < 0) return -1; outsock = socket(AF_INET, type, 0); if (outsock == INVALID_SOCKET) return -1; sock_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (connect(outsock, (struct sockaddr *)&sock_in, sizeof(sock_in)) < 0) return -1; /* For stream sockets, accept the connection and close the listener */ len = sizeof(sock_in); insock = accept(newsock, (struct sockaddr *)&sock_in, &len); if (insock == INVALID_SOCKET) return -1; if (closesocket(newsock) < 0) return -1; sb[0] = insock; sb[1] = outsock; return 0; } static void CALLBACK completion(DWORD error, DWORD nread, LPOVERLAPPED ov) { } static size_t fake_read(int fd, void *buf, size_t len) { HANDLE h = (HANDLE)_get_osfhandle(fd); INPUT_RECORD p; DPRINTF("fake_read(%d/%d,%p,%d) = ", fd, (int)h, buf, (int)len); DWORD ret = 0; OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); ov.Offset = SetFilePointer(h, 0, NULL, FILE_CURRENT); if (PeekNamedPipe(h, NULL, 0, NULL, &ret, NULL)) { // cygwin sshd/telnetd uses named pipes for stdin. We have to // support these separately. Getting stuck in ReadFile on a named // pipe appears to freeze up gethostbyname() for some reason on win2k! DPRINTF("(stdin is a pipe)\n"); while (PeekNamedPipe(h, NULL, 0, NULL, &ret, NULL) && !ret) { DPRINTF("."); Sleep(100); } ReadFile(h, buf, len, &ret, NULL); } else if (PeekConsoleInput(h, &p, 1, &ret)) { // a typical stdin/out pair refers to a console. Unfortunately, // console I/O is stupid: you can poll it to see if it's ready, but // if you have it in line mode, then it's not *really* ready. // ReadConsole/ReadFile will only return after the user hits enter. // Unfortunately, it seems the only way around this is to disable // line/echo mode and fake it ourselves. Hopefully this isn't too // ugly... DPRINTF("(stdin is a console)\n"); size_t used = 0; char *xbuf = (char *)buf; HANDLE hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); DWORD conmode = 0; GetConsoleMode(h, &conmode); SetConsoleMode(h, conmode & ~(ENABLE_LINE_INPUT | ENABLE_MOUSE_INPUT | ENABLE_ECHO_INPUT)); while (PeekConsoleInput(h, &p, 1, &ret)) { DWORD tmp; if (ret) { ReadConsoleInput(h, &p, 1, &ret); assert(ret); if (p.EventType == KEY_EVENT && p.Event.KeyEvent.bKeyDown) { int key = p.Event.KeyEvent.uChar.AsciiChar; if (key == '\r') // end of line { xbuf[used++] = '\n'; WriteConsole(hout, "\r\n", 2, &tmp, NULL); ret = used; break; } else if (key == '\b' && used > 0) { used--; WriteConsole(hout, "\b \b", 3, &tmp, NULL); } else if (key && used < len-1) { xbuf[used++] = key; WriteConsole(hout, xbuf+used-1, 1, &tmp, NULL); } } } else { DPRINTF("."); WaitForSingleObjectEx(h, 1000, true); } } CloseHandle(hout); } else { // stdin might be redirected from a file, in which case we can // probably safely (heh) assume it'll never block. Still, try // ReadFileEx with a timeout first and see if that works. DPRINTF("(stdin is a file)\n"); while (!ret) { DPRINTF("."); int rv = 0; if (ReadFileEx(h, buf, 0, &ov, &completion)) { rv = SleepEx(1000, true); CancelIo(h); DPRINTF("(rv is %d)\n", rv); if (rv == WAIT_IO_COMPLETION) { ReadFile(h, buf, len, &ret, NULL); break; } else if (!rv) // timed out Sleep(1); // ensure lock is released for nonzero time (1ms) else return 0; // unknown problem: assume EOF } else { // can't do ReadFileEx: probably stupid Win9x. ReadFile(h, buf, len, &ret, NULL); break; } } } DPRINTF("[%d]\n", ret); return ret; } DWORD WINAPI fd2socket_fwd(LPVOID lpThreadParameter) { // return 0; DWORD retval = 0; const int BUFSIZE = 512; socket_fd_pair *pair = (socket_fd_pair *)lpThreadParameter; // fprintf(stderr, "forwarding %d -> %d\n", // pair->fd, pair->socket); fflush(stderr); char buf[BUFSIZE]; while (true) { char *ptr = buf; size_t bytes = fake_read(pair->fd, ptr, BUFSIZE); if (bytes <= 0) { retval = bytes; break; } while (bytes > 0) { int written = send(pair->socket, ptr, bytes, 0); if (written < 0) { retval = written; break; } bytes -= written; ptr += written; } } shutdown(pair->socket, SD_BOTH); closesocket(pair->socket); // fprintf(stderr, "TERMINATING-%d\n", pair->fd); fflush(stderr); return retval; } DWORD WINAPI socket2fd_fwd(LPVOID lpThreadParameter) { DWORD retval = 0; const int BUFSIZE = 512; socket_fd_pair *pair = (socket_fd_pair *)lpThreadParameter; char buf[BUFSIZE]; while (true) { char *ptr = buf; int bytes = recv(pair->socket, ptr, BUFSIZE, 0); if (bytes <= 0) { retval = bytes; break; } while (bytes > 0) { int written = _write(pair->fd, ptr, bytes); if (written < 0) { retval = written; break; } bytes -= written; ptr += written; } } shutdown(pair->socket, SD_BOTH); closesocket(pair->socket); // fprintf(stderr, "TERMINATING-%d\n", pair->fd); fflush(stderr); return retval; } SocketFromFDMaker::SocketFromFDMaker(int fd, LPTHREAD_START_ROUTINE lpStartAddress, bool wait) : m_hThread(0), m_socket(INVALID_SOCKET), m_wait(wait) { // might do this twice WSAData wsaData; WSAStartup(MAKEWORD(2,0), &wsaData); int s[2], result; result = socketpair(AF_INET, SOCK_STREAM, 0, s); assert(result == 0); m_pair.fd = fd; m_pair.socket = s[0]; m_socket = s[1]; DWORD threadid; m_hThread = CreateThread( NULL, 0, lpStartAddress, &m_pair, 0, &threadid ); assert(m_hThread); } SocketFromFDMaker::~SocketFromFDMaker() { int result; // fprintf(stderr, "shutting down #%d\n", m_socket); if (m_socket != INVALID_SOCKET) { result = shutdown(m_socket, SD_BOTH); // this assertion will fail if someone has already closed the // socket; eg. if you give the socket to a WvFDStream and then let // him close it. But you shouldn't do that, because nobody is // supposed to close stdin/stdout/stderr! if (result != 0) { int e = GetLastError(); if (e == WSASYSNOTREADY || e == WSANOTINITIALISED) { fprintf(stderr, "Abnormal termination. Skipping cleanup.\n"); _exit(42); } else { fprintf(stderr, "ERROR! Socket #%d was already shut down! (%d)\n", m_socket, e); assert(result == 0); } } if (m_wait) // wait for socket->fd copier { // wait for thread to terminate. Since it's reading from a // socket (m_wait==true), this will be safe, because we know // it'll die politely when it should. WaitForSingleObject(m_hThread, INFINITE); } else { // FIXME: fd->socket copier will never die politely. It gets // stuck in _read(), which enters a critical section and // then blocks until input is available. Unfortunately, it's // impossible to make input *not* available. // // TerminateThread() is generally evil, and doesn't help here // anyway: it just leaves that critical section locked forever, so // no operation on that fd will *ever* finish. // // Answer: just do nothing. Someone will clean up the broken // thread eventually, I guess. (ExitProcess() claims to do // this, but I hope it doesn't get stuck in a critical section...) } close(m_socket); } CloseHandle(m_hThread); } wvstreams-4.6.1/win32/wvwindebuglog.cc0000644000175000001440000000030111042636572016726 0ustar wlachusers#include "wvwindebuglog.h" #include "wvlog.h" void WvWinDebugLog::_mid_line(const char *str, size_t len) { ::OutputDebugString(str); } WvWinDebugLog::~WvWinDebugLog() { end_line(); } wvstreams-4.6.1/win32/t/0000755000175000001440000000000011042636572014005 5ustar wlachuserswvstreams-4.6.1/win32/t/uniregistrygen.t.cc0000644000175000001440000000062011042636572017632 0ustar wlachusers#include "uniconfroot.h" #include "wvtest.h" WVTEST_MAIN("uniregistry") { UniConfRoot uni("registry:HKEY_CURRENT_USER"); WVPASS(!!uni.xget("/AppEvents/EventLabels/Close")); UniConf::RecursiveIter i(uni["Software/Microsoft/Windows"]); int count; for (i.rewind(), count = 0; i.next() && count < 10; count++) printf("Key '%s' = '%s'\n", i->key().cstr(), i->getme().cstr()); } wvstreams-4.6.1/win32/cominclude/0000755000175000001440000000000011042636572015664 5ustar wlachuserswvstreams-4.6.1/win32/cominclude/comdef.h0000644000175000001440000000175411042636572017301 0ustar wlachusers#ifndef __COMDEF_H #define __COMDEF_H //#warning "Using hideously broken fake comdef.h" class WvComSmartBase { public: void *p; }; // FIXME: completely untested and random template class WvComSmart : public WvComSmartBase { public: WvComSmart(IUnknown *ptr = 0, bool addref = false) { p = ptr; } WvComSmart(const WvComSmartBase &b) { p = b.p; } bool operator== (const void *b) const { return p == b; } bool operator!= (const void *b) const { return p != b; } I *operator-> () { return (I *)p; } operator I* () { return (I *)p; } I **operator& () { return (I **)&p; } }; #define _COM_SMARTPTR_TYPEDEF(x, y) typedef WvComSmart x##Ptr; // FIXME extern CLSID xblah; _COM_SMARTPTR_TYPEDEF(IUnknown, xblah); _COM_SMARTPTR_TYPEDEF(IDispatch, xblah); class _com_error { public: const char *ErrorMessage(); }; #define __uuidof(x) (xblah) #endif // _COMDEF_H wvstreams-4.6.1/win32/cominclude/comutil.h0000644000175000001440000000002411042636572017505 0ustar wlachusers#include "comdef.h" wvstreams-4.6.1/win32/streams.h0000644000175000001440000000204011042636572015365 0ustar wlachusers#ifndef __WIN32_STREAMS_H #define __WIN32_STREAMS_H #include extern "C" { int close(int fd); int read(int fd, void *buf, size_t count); int write(int fd, const void *buf, size_t count); unsigned int sleep(unsigned int seconds); // does this belong here? } #ifndef __GNUC__ // this little trick allows us to define our own close/read/write // (in streams.cc) that optionally call _close/_read/_write (defined in ) #define __STDC__ 1 // prevents io.h from dllimporting close/read/write #endif #include struct socket_fd_pair { SOCKET socket; int fd; }; class SocketFromFDMaker { protected: HANDLE m_hThread; socket_fd_pair m_pair; SOCKET m_socket; bool m_wait; public: SocketFromFDMaker(int fd, LPTHREAD_START_ROUTINE lpt, bool wait_for_termination = false); ~SocketFromFDMaker(); SOCKET GetSocket() { return m_socket; } }; DWORD WINAPI fd2socket_fwd(LPVOID lpThreadParameter); DWORD WINAPI socket2fd_fwd(LPVOID lpThreadParameter); #endif // __WIN32_STREAMS_H wvstreams-4.6.1/win32/unipstoregen.cc0000644000175000001440000001142611042636572016577 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2003 Net Integration Technologies, Inc. * * A generator that exposes Windows protected storage. */ #include "unipstoregen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" #include WV_LINK(UniPStoreGen); static const int MAX = 1024; using namespace PSTORECLib; typedef HRESULT (WINAPI *PStoreCreateInstancePtr)(IPStore **, DWORD, DWORD, DWORD); HRESULT UniPStoreGen::create_types(WvString type_name, WvString subtype_name) { HRESULT hRes; _PST_TYPEINFO myTypeInfo; myTypeInfo.cbSize = strlen(type_name.cstr()) + 1; myTypeInfo.szDisplayName = new wchar_t[myTypeInfo.cbSize]; mbstowcs(myTypeInfo.szDisplayName, type_name.cstr(), myTypeInfo.cbSize); _PST_TYPEINFO mySubTypeInfo; mySubTypeInfo.cbSize = strlen(subtype_name.cstr()) + 1; mySubTypeInfo.szDisplayName = new wchar_t[mySubTypeInfo.cbSize]; mbstowcs(mySubTypeInfo.szDisplayName, subtype_name.cstr(), mySubTypeInfo.cbSize); _PST_ACCESSRULESET myRuleSet; myRuleSet.cbSize = sizeof(myRuleSet); myRuleSet.cRules = 0; myRuleSet.rgRules = 0; hRes = m_spPStore->CreateType( m_key, &m_type, &myTypeInfo, 0); if ((hRes != PST_E_OK) && (hRes != PST_E_TYPE_EXISTS)) { m_log("CreateSubtype() returned: %s\n", hRes); goto done; } hRes = m_spPStore->CreateSubtype( m_key, &m_type, &m_subtype, &mySubTypeInfo, &myRuleSet, 0); if ((hRes != PST_E_OK) && (hRes != PST_E_TYPE_EXISTS)) { m_log("CreateSubtype() returned: %s\n", hRes); goto done; } done: delete[] myTypeInfo.szDisplayName; delete[] mySubTypeInfo.szDisplayName; return hRes; } // moniker is // PST_KEY_CURRENT_USER:TYPENAME:TYPEGUID:SUBTYPE:SUBTYPEGUID UniPStoreGen::UniPStoreGen(WvString _moniker) : m_log(_moniker), m_key(-1) { // load the library and get an entry point function pointer m_hPstoreDLL = LoadLibrary("pstorec.dll"); assert(m_hPstoreDLL); PStoreCreateInstancePtr pPStoreCreateInstance = (PStoreCreateInstancePtr) GetProcAddress(m_hPstoreDLL, "PStoreCreateInstance"); assert(pPStoreCreateInstance); HRESULT hr = pPStoreCreateInstance(&m_spPStore, 0, 0, 0); assert(SUCCEEDED(hr)); // parse the moniker char *moniker = _moniker.edit(); const char *seps = ":"; WvString _key = strtok(moniker, seps); WvString type_name = strtok(NULL, seps); WvString _type_guid = strtok(NULL, seps); WvString subtype_name = strtok(NULL, seps); WvString _subtype_guid = strtok(NULL, seps); if (!!_key && strcmp(_key, "PST_KEY_CURRENT_USER") == 0) { m_key = PST_KEY_CURRENT_USER; } else if (!!_key && strcmp(_key, "PST_KEY_LOCAL_MACHINE") == 0) { m_key = PST_KEY_LOCAL_MACHINE; } if ((m_key >= 0) && !!type_name && !!_type_guid && !!subtype_name && !!_subtype_guid) { HRESULT hr; hr = UuidFromString((unsigned char*)_type_guid.edit(), &m_type); hr = UuidFromString((unsigned char*)_subtype_guid.edit(), &m_subtype); int result = create_types(type_name, subtype_name); assert(SUCCEEDED( result ) || (result == PST_E_TYPE_EXISTS)); } } UniPStoreGen::~UniPStoreGen() { m_spPStore = 0; if (m_hPstoreDLL) { FreeLibrary(m_hPstoreDLL); m_hPstoreDLL = 0; } } bool UniPStoreGen::isok() { return m_key >= 0; } WvString UniPStoreGen::get(const UniConfKey &key) { HRESULT hRes; WvString value = WvString::null; unsigned char *data; unsigned long cbdata; WvString _name = key.last().printable(); WCHAR name[MAX]; mbstowcs(name, _name.cstr(), MAX); hRes = m_spPStore->ReadItem( m_key, &m_type, &m_subtype, name, &cbdata, &data, NULL, 0 ); if (hRes == PST_E_OK) { value.setsize(MAX); wcstombs(value.edit(), (wchar_t*)data, MAX); CoTaskMemFree(data); } return value; } void UniPStoreGen::set(const UniConfKey &key, WvStringParm value) { WCHAR name[MAX], data[MAX]; mbstowcs(name, key.last().printable().cstr(), MAX); mbstowcs(data, value.cstr(), MAX); DWORD cbdata = DWORD((wcslen(data) + 1) * sizeof(WCHAR)); HRESULT hRes = m_spPStore->WriteItem( m_key, &m_type, &m_subtype, name, cbdata, (unsigned char *)data, NULL, PST_CF_NONE, 0 ); if (hRes == PST_E_OK) { delta(key, value); } } void UniPStoreGen::setv(const UniConfPairList &pairs) { setv_naive(pairs); } bool UniPStoreGen::exists(const UniConfKey &key) { return false; } bool UniPStoreGen::haschildren(const UniConfKey &key) { return false; } UniConfGen::Iter *UniPStoreGen::iterator(const UniConfKey &key) { return new NullIter(); } static IUniConfGen *creator(WvStringParm s, IObject*) { return new UniPStoreGen(s); } #pragma warning(disable : 4073) #pragma init_seg(lib) WvMoniker UniPStoreGenMoniker("pstore", creator); wvstreams-4.6.1/win32/sys/0000755000175000001440000000000011042636572014360 5ustar wlachuserswvstreams-4.6.1/win32/sys/socket.h0000644000175000001440000000000011042636572016007 0ustar wlachuserswvstreams-4.6.1/win32/winstreams.cc0000644000175000001440000000056111042636572016247 0ustar wlachusers// winstreams.cpp : Defines the entry point for the DLL application. // #include "winsock2.h" #include "assert.h" class RunWinSockInitialize { WSAData wsaData; public: RunWinSockInitialize() { int result = WSAStartup(MAKEWORD(2,0), &wsaData); assert(result == 0); } }; RunWinSockInitialize __runinitialize; void *_wvinitialize = &__runinitialize; wvstreams-4.6.1/win32/pstorec.tlh0000644000175000001440000002173711042636572015744 0ustar wlachusers// Created by Microsoft (R) C/C++ Compiler Version 13.00.9466 (b086ed06). // // e:\dev\niti\src\exchangeit\outlook\debug\pstorec.tlh // // C++ source equivalent of Win32 type library c:\windows\system32\pstorec.dll // compiler-generated file created 06/13/03 at 16:47:23 - DO NOT EDIT! #pragma once #pragma pack(push, 8) #include namespace PSTORECLib { // // Forward references and typedefs // struct __declspec(uuid("5a6f1ebd-2db1-11d0-8c39-00c04fd9126b")) /* LIBID */ __PSTORECLib; struct /* coclass */ CPStore; struct __declspec(uuid("5a6f1ebf-2db1-11d0-8c39-00c04fd9126b")) /* interface */ IEnumPStoreProviders; struct _PST_PROVIDERINFO; struct __declspec(uuid("5a6f1ec0-2db1-11d0-8c39-00c04fd9126b")) /* interface */ IPStore; struct _PST_TYPEINFO; struct _PST_ACCESSRULESET; struct _PST_ACCESSRULE; struct _PST_ACCESSCLAUSE; struct __declspec(uuid("789c1cbf-31ee-11d0-8c39-00c04fd9126b")) /* interface */ IEnumPStoreTypes; struct _PST_PROMPTINFO; struct __declspec(uuid("5a6f1ec1-2db1-11d0-8c39-00c04fd9126b")) /* interface */ IEnumPStoreItems; struct /* coclass */ CEnumTypes; struct /* coclass */ CEnumItems; // // Smart pointer typedef declarations // _COM_SMARTPTR_TYPEDEF(IEnumPStoreProviders, __uuidof(IEnumPStoreProviders)); _COM_SMARTPTR_TYPEDEF(IEnumPStoreTypes, __uuidof(IEnumPStoreTypes)); _COM_SMARTPTR_TYPEDEF(IEnumPStoreItems, __uuidof(IEnumPStoreItems)); _COM_SMARTPTR_TYPEDEF(IPStore, __uuidof(IPStore)); // // Type library items // struct __declspec(uuid("5a6f1ec3-2db1-11d0-8c39-00c04fd9126b")) CPStore; // [ default ] interface IEnumPStoreProviders // interface IPStore struct _PST_PROVIDERINFO { unsigned long cbSize; GUID ID; unsigned long Capabilities; LPWSTR szProviderName; }; struct __declspec(uuid("5a6f1ebf-2db1-11d0-8c39-00c04fd9126b")) IEnumPStoreProviders : IUnknown { // // Raw methods provided by interface // virtual HRESULT __stdcall Next ( /*[in]*/ unsigned long celt, /*[out]*/ struct _PST_PROVIDERINFO * * rgelt, /*[in,out]*/ unsigned long * pceltFetched ) = 0; virtual HRESULT __stdcall Skip ( /*[in]*/ unsigned long celt ) = 0; virtual HRESULT __stdcall Reset ( ) = 0; virtual HRESULT __stdcall Clone ( /*[out]*/ struct IEnumPStoreProviders * * ppenum ) = 0; }; struct _PST_TYPEINFO { unsigned long cbSize; LPWSTR szDisplayName; }; struct _PST_ACCESSCLAUSE { unsigned long cbSize; unsigned long ClauseType; unsigned long cbClauseData; unsigned char * pbClauseData; }; struct _PST_ACCESSRULE { unsigned long cbSize; unsigned long AccessModeFlags; unsigned long cClauses; struct _PST_ACCESSCLAUSE * rgClauses; }; struct _PST_ACCESSRULESET { unsigned long cbSize; unsigned long cRules; struct _PST_ACCESSRULE * rgRules; }; struct __declspec(uuid("789c1cbf-31ee-11d0-8c39-00c04fd9126b")) IEnumPStoreTypes : IUnknown { // // Raw methods provided by interface // virtual HRESULT __stdcall Next ( /*[in]*/ unsigned long celt, /*[out]*/ GUID * rgelt, /*[in,out]*/ unsigned long * pceltFetched ) = 0; virtual HRESULT __stdcall Skip ( /*[in]*/ unsigned long celt ) = 0; virtual HRESULT __stdcall Reset ( ) = 0; virtual HRESULT __stdcall Clone ( /*[out]*/ struct IEnumPStoreTypes * * ppenum ) = 0; }; struct _PST_PROMPTINFO { unsigned long cbSize; unsigned long dwPromptFlags; unsigned long hwndApp; LPWSTR szPrompt; }; struct __declspec(uuid("5a6f1ec1-2db1-11d0-8c39-00c04fd9126b")) IEnumPStoreItems : IUnknown { // // Raw methods provided by interface // virtual HRESULT __stdcall Next ( /*[in]*/ unsigned long celt, /*[out]*/ LPWSTR * rgelt, /*[in,out]*/ unsigned long * pceltFetched ) = 0; virtual HRESULT __stdcall Skip ( /*[in]*/ unsigned long celt ) = 0; virtual HRESULT __stdcall Reset ( ) = 0; virtual HRESULT __stdcall Clone ( /*[out]*/ struct IEnumPStoreItems * * ppenum ) = 0; }; struct __declspec(uuid("5a6f1ec0-2db1-11d0-8c39-00c04fd9126b")) IPStore : IUnknown { // // Raw methods provided by interface // virtual HRESULT __stdcall GetInfo ( /*[out]*/ struct _PST_PROVIDERINFO * * ppProperties ) = 0; virtual HRESULT __stdcall GetProvParam ( /*[in]*/ unsigned long dwParam, /*[out]*/ unsigned long * pcbData, /*[out]*/ unsigned char * * ppbData, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall SetProvParam ( /*[in]*/ unsigned long dwParam, /*[in]*/ unsigned long cbData, /*[in]*/ unsigned char * pbData, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall CreateType ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ struct _PST_TYPEINFO * pInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall GetTypeInfo ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[out]*/ struct _PST_TYPEINFO * * ppInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall DeleteType ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall CreateSubtype ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ GUID * pSubtype, /*[in]*/ struct _PST_TYPEINFO * pInfo, /*[in]*/ struct _PST_ACCESSRULESET * pRules, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall GetSubtypeInfo ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ GUID * pSubtype, /*[out]*/ struct _PST_TYPEINFO * * ppInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall DeleteSubtype ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ GUID * pSubtype, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall ReadAccessRuleset ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ GUID * pSubtype, /*[out]*/ struct _PST_ACCESSRULESET * * ppRules, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall WriteAccessRuleset ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ GUID * pSubtype, /*[in]*/ struct _PST_ACCESSRULESET * pRules, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall EnumTypes ( /*[in]*/ unsigned long Key, /*[in]*/ unsigned long dwFlags, /*[in]*/ struct IEnumPStoreTypes * * ppenum ) = 0; virtual HRESULT __stdcall EnumSubtypes ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pType, /*[in]*/ unsigned long dwFlags, /*[in]*/ struct IEnumPStoreTypes * * ppenum ) = 0; virtual HRESULT __stdcall DeleteItem ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ LPWSTR szItemName, /*[in]*/ struct _PST_PROMPTINFO * pPromptInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall ReadItem ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ LPWSTR szItemName, /*[out]*/ unsigned long * pcbData, /*[out]*/ unsigned char * * ppbData, /*[in]*/ struct _PST_PROMPTINFO * pPromptInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall WriteItem ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ LPWSTR szItemName, /*[in]*/ unsigned long cbData, /*[in]*/ unsigned char * pbData, /*[in]*/ struct _PST_PROMPTINFO * pPromptInfo, /*[in]*/ unsigned long dwDefaultConfirmationStyle, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall OpenItem ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ LPWSTR szItemName, /*[in]*/ unsigned long ModeFlags, /*[in]*/ struct _PST_PROMPTINFO * pPromptInfo, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall CloseItem ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ LPWSTR szItemName, /*[in]*/ unsigned long dwFlags ) = 0; virtual HRESULT __stdcall EnumItems ( /*[in]*/ unsigned long Key, /*[in]*/ GUID * pItemType, /*[in]*/ GUID * pItemSubtype, /*[in]*/ unsigned long dwFlags, /*[in]*/ struct IEnumPStoreItems * * ppenum ) = 0; }; struct __declspec(uuid("09bb61e7-31ec-11d0-8c39-00c04fd9126b")) CEnumTypes; // [ default ] interface IEnumPStoreTypes struct __declspec(uuid("09bb61e6-31ec-11d0-8c39-00c04fd9126b")) CEnumItems; // [ default ] interface IEnumPStoreItems } // namespace PSTORECLib #pragma pack(pop) wvstreams-4.6.1/win32/utils.cc0000644000175000001440000000247411042636572015220 0ustar wlachusers// utils.cpp : Defines the entry point for the DLL application. // #include "wvwin32-sanitize.h" #define EPOCHFILETIME (116444736000000000LL) int gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ft; LARGE_INTEGER li; __int64 t; static int tzflag; if (tv) { GetSystemTimeAsFileTime(&ft); li.LowPart = ft.dwLowDateTime; li.HighPart = ft.dwHighDateTime; t = li.QuadPart; /* In 100-nanosecond intervals */ t -= EPOCHFILETIME; /* Offset to the Epoch time */ t /= 10; /* In microseconds */ tv->tv_sec = (long)(t / 1000000); tv->tv_usec = (long)(t % 1000000); } #if 0 if (tz) { if (!tzflag) { _tzset(); tzflag++; } tz->tz_minuteswest = _timezone / 60; tz->tz_dsttime = _daylight; } #endif return 0; } pid_t getpid() { return GetCurrentThreadId(); } unsigned int sleep(unsigned int secs) { Sleep(secs*1000); return 0; } // FIXME: this makes alarms silently fail. They should probably fail more // nicely, or (better still) actually work... unsigned int alarm(unsigned int t) { return 0; } // This is the same as what Python uses, apparently int fsync(int fd) { return _commit(fd); } wvstreams-4.6.1/win32/wvwin32task.cc0000644000175000001440000001000711042636572016251 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * */ #define WIN32_LEAN_AND_MEAN //#define NOMINMAX #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif #include #include #include "wvwin32task.h" #include #include #include #include // for alloca() #include // for alloca() on non-Linux platforms? int WvTask::taskcount, WvTask::numtasks, WvTask::numrunning; WvTaskMan *WvTaskMan::singleton = NULL; int WvTaskMan::links = 1; // never delete singleton int WvTaskMan::magic_number; WvTaskList WvTaskMan::free_tasks; WvTask *WvTaskMan::stack_target; WvTask *WvTaskMan::current_task; LPVOID WvTaskMan::toplevel; WvTask::WvTask(WvTaskMan &_man, size_t _stacksize) : man(_man) { stacksize = _stacksize; running = recycled = false; func = NULL; userdata = NULL; tid = ++taskcount; numtasks++; magic_number = WVTASK_MAGIC; stack_magic = NULL; mystate = CreateFiber(_stacksize, &MyFiberProc, this); assert(mystate); } WvTask::~WvTask() { numtasks--; if (running) numrunning--; magic_number = 42; } VOID CALLBACK WvTask::MyFiberProc(PVOID lpParameter) { WvTask *_this = (WvTask *) lpParameter; while (true) { if (_this->func && _this->running) { _this->func(_this->userdata); // the task's function terminated. _this->name = "DEAD"; _this->running = false; _this->numrunning--; } _this->man.yield(); } } void WvTask::start(WvStringParm _name, TaskFunc *_func, void *_userdata) { assert(!recycled); name = _name; func = _func; userdata = _userdata; running = true; numrunning++; } void WvTask::recycle() { assert(!running); if (!running && !recycled) { man.free_tasks.append(this, true); recycled = true; } } WvTaskMan *WvTaskMan::get() { if (!singleton) singleton = new WvTaskMan; links++; return singleton; } void WvTaskMan::unlink() { links--; if (links == 0) { delete singleton; singleton = NULL; } } WvTaskMan::WvTaskMan() { stack_target = NULL; current_task = NULL; magic_number = -WVTASK_MAGIC; toplevel = ::ConvertThreadToFiber(0); assert(toplevel); } WvTaskMan::~WvTaskMan() { magic_number = -42; } WvTask *WvTaskMan::start(WvStringParm name, WvTask::TaskFunc *func, void *userdata, size_t stacksize) { WvTask *t; WvTaskList::Iter i(free_tasks); for (i.rewind(); i.next(); ) { if (i().stacksize >= stacksize) { t = &i(); i.link->set_autofree(false); i.unlink(); t->recycled = false; t->start(name, func, userdata); return t; } } // if we get here, no matching task was found. t = new WvTask(*this, stacksize); t->start(name, func, userdata); return t; } int WvTaskMan::run(WvTask &task, int val) { assert(magic_number == -WVTASK_MAGIC); assert(task.magic_number == WVTASK_MAGIC); assert(!task.recycled); if (&task == current_task) return val; // that's easy! WvTask *old_task = current_task; current_task = &task; LPVOID *state; if (!old_task) state = &toplevel; // top-level call (not in an actual task yet) else state = &old_task->mystate; //fprintf(stderr, "taskman: switching from %p to %p\n", old_task, &task); ::SwitchToFiber(task.mystate); //fprintf(stderr, "taskman: back in %p\n", old_task); // someone did yield() (if toplevel) or run() on our task; exit current_task = old_task; int newval = 0; return newval; } int WvTaskMan::yield(int val) { if (!current_task) return 0; // weird... WvTask *task = current_task; //fprintf(stderr, "taskman: yielding from %p to toplevel\n", task); current_task = 0; // toplevel ::SwitchToFiber(toplevel); //fprintf(stderr, "taskman: return from yield in %p (%p)\n", current_task, task); assert(current_task == task); int newval = 0; return newval; } wvstreams-4.6.1/win32/uniregistrygen.cc0000644000175000001440000001563011077124114017124 0ustar wlachusers/* * Worldvisions Weaver Software: * Copyright (C) 1997-2004 Net Integration Technologies, Inc. * * A generator that exposes the windows registry. */ #include "uniregistrygen.h" #include "wvmoniker.h" #include "wvlinkerhack.h" WV_LINK(UniRegistryGen); // returns a handle to the key specified by key, or, if key specifies a value, // a handle to the key containing that value (and setting isValue = true) static HKEY follow_path(HKEY from, const UniConfKey &key, bool create, bool *isValue) { const REGSAM samDesired = KEY_READ | KEY_WRITE; LONG result; HKEY hLastKey = from; // DuplicateHandle() does not work with regkeys int n = key.numsegments(); if (isValue) *isValue = false; for (int i=0;i 0) { RegCloseKey(hLastKey); } hLastKey = hNextKey; } return hLastKey; } UniRegistryGen::UniRegistryGen(WvString _moniker) : m_log(_moniker), m_hRoot(0) { UniConfKey key = _moniker; WvString hive = key.first().printable(); if (strcmp("HKEY_CLASSES_ROOT", hive) == 0) { m_hRoot = HKEY_CLASSES_ROOT; } else if (strcmp("HKEY_CURRENT_USER", hive) == 0) { m_hRoot = HKEY_CURRENT_USER; } else if (strcmp("HKEY_LOCAL_MACHINE", hive) == 0) { m_hRoot = HKEY_LOCAL_MACHINE; } else if (strcmp("HKEY_USERS", hive) == 0) { m_hRoot = HKEY_USERS; } m_hRoot = follow_path(m_hRoot, key.range(1, key.numsegments()), true, NULL); #if 0 // FIXME: Notifications don't work for external registry changes. // hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); RegNotifyChangeKeyValue( m_hRoot, TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY, hEvent, TRUE ); #endif } UniRegistryGen::~UniRegistryGen() { if (m_hRoot) { RegCloseKey(m_hRoot); m_hRoot = 0; } } bool UniRegistryGen::isok() { return m_hRoot != 0; } WvString UniRegistryGen::get(const UniConfKey &key) { WvString retval = WvString::null; bool isvalue; HKEY hKey = follow_path(m_hRoot, key, false, &isvalue); WvString value; if (isvalue) { // the path ends up at a value so fetch that value = key.last(); if (value == ".") value = WvString::null; } else { // the key isn't a value, fetch its default value instead value = WvString::null; } DWORD type; TCHAR data[1024]; DWORD size = sizeof(data) / sizeof(data[0]); LONG result = RegQueryValueEx( hKey, value.cstr(), 0, &type, (BYTE *) data, &size ); if (result == ERROR_SUCCESS) { switch (type) { case REG_DWORD: retval.setsize(11); itoa(*((int *) data), retval.edit(), 10); break; case REG_SZ: retval = data; break; default: break; }; } if (hKey != m_hRoot) RegCloseKey(hKey); return retval; } void UniRegistryGen::set(const UniConfKey &key, WvStringParm value) { LONG result; HKEY hKey = follow_path(m_hRoot, key.first( key.numsegments()-1 ), true, NULL); if (hKey) { if (value.isnull()) { result = RegDeleteValue(hKey, key.last().printable()); } else { WvString last = key.last(); if (last == ".") last = WvString::null; result = RegSetValueEx( hKey, last, 0, REG_SZ, (BYTE *) value.cstr(), strlen(value)+1 ); } if (result == ERROR_SUCCESS) { delta(key, value); } } if (hKey != m_hRoot) RegCloseKey(hKey); } void UniRegistryGen::setv(const UniConfPairList &pairs) { setv_naive(pairs); } bool UniRegistryGen::exists(const UniConfKey &key) { return !get(key).isnull(); } bool UniRegistryGen::haschildren(const UniConfKey &key) { UniRegistryGenIter iter(*this, key, m_hRoot); iter.rewind(); return iter.next(); } UniConfGen::Iter *UniRegistryGen::iterator(const UniConfKey &key) { return new UniRegistryGenIter(*this, key, m_hRoot); } UniRegistryGenIter::UniRegistryGenIter(UniRegistryGen &gen, const UniConfKey &key, HKEY base) : m_hKey(0), m_enumerating(KEYS), m_index(0), gen(gen), parent(key), m_dontClose(base) { bool isValue; HKEY hKey = follow_path(base, key, false, &isValue); // fprintf(stderr, "(iter:%s:%d:%p)\n", // key.printable().cstr(), isValue, hKey); fflush(stderr); if (isValue) { // a value doesn't have subkeys if (hKey != m_dontClose) RegCloseKey(hKey); m_enumerating = VALUES; } else m_hKey = hKey; } UniRegistryGenIter::~UniRegistryGenIter() { if (m_hKey && m_hKey != m_dontClose) RegCloseKey(m_hKey); } void UniRegistryGenIter::rewind() { current_key = "YOU HAVE TO REWIND, DUMMY!"; m_enumerating = KEYS; m_index = 0; } bool UniRegistryGenIter::next() { if (m_enumerating == KEYS) { LONG result = next_key(); if (result == ERROR_SUCCESS) return true; else if (result == ERROR_NO_MORE_ITEMS) { // done enumerating keys, now enumerate the values m_enumerating = VALUES; m_index = 0; } else { fprintf(stderr, "KEY_ENUM result: %ld\n", result); fflush(stderr); return false; // give up } } assert(m_enumerating == VALUES); LONG result = next_value(); if (result == ERROR_SUCCESS) return true; return false; } UniConfKey UniRegistryGenIter::key() const { return current_key; } WvString UniRegistryGenIter::value() const { UniConfKey val(parent, current_key); return gen.get(val); } LONG UniRegistryGenIter::next_key() { if (!m_hKey) return ERROR_NO_MORE_ITEMS; FILETIME dontcare; TCHAR data[1024]; DWORD size = sizeof(data) / sizeof(data[0]); LONG result = RegEnumKeyEx(m_hKey, m_index++, data, &size, 0, 0, 0, &dontcare); if (result == ERROR_SUCCESS) current_key = data; return result; } LONG UniRegistryGenIter::next_value() { if (!m_hKey) return ERROR_NO_MORE_ITEMS; TCHAR data[1024] = ""; DWORD size = sizeof(data) / sizeof(data[0]); while (!*data) { LONG result = RegEnumValue(m_hKey, m_index++, data, &size, 0, 0, 0, 0); if (result != ERROR_SUCCESS) return result; } current_key = data; return ERROR_SUCCESS; } static IUniConfGen *creator(WvStringParm s, IObject*) { return new UniRegistryGen(s); } #pragma warning(disable : 4073) #pragma init_seg(lib) WvMoniker UniRegistryGenMoniker("registry", creator);