gvpe-3.0/0000755000000000000000000000000013011103357007256 500000000000000gvpe-3.0/libev/0000755000000000000000000000000013011103357010357 500000000000000gvpe-3.0/libev/ev.c0000644000000000000000000037471012661246375011113 00000000000000/* * libev event processing core, watcher management * * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ /* this big block deduces configuration from config.h */ #ifndef EV_STANDALONE # ifdef EV_CONFIG_H # include EV_CONFIG_H # else # include "config.h" # endif # if HAVE_FLOOR # ifndef EV_USE_FLOOR # define EV_USE_FLOOR 1 # endif # endif # if HAVE_CLOCK_SYSCALL # ifndef EV_USE_CLOCK_SYSCALL # define EV_USE_CLOCK_SYSCALL 1 # ifndef EV_USE_REALTIME # define EV_USE_REALTIME 0 # endif # ifndef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 1 # endif # endif # elif !defined EV_USE_CLOCK_SYSCALL # define EV_USE_CLOCK_SYSCALL 0 # endif # if HAVE_CLOCK_GETTIME # ifndef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 1 # endif # ifndef EV_USE_REALTIME # define EV_USE_REALTIME 0 # endif # else # ifndef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 0 # endif # ifndef EV_USE_REALTIME # define EV_USE_REALTIME 0 # endif # endif # if HAVE_NANOSLEEP # ifndef EV_USE_NANOSLEEP # define EV_USE_NANOSLEEP EV_FEATURE_OS # endif # else # undef EV_USE_NANOSLEEP # define EV_USE_NANOSLEEP 0 # endif # if HAVE_SELECT && HAVE_SYS_SELECT_H # ifndef EV_USE_SELECT # define EV_USE_SELECT EV_FEATURE_BACKENDS # endif # else # undef EV_USE_SELECT # define EV_USE_SELECT 0 # endif # if HAVE_POLL && HAVE_POLL_H # ifndef EV_USE_POLL # define EV_USE_POLL EV_FEATURE_BACKENDS # endif # else # undef EV_USE_POLL # define EV_USE_POLL 0 # endif # if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H # ifndef EV_USE_EPOLL # define EV_USE_EPOLL EV_FEATURE_BACKENDS # endif # else # undef EV_USE_EPOLL # define EV_USE_EPOLL 0 # endif # if HAVE_KQUEUE && HAVE_SYS_EVENT_H # ifndef EV_USE_KQUEUE # define EV_USE_KQUEUE EV_FEATURE_BACKENDS # endif # else # undef EV_USE_KQUEUE # define EV_USE_KQUEUE 0 # endif # if HAVE_PORT_H && HAVE_PORT_CREATE # ifndef EV_USE_PORT # define EV_USE_PORT EV_FEATURE_BACKENDS # endif # else # undef EV_USE_PORT # define EV_USE_PORT 0 # endif # if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H # ifndef EV_USE_INOTIFY # define EV_USE_INOTIFY EV_FEATURE_OS # endif # else # undef EV_USE_INOTIFY # define EV_USE_INOTIFY 0 # endif # if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H # ifndef EV_USE_SIGNALFD # define EV_USE_SIGNALFD EV_FEATURE_OS # endif # else # undef EV_USE_SIGNALFD # define EV_USE_SIGNALFD 0 # endif # if HAVE_EVENTFD # ifndef EV_USE_EVENTFD # define EV_USE_EVENTFD EV_FEATURE_OS # endif # else # undef EV_USE_EVENTFD # define EV_USE_EVENTFD 0 # endif #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef EV_H # include EV_H #else # include "ev.h" #endif #if EV_NO_THREADS # undef EV_NO_SMP # define EV_NO_SMP 1 # undef ECB_NO_THREADS # define ECB_NO_THREADS 1 #endif #if EV_NO_SMP # undef EV_NO_SMP # define ECB_NO_SMP 1 #endif #ifndef _WIN32 # include # include # include #else # include # define WIN32_LEAN_AND_MEAN # include # include # ifndef EV_SELECT_IS_WINSOCKET # define EV_SELECT_IS_WINSOCKET 1 # endif # undef EV_AVOID_STDIO #endif /* OS X, in its infinite idiocy, actually HARDCODES * a limit of 1024 into their select. Where people have brains, * OS X engineers apparently have a vacuum. Or maybe they were * ordered to have a vacuum, or they do anything for money. * This might help. Or not. */ #define _DARWIN_UNLIMITED_SELECT 1 /* this block tries to deduce configuration from header-defined symbols and defaults */ /* try to deduce the maximum number of signals on this platform */ #if defined EV_NSIG /* use what's provided */ #elif defined NSIG # define EV_NSIG (NSIG) #elif defined _NSIG # define EV_NSIG (_NSIG) #elif defined SIGMAX # define EV_NSIG (SIGMAX+1) #elif defined SIG_MAX # define EV_NSIG (SIG_MAX+1) #elif defined _SIG_MAX # define EV_NSIG (_SIG_MAX+1) #elif defined MAXSIG # define EV_NSIG (MAXSIG+1) #elif defined MAX_SIG # define EV_NSIG (MAX_SIG+1) #elif defined SIGARRAYSIZE # define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */ #elif defined _sys_nsig # define EV_NSIG (_sys_nsig) /* Solaris 2.5 */ #else # define EV_NSIG (8 * sizeof (sigset_t) + 1) #endif #ifndef EV_USE_FLOOR # define EV_USE_FLOOR 0 #endif #ifndef EV_USE_CLOCK_SYSCALL # if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17 # define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS # else # define EV_USE_CLOCK_SYSCALL 0 # endif #endif #if !(_POSIX_TIMERS > 0) # ifndef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 0 # endif # ifndef EV_USE_REALTIME # define EV_USE_REALTIME 0 # endif #endif #ifndef EV_USE_MONOTONIC # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 # define EV_USE_MONOTONIC EV_FEATURE_OS # else # define EV_USE_MONOTONIC 0 # endif #endif #ifndef EV_USE_REALTIME # define EV_USE_REALTIME !EV_USE_CLOCK_SYSCALL #endif #ifndef EV_USE_NANOSLEEP # if _POSIX_C_SOURCE >= 199309L # define EV_USE_NANOSLEEP EV_FEATURE_OS # else # define EV_USE_NANOSLEEP 0 # endif #endif #ifndef EV_USE_SELECT # define EV_USE_SELECT EV_FEATURE_BACKENDS #endif #ifndef EV_USE_POLL # ifdef _WIN32 # define EV_USE_POLL 0 # else # define EV_USE_POLL EV_FEATURE_BACKENDS # endif #endif #ifndef EV_USE_EPOLL # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) # define EV_USE_EPOLL EV_FEATURE_BACKENDS # else # define EV_USE_EPOLL 0 # endif #endif #ifndef EV_USE_KQUEUE # define EV_USE_KQUEUE 0 #endif #ifndef EV_USE_PORT # define EV_USE_PORT 0 #endif #ifndef EV_USE_INOTIFY # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) # define EV_USE_INOTIFY EV_FEATURE_OS # else # define EV_USE_INOTIFY 0 # endif #endif #ifndef EV_PID_HASHSIZE # define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1 #endif #ifndef EV_INOTIFY_HASHSIZE # define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1 #endif #ifndef EV_USE_EVENTFD # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) # define EV_USE_EVENTFD EV_FEATURE_OS # else # define EV_USE_EVENTFD 0 # endif #endif #ifndef EV_USE_SIGNALFD # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) # define EV_USE_SIGNALFD EV_FEATURE_OS # else # define EV_USE_SIGNALFD 0 # endif #endif #if 0 /* debugging */ # define EV_VERIFY 3 # define EV_USE_4HEAP 1 # define EV_HEAP_CACHE_AT 1 #endif #ifndef EV_VERIFY # define EV_VERIFY (EV_FEATURE_API ? 1 : 0) #endif #ifndef EV_USE_4HEAP # define EV_USE_4HEAP EV_FEATURE_DATA #endif #ifndef EV_HEAP_CACHE_AT # define EV_HEAP_CACHE_AT EV_FEATURE_DATA #endif #ifdef ANDROID /* supposedly, android doesn't typedef fd_mask */ # undef EV_USE_SELECT # define EV_USE_SELECT 0 /* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */ # undef EV_USE_CLOCK_SYSCALL # define EV_USE_CLOCK_SYSCALL 0 #endif /* aix's poll.h seems to cause lots of trouble */ #ifdef _AIX /* AIX has a completely broken poll.h header */ # undef EV_USE_POLL # define EV_USE_POLL 0 #endif /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ /* which makes programs even slower. might work on other unices, too. */ #if EV_USE_CLOCK_SYSCALL # include # ifdef SYS_clock_gettime # define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) # undef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 1 # else # undef EV_USE_CLOCK_SYSCALL # define EV_USE_CLOCK_SYSCALL 0 # endif #endif /* this block fixes any misconfiguration where we know we run into trouble otherwise */ #ifndef CLOCK_MONOTONIC # undef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 0 #endif #ifndef CLOCK_REALTIME # undef EV_USE_REALTIME # define EV_USE_REALTIME 0 #endif #if !EV_STAT_ENABLE # undef EV_USE_INOTIFY # define EV_USE_INOTIFY 0 #endif #if !EV_USE_NANOSLEEP /* hp-ux has it in sys/time.h, which we unconditionally include above */ # if !defined _WIN32 && !defined __hpux # include # endif #endif #if EV_USE_INOTIFY # include # include /* some very old inotify.h headers don't have IN_DONT_FOLLOW */ # ifndef IN_DONT_FOLLOW # undef EV_USE_INOTIFY # define EV_USE_INOTIFY 0 # endif #endif #if EV_USE_EVENTFD /* our minimum requirement is glibc 2.7 which has the stub, but not the header */ # include # ifndef EFD_NONBLOCK # define EFD_NONBLOCK O_NONBLOCK # endif # ifndef EFD_CLOEXEC # ifdef O_CLOEXEC # define EFD_CLOEXEC O_CLOEXEC # else # define EFD_CLOEXEC 02000000 # endif # endif EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags); #endif #if EV_USE_SIGNALFD /* our minimum requirement is glibc 2.7 which has the stub, but not the header */ # include # ifndef SFD_NONBLOCK # define SFD_NONBLOCK O_NONBLOCK # endif # ifndef SFD_CLOEXEC # ifdef O_CLOEXEC # define SFD_CLOEXEC O_CLOEXEC # else # define SFD_CLOEXEC 02000000 # endif # endif EV_CPP (extern "C") int signalfd (int fd, const sigset_t *mask, int flags); struct signalfd_siginfo { uint32_t ssi_signo; char pad[128 - sizeof (uint32_t)]; }; #endif /**/ #if EV_VERIFY >= 3 # define EV_FREQUENT_CHECK ev_verify (EV_A) #else # define EV_FREQUENT_CHECK do { } while (0) #endif /* * This is used to work around floating point rounding problems. * This value is good at least till the year 4000. */ #define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */ /*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ #define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0) #define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ /* ECB.H BEGIN */ /* * libecb - http://software.schmorp.de/pkg/libecb * * Copyright (©) 2009-2015 Marc Alexander Lehmann * Copyright (©) 2011 Emanuele Giaquinta * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef ECB_H #define ECB_H /* 16 bits major, 16 bits minor */ #define ECB_VERSION 0x00010005 #ifdef _WIN32 typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; #if __GNUC__ typedef signed long long int64_t; typedef unsigned long long uint64_t; #else /* _MSC_VER || __BORLANDC__ */ typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; #endif #ifdef _WIN64 #define ECB_PTRSIZE 8 typedef uint64_t uintptr_t; typedef int64_t intptr_t; #else #define ECB_PTRSIZE 4 typedef uint32_t uintptr_t; typedef int32_t intptr_t; #endif #else #include #if (defined INTPTR_MAX ? INTPTR_MAX : ULONG_MAX) > 0xffffffffU #define ECB_PTRSIZE 8 #else #define ECB_PTRSIZE 4 #endif #endif #define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__) #define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64) /* work around x32 idiocy by defining proper macros */ #if ECB_GCC_AMD64 || ECB_MSVC_AMD64 #if _ILP32 #define ECB_AMD64_X32 1 #else #define ECB_AMD64 1 #endif #endif /* many compilers define _GNUC_ to some versions but then only implement * what their idiot authors think are the "more important" extensions, * causing enormous grief in return for some better fake benchmark numbers. * or so. * we try to detect these and simply assume they are not gcc - if they have * an issue with that they should have done it right in the first place. */ #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__ #define ECB_GCC_VERSION(major,minor) 0 #else #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) #endif #define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor))) #if __clang__ && defined __has_builtin #define ECB_CLANG_BUILTIN(x) __has_builtin (x) #else #define ECB_CLANG_BUILTIN(x) 0 #endif #if __clang__ && defined __has_extension #define ECB_CLANG_EXTENSION(x) __has_extension (x) #else #define ECB_CLANG_EXTENSION(x) 0 #endif #define ECB_CPP (__cplusplus+0) #define ECB_CPP11 (__cplusplus >= 201103L) #if ECB_CPP #define ECB_C 0 #define ECB_STDC_VERSION 0 #else #define ECB_C 1 #define ECB_STDC_VERSION __STDC_VERSION__ #endif #define ECB_C99 (ECB_STDC_VERSION >= 199901L) #define ECB_C11 (ECB_STDC_VERSION >= 201112L) #if ECB_CPP #define ECB_EXTERN_C extern "C" #define ECB_EXTERN_C_BEG ECB_EXTERN_C { #define ECB_EXTERN_C_END } #else #define ECB_EXTERN_C extern #define ECB_EXTERN_C_BEG #define ECB_EXTERN_C_END #endif /*****************************************************************************/ /* ECB_NO_THREADS - ecb is not used by multiple threads, ever */ /* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */ #if ECB_NO_THREADS #define ECB_NO_SMP 1 #endif #if ECB_NO_SMP #define ECB_MEMORY_FENCE do { } while (0) #endif /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */ #if __xlC__ && ECB_CPP #include #endif #if 1400 <= _MSC_VER #include /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */ #endif #ifndef ECB_MEMORY_FENCE #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 #if __i386 || __i386__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") #elif ECB_GCC_AMD64 #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory") #elif defined __ARM_ARCH_2__ \ || defined __ARM_ARCH_3__ || defined __ARM_ARCH_3M__ \ || defined __ARM_ARCH_4__ || defined __ARM_ARCH_4T__ \ || defined __ARM_ARCH_5__ || defined __ARM_ARCH_5E__ \ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__ \ || defined __ARM_ARCH_5TEJ__ /* should not need any, unless running old code on newer cpu - arm doesn't support that */ #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \ || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__ \ || defined __ARM_ARCH_6T2__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory") #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \ || defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory") #elif __aarch64__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory") #elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8) #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore") #elif defined __s390__ || defined __s390x__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory") #elif defined __mips__ /* GNU/Linux emulates sync on mips1 architectures, so we force its use */ /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */ #define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory") #elif defined __alpha__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory") #elif defined __hppa__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") #elif defined __ia64__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory") #elif defined __m68k__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") #elif defined __m88k__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory") #elif defined __sh__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") #endif #endif #endif #ifndef ECB_MEMORY_FENCE #if ECB_GCC_VERSION(4,7) /* see comment below (stdatomic.h) about the C11 memory model. */ #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) #elif ECB_CLANG_EXTENSION(c_atomic) /* see comment below (stdatomic.h) about the C11 memory model. */ #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ #define ECB_MEMORY_FENCE __sync_synchronize () #elif _MSC_VER >= 1500 /* VC++ 2008 */ /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */ #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) #define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier() #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */ #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier() #elif _MSC_VER >= 1400 /* VC++ 2005 */ #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) #define ECB_MEMORY_FENCE _ReadWriteBarrier () #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */ #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier () #elif defined _WIN32 #include #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */ #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 #include #define ECB_MEMORY_FENCE __machine_rw_barrier () #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier () #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier () #elif __xlC__ #define ECB_MEMORY_FENCE __sync () #endif #endif #ifndef ECB_MEMORY_FENCE #if ECB_C11 && !defined __STDC_NO_ATOMICS__ /* we assume that these memory fences work on all variables/all memory accesses, */ /* not just C11 atomics and atomic accesses */ #include /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */ /* any fence other than seq_cst, which isn't very efficient for us. */ /* Why that is, we don't know - either the C11 memory model is quite useless */ /* for most usages, or gcc and clang have a bug */ /* I *currently* lean towards the latter, and inefficiently implement */ /* all three of ecb's fences as a seq_cst fence */ /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */ /* for all __atomic_thread_fence's except seq_cst */ #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) #endif #endif #ifndef ECB_MEMORY_FENCE #if !ECB_AVOID_PTHREADS /* * if you get undefined symbol references to pthread_mutex_lock, * or failure to find pthread.h, then you should implement * the ECB_MEMORY_FENCE operations for your cpu/compiler * OR provide pthread.h and link against the posix thread library * of your system. */ #include #define ECB_NEEDS_PTHREADS 1 #define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1 static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER; #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0) #endif #endif #if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE #endif #if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE #endif /*****************************************************************************/ #if ECB_CPP #define ecb_inline static inline #elif ECB_GCC_VERSION(2,5) #define ecb_inline static __inline__ #elif ECB_C99 #define ecb_inline static inline #else #define ecb_inline static #endif #if ECB_GCC_VERSION(3,3) #define ecb_restrict __restrict__ #elif ECB_C99 #define ecb_restrict restrict #else #define ecb_restrict #endif typedef int ecb_bool; #define ECB_CONCAT_(a, b) a ## b #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b) #define ECB_STRINGIFY_(a) # a #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) #define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr)) #define ecb_function_ ecb_inline #if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8) #define ecb_attribute(attrlist) __attribute__ (attrlist) #else #define ecb_attribute(attrlist) #endif #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p) #define ecb_is_constant(expr) __builtin_constant_p (expr) #else /* possible C11 impl for integral types typedef struct ecb_is_constant_struct ecb_is_constant_struct; #define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */ #define ecb_is_constant(expr) 0 #endif #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect) #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) #else #define ecb_expect(expr,value) (expr) #endif #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch) #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) #else #define ecb_prefetch(addr,rw,locality) #endif /* no emulation for ecb_decltype */ #if ECB_CPP11 // older implementations might have problems with decltype(x)::type, work around it template struct ecb_decltype_t { typedef T type; }; #define ecb_decltype(x) ecb_decltype_t::type #elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8) #define ecb_decltype(x) __typeof__ (x) #endif #if _MSC_VER >= 1300 #define ecb_deprecated __declspec (deprecated) #else #define ecb_deprecated ecb_attribute ((__deprecated__)) #endif #if _MSC_VER >= 1500 #define ecb_deprecated_message(msg) __declspec (deprecated (msg)) #elif ECB_GCC_VERSION(4,5) #define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg)) #else #define ecb_deprecated_message(msg) ecb_deprecated #endif #if _MSC_VER >= 1400 #define ecb_noinline __declspec (noinline) #else #define ecb_noinline ecb_attribute ((__noinline__)) #endif #define ecb_unused ecb_attribute ((__unused__)) #define ecb_const ecb_attribute ((__const__)) #define ecb_pure ecb_attribute ((__pure__)) #if ECB_C11 || __IBMC_NORETURN /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */ #define ecb_noreturn _Noreturn #elif ECB_CPP11 #define ecb_noreturn [[noreturn]] #elif _MSC_VER >= 1200 /* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */ #define ecb_noreturn __declspec (noreturn) #else #define ecb_noreturn ecb_attribute ((__noreturn__)) #endif #if ECB_GCC_VERSION(4,3) #define ecb_artificial ecb_attribute ((__artificial__)) #define ecb_hot ecb_attribute ((__hot__)) #define ecb_cold ecb_attribute ((__cold__)) #else #define ecb_artificial #define ecb_hot #define ecb_cold #endif /* put around conditional expressions if you are very sure that the */ /* expression is mostly true or mostly false. note that these return */ /* booleans, not the expression. */ #define ecb_expect_false(expr) ecb_expect (!!(expr), 0) #define ecb_expect_true(expr) ecb_expect (!!(expr), 1) /* for compatibility to the rest of the world */ #define ecb_likely(expr) ecb_expect_true (expr) #define ecb_unlikely(expr) ecb_expect_false (expr) /* count trailing zero bits and count # of one bits */ #if ECB_GCC_VERSION(3,4) \ || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \ && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \ && ECB_CLANG_BUILTIN(__builtin_popcount)) /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */ #define ecb_ld32(x) (__builtin_clz (x) ^ 31) #define ecb_ld64(x) (__builtin_clzll (x) ^ 63) #define ecb_ctz32(x) __builtin_ctz (x) #define ecb_ctz64(x) __builtin_ctzll (x) #define ecb_popcount32(x) __builtin_popcount (x) /* no popcountll */ #else ecb_function_ ecb_const int ecb_ctz32 (uint32_t x); ecb_function_ ecb_const int ecb_ctz32 (uint32_t x) { #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) unsigned long r; _BitScanForward (&r, x); return (int)r; #else int r = 0; x &= ~x + 1; /* this isolates the lowest bit */ #if ECB_branchless_on_i386 r += !!(x & 0xaaaaaaaa) << 0; r += !!(x & 0xcccccccc) << 1; r += !!(x & 0xf0f0f0f0) << 2; r += !!(x & 0xff00ff00) << 3; r += !!(x & 0xffff0000) << 4; #else if (x & 0xaaaaaaaa) r += 1; if (x & 0xcccccccc) r += 2; if (x & 0xf0f0f0f0) r += 4; if (x & 0xff00ff00) r += 8; if (x & 0xffff0000) r += 16; #endif return r; #endif } ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); ecb_function_ ecb_const int ecb_ctz64 (uint64_t x) { #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) unsigned long r; _BitScanForward64 (&r, x); return (int)r; #else int shift = x & 0xffffffff ? 0 : 32; return ecb_ctz32 (x >> shift) + shift; #endif } ecb_function_ ecb_const int ecb_popcount32 (uint32_t x); ecb_function_ ecb_const int ecb_popcount32 (uint32_t x) { x -= (x >> 1) & 0x55555555; x = ((x >> 2) & 0x33333333) + (x & 0x33333333); x = ((x >> 4) + x) & 0x0f0f0f0f; x *= 0x01010101; return x >> 24; } ecb_function_ ecb_const int ecb_ld32 (uint32_t x); ecb_function_ ecb_const int ecb_ld32 (uint32_t x) { #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) unsigned long r; _BitScanReverse (&r, x); return (int)r; #else int r = 0; if (x >> 16) { x >>= 16; r += 16; } if (x >> 8) { x >>= 8; r += 8; } if (x >> 4) { x >>= 4; r += 4; } if (x >> 2) { x >>= 2; r += 2; } if (x >> 1) { r += 1; } return r; #endif } ecb_function_ ecb_const int ecb_ld64 (uint64_t x); ecb_function_ ecb_const int ecb_ld64 (uint64_t x) { #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) unsigned long r; _BitScanReverse64 (&r, x); return (int)r; #else int r = 0; if (x >> 32) { x >>= 32; r += 32; } return r + ecb_ld32 (x); #endif } #endif ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x); ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); } ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x); ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); } ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x); ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x) { return ( (x * 0x0802U & 0x22110U) | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; } ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x); ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x) { x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1); x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2); x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4); x = ( x >> 8 ) | ( x << 8); return x; } ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x); ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x) { x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1); x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2); x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4); x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8); x = ( x >> 16 ) | ( x << 16); return x; } /* popcount64 is only available on 64 bit cpus as gcc builtin */ /* so for this version we are lazy */ ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); ecb_function_ ecb_const int ecb_popcount64 (uint64_t x) { return ecb_popcount32 (x) + ecb_popcount32 (x >> 32); } ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count); ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count); ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count); ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count); ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count); ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count); ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count); ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count); ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); } ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); } ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); } ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); } ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); } ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); } ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } #if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64)) #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16) #define ecb_bswap16(x) __builtin_bswap16 (x) #else #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16) #endif #define ecb_bswap32(x) __builtin_bswap32 (x) #define ecb_bswap64(x) __builtin_bswap64 (x) #elif _MSC_VER #include #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x))) #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x))) #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x))) #else ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x); ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x) { return ecb_rotl16 (x, 8); } ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x); ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x) { return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16); } ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x); ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x) { return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32); } #endif #if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable) #define ecb_unreachable() __builtin_unreachable () #else /* this seems to work fine, but gcc always emits a warning for it :/ */ ecb_inline ecb_noreturn void ecb_unreachable (void); ecb_inline ecb_noreturn void ecb_unreachable (void) { } #endif /* try to tell the compiler that some condition is definitely true */ #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 ecb_inline ecb_const uint32_t ecb_byteorder_helper (void); ecb_inline ecb_const uint32_t ecb_byteorder_helper (void) { /* the union code still generates code under pressure in gcc, */ /* but less than using pointers, and always seems to */ /* successfully return a constant. */ /* the reason why we have this horrible preprocessor mess */ /* is to avoid it in all cases, at least on common architectures */ /* or when using a recent enough gcc version (>= 4.6) */ #if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ || ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__) #define ECB_LITTLE_ENDIAN 1 return 0x44332211; #elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \ || ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__) #define ECB_BIG_ENDIAN 1 return 0x11223344; #else union { uint8_t c[4]; uint32_t u; } u = { 0x11, 0x22, 0x33, 0x44 }; return u.u; #endif } ecb_inline ecb_const ecb_bool ecb_big_endian (void); ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; } ecb_inline ecb_const ecb_bool ecb_little_endian (void); ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; } #if ECB_GCC_VERSION(3,0) || ECB_C99 #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) #else #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) #endif #if ECB_CPP template static inline T ecb_div_rd (T val, T div) { return val < 0 ? - ((-val + div - 1) / div) : (val ) / div; } template static inline T ecb_div_ru (T val, T div) { return val < 0 ? - ((-val ) / div) : (val + div - 1) / div; } #else #define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div)) #define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div)) #endif #if ecb_cplusplus_does_not_suck /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */ template static inline int ecb_array_length (const T (&arr)[N]) { return N; } #else #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) #endif ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x) { unsigned int s = (x & 0x8000) << (31 - 15); int e = (x >> 10) & 0x001f; unsigned int m = x & 0x03ff; if (ecb_expect_false (e == 31)) /* infinity or NaN */ e = 255 - (127 - 15); else if (ecb_expect_false (!e)) { if (ecb_expect_true (!m)) /* zero, handled by code below by forcing e to 0 */ e = 0 - (127 - 15); else { /* subnormal, renormalise */ unsigned int s = 10 - ecb_ld32 (m); m = (m << s) & 0x3ff; /* mask implicit bit */ e -= s - 1; } } /* e and m now are normalised, or zero, (or inf or nan) */ e += 127 - 15; return s | (e << 23) | (m << (23 - 10)); } ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x); ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x) { unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */ unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */ unsigned int m = x & 0x007fffff; x &= 0x7fffffff; /* if it's within range of binary16 normals, use fast path */ if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff)) { /* mantissa round-to-even */ m += 0x00000fff + ((m >> (23 - 10)) & 1); /* handle overflow */ if (ecb_expect_false (m >= 0x00800000)) { m >>= 1; e += 1; } return s | (e << 10) | (m >> (23 - 10)); } /* handle large numbers and infinity */ if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000)) return s | 0x7c00; /* handle zero, subnormals and small numbers */ if (ecb_expect_true (x < 0x38800000)) { /* zero */ if (ecb_expect_true (!x)) return s; /* handle subnormals */ /* too small, will be zero */ if (e < (14 - 24)) /* might not be sharp, but is good enough */ return s; m |= 0x00800000; /* make implicit bit explicit */ /* very tricky - we need to round to the nearest e (+10) bit value */ { unsigned int bits = 14 - e; unsigned int half = (1 << (bits - 1)) - 1; unsigned int even = (m >> bits) & 1; /* if this overflows, we will end up with a normalised number */ m = (m + half + even) >> bits; } return s | m; } /* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */ m >>= 13; return s | 0x7c00 | m | !m; } /*******************************************************************************/ /* floating point stuff, can be disabled by defining ECB_NO_LIBM */ /* basically, everything uses "ieee pure-endian" floating point numbers */ /* the only noteworthy exception is ancient armle, which uses order 43218765 */ #if 0 \ || __i386 || __i386__ \ || ECB_GCC_AMD64 \ || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \ || defined __s390__ || defined __s390x__ \ || defined __mips__ \ || defined __alpha__ \ || defined __hppa__ \ || defined __ia64__ \ || defined __m68k__ \ || defined __m88k__ \ || defined __sh__ \ || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \ || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \ || defined __aarch64__ #define ECB_STDFP 1 #include /* for memcpy */ #else #define ECB_STDFP 0 #endif #ifndef ECB_NO_LIBM #include /* for frexp*, ldexp*, INFINITY, NAN */ /* only the oldest of old doesn't have this one. solaris. */ #ifdef INFINITY #define ECB_INFINITY INFINITY #else #define ECB_INFINITY HUGE_VAL #endif #ifdef NAN #define ECB_NAN NAN #else #define ECB_NAN ECB_INFINITY #endif #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L #define ecb_ldexpf(x,e) ldexpf ((x), (e)) #define ecb_frexpf(x,e) frexpf ((x), (e)) #else #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e)) #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) #endif /* convert a float to ieee single/binary32 */ ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x) { uint32_t r; #if ECB_STDFP memcpy (&r, &x, 4); #else /* slow emulation, works for anything but -0 */ uint32_t m; int e; if (x == 0e0f ) return 0x00000000U; if (x > +3.40282346638528860e+38f) return 0x7f800000U; if (x < -3.40282346638528860e+38f) return 0xff800000U; if (x != x ) return 0x7fbfffffU; m = ecb_frexpf (x, &e) * 0x1000000U; r = m & 0x80000000U; if (r) m = -m; if (e <= -126) { m &= 0xffffffU; m >>= (-125 - e); e = -126; } r |= (e + 126) << 23; r |= m & 0x7fffffU; #endif return r; } /* converts an ieee single/binary32 to a float */ ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x); ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x) { float r; #if ECB_STDFP memcpy (&r, &x, 4); #else /* emulation, only works for normals and subnormals and +0 */ int neg = x >> 31; int e = (x >> 23) & 0xffU; x &= 0x7fffffU; if (e) x |= 0x800000U; else e = 1; /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126); r = neg ? -r : r; #endif return r; } /* convert a double to ieee double/binary64 */ ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x); ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x) { uint64_t r; #if ECB_STDFP memcpy (&r, &x, 8); #else /* slow emulation, works for anything but -0 */ uint64_t m; int e; if (x == 0e0 ) return 0x0000000000000000U; if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U; if (x < -1.79769313486231470e+308) return 0xfff0000000000000U; if (x != x ) return 0X7ff7ffffffffffffU; m = frexp (x, &e) * 0x20000000000000U; r = m & 0x8000000000000000;; if (r) m = -m; if (e <= -1022) { m &= 0x1fffffffffffffU; m >>= (-1021 - e); e = -1022; } r |= ((uint64_t)(e + 1022)) << 52; r |= m & 0xfffffffffffffU; #endif return r; } /* converts an ieee double/binary64 to a double */ ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x); ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x) { double r; #if ECB_STDFP memcpy (&r, &x, 8); #else /* emulation, only works for normals and subnormals and +0 */ int neg = x >> 63; int e = (x >> 52) & 0x7ffU; x &= 0xfffffffffffffU; if (e) x |= 0x10000000000000U; else e = 1; /* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */ r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022); r = neg ? -r : r; #endif return r; } /* convert a float to ieee half/binary16 */ ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x); ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x) { return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x)); } /* convert an ieee half/binary16 to float */ ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x) { return ecb_binary32_to_float (ecb_binary16_to_binary32 (x)); } #endif #endif /* ECB.H END */ #if ECB_MEMORY_FENCE_NEEDS_PTHREADS /* if your architecture doesn't need memory fences, e.g. because it is * single-cpu/core, or if you use libev in a project that doesn't use libev * from multiple threads, then you can define ECB_AVOID_PTHREADS when compiling * libev, in which cases the memory fences become nops. * alternatively, you can remove this #error and link against libpthread, * which will then provide the memory fences. */ # error "memory fences not defined for your architecture, please report" #endif #ifndef ECB_MEMORY_FENCE # define ECB_MEMORY_FENCE do { } while (0) # define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE # define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE #endif #define expect_false(cond) ecb_expect_false (cond) #define expect_true(cond) ecb_expect_true (cond) #define noinline ecb_noinline #define inline_size ecb_inline #if EV_FEATURE_CODE # define inline_speed ecb_inline #else # define inline_speed noinline static #endif #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) #if EV_MINPRI == EV_MAXPRI # define ABSPRI(w) (((W)w), 0) #else # define ABSPRI(w) (((W)w)->priority - EV_MINPRI) #endif #define EMPTY /* required for microsofts broken pseudo-c compiler */ #define EMPTY2(a,b) /* used to suppress some warnings */ typedef ev_watcher *W; typedef ev_watcher_list *WL; typedef ev_watcher_time *WT; #define ev_active(w) ((W)(w))->active #define ev_at(w) ((WT)(w))->at #if EV_USE_REALTIME /* sig_atomic_t is used to avoid per-thread variables or locking but still */ /* giving it a reasonably high chance of working on typical architectures */ static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */ #endif #if EV_USE_MONOTONIC static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */ #endif #ifndef EV_FD_TO_WIN32_HANDLE # define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd) #endif #ifndef EV_WIN32_HANDLE_TO_FD # define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0) #endif #ifndef EV_WIN32_CLOSE_FD # define EV_WIN32_CLOSE_FD(fd) close (fd) #endif #ifdef _WIN32 # include "ev_win32.c" #endif /*****************************************************************************/ /* define a suitable floor function (only used by periodics atm) */ #if EV_USE_FLOOR # include # define ev_floor(v) floor (v) #else #include /* a floor() replacement function, should be independent of ev_tstamp type */ noinline static ev_tstamp ev_floor (ev_tstamp v) { /* the choice of shift factor is not terribly important */ #if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */ const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.; #else const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.; #endif /* argument too large for an unsigned long? */ if (expect_false (v >= shift)) { ev_tstamp f; if (v == v - 1.) return v; /* very large number */ f = shift * ev_floor (v * (1. / shift)); return f + ev_floor (v - f); } /* special treatment for negative args? */ if (expect_false (v < 0.)) { ev_tstamp f = -ev_floor (-v); return f - (f == v ? 0 : 1); } /* fits into an unsigned long */ return (unsigned long)v; } #endif /*****************************************************************************/ #ifdef __linux # include #endif noinline ecb_cold static unsigned int ev_linux_version (void) { #ifdef __linux unsigned int v = 0; struct utsname buf; int i; char *p = buf.release; if (uname (&buf)) return 0; for (i = 3+1; --i; ) { unsigned int c = 0; for (;;) { if (*p >= '0' && *p <= '9') c = c * 10 + *p++ - '0'; else { p += *p == '.'; break; } } v = (v << 8) | c; } return v; #else return 0; #endif } /*****************************************************************************/ #if EV_AVOID_STDIO noinline ecb_cold static void ev_printerr (const char *msg) { write (STDERR_FILENO, msg, strlen (msg)); } #endif static void (*syserr_cb)(const char *msg) EV_THROW; ecb_cold void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW { syserr_cb = cb; } noinline ecb_cold static void ev_syserr (const char *msg) { if (!msg) msg = "(libev) system error"; if (syserr_cb) syserr_cb (msg); else { #if EV_AVOID_STDIO ev_printerr (msg); ev_printerr (": "); ev_printerr (strerror (errno)); ev_printerr ("\n"); #else perror (msg); #endif abort (); } } static void * ev_realloc_emul (void *ptr, long size) EV_THROW { /* some systems, notably openbsd and darwin, fail to properly * implement realloc (x, 0) (as required by both ansi c-89 and * the single unix specification, so work around them here. * recently, also (at least) fedora and debian started breaking it, * despite documenting it otherwise. */ if (size) return realloc (ptr, size); free (ptr); return 0; } static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul; ecb_cold void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW { alloc = cb; } inline_speed void * ev_realloc (void *ptr, long size) { ptr = alloc (ptr, size); if (!ptr && size) { #if EV_AVOID_STDIO ev_printerr ("(libev) memory allocation failed, aborting.\n"); #else fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size); #endif abort (); } return ptr; } #define ev_malloc(size) ev_realloc (0, (size)) #define ev_free(ptr) ev_realloc ((ptr), 0) /*****************************************************************************/ /* set in reify when reification needed */ #define EV_ANFD_REIFY 1 /* file descriptor info structure */ typedef struct { WL head; unsigned char events; /* the events watched for */ unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */ unsigned char emask; /* the epoll backend stores the actual kernel mask in here */ unsigned char unused; #if EV_USE_EPOLL unsigned int egen; /* generation counter to counter epoll bugs */ #endif #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP SOCKET handle; #endif #if EV_USE_IOCP OVERLAPPED or, ow; #endif } ANFD; /* stores the pending event set for a given watcher */ typedef struct { W w; int events; /* the pending event set for the given watcher */ } ANPENDING; #if EV_USE_INOTIFY /* hash table entry per inotify-id */ typedef struct { WL head; } ANFS; #endif /* Heap Entry */ #if EV_HEAP_CACHE_AT /* a heap element */ typedef struct { ev_tstamp at; WT w; } ANHE; #define ANHE_w(he) (he).w /* access watcher, read-write */ #define ANHE_at(he) (he).at /* access cached at, read-only */ #define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */ #else /* a heap element */ typedef WT ANHE; #define ANHE_w(he) (he) #define ANHE_at(he) (he)->at #define ANHE_at_cache(he) #endif #if EV_MULTIPLICITY struct ev_loop { ev_tstamp ev_rt_now; #define ev_rt_now ((loop)->ev_rt_now) #define VAR(name,decl) decl; #include "ev_vars.h" #undef VAR }; #include "ev_wrap.h" static struct ev_loop default_loop_struct; EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */ #else EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */ #define VAR(name,decl) static decl; #include "ev_vars.h" #undef VAR static int ev_default_loop_ptr; #endif #if EV_FEATURE_API # define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A) # define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A) # define EV_INVOKE_PENDING invoke_cb (EV_A) #else # define EV_RELEASE_CB (void)0 # define EV_ACQUIRE_CB (void)0 # define EV_INVOKE_PENDING ev_invoke_pending (EV_A) #endif #define EVBREAK_RECURSE 0x80 /*****************************************************************************/ #ifndef EV_HAVE_EV_TIME ev_tstamp ev_time (void) EV_THROW { #if EV_USE_REALTIME if (expect_true (have_realtime)) { struct timespec ts; clock_gettime (CLOCK_REALTIME, &ts); return ts.tv_sec + ts.tv_nsec * 1e-9; } #endif struct timeval tv; gettimeofday (&tv, 0); return tv.tv_sec + tv.tv_usec * 1e-6; } #endif inline_size ev_tstamp get_clock (void) { #if EV_USE_MONOTONIC if (expect_true (have_monotonic)) { struct timespec ts; clock_gettime (CLOCK_MONOTONIC, &ts); return ts.tv_sec + ts.tv_nsec * 1e-9; } #endif return ev_time (); } #if EV_MULTIPLICITY ev_tstamp ev_now (EV_P) EV_THROW { return ev_rt_now; } #endif void ev_sleep (ev_tstamp delay) EV_THROW { if (delay > 0.) { #if EV_USE_NANOSLEEP struct timespec ts; EV_TS_SET (ts, delay); nanosleep (&ts, 0); #elif defined _WIN32 Sleep ((unsigned long)(delay * 1e3)); #else struct timeval tv; /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ /* something not guaranteed by newer posix versions, but guaranteed */ /* by older ones */ EV_TV_SET (tv, delay); select (0, 0, 0, 0, &tv); #endif } } /*****************************************************************************/ #define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */ /* find a suitable new size for the given array, */ /* hopefully by rounding to a nice-to-malloc size */ inline_size int array_nextsize (int elem, int cur, int cnt) { int ncur = cur + 1; do ncur <<= 1; while (cnt > ncur); /* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */ if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4) { ncur *= elem; ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1); ncur = ncur - sizeof (void *) * 4; ncur /= elem; } return ncur; } noinline ecb_cold static void * array_realloc (int elem, void *base, int *cur, int cnt) { *cur = array_nextsize (elem, *cur, cnt); return ev_realloc (base, elem * *cur); } #define array_init_zero(base,count) \ memset ((void *)(base), 0, sizeof (*(base)) * (count)) #define array_needsize(type,base,cur,cnt,init) \ if (expect_false ((cnt) > (cur))) \ { \ ecb_unused int ocur_ = (cur); \ (base) = (type *)array_realloc \ (sizeof (type), (base), &(cur), (cnt)); \ init ((base) + (ocur_), (cur) - ocur_); \ } #if 0 #define array_slim(type,stem) \ if (stem ## max < array_roundsize (stem ## cnt >> 2)) \ { \ stem ## max = array_roundsize (stem ## cnt >> 1); \ base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\ fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\ } #endif #define array_free(stem, idx) \ ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0 /*****************************************************************************/ /* dummy callback for pending events */ noinline static void pendingcb (EV_P_ ev_prepare *w, int revents) { } noinline void ev_feed_event (EV_P_ void *w, int revents) EV_THROW { W w_ = (W)w; int pri = ABSPRI (w_); if (expect_false (w_->pending)) pendings [pri][w_->pending - 1].events |= revents; else { w_->pending = ++pendingcnt [pri]; array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2); pendings [pri][w_->pending - 1].w = w_; pendings [pri][w_->pending - 1].events = revents; } pendingpri = NUMPRI - 1; } inline_speed void feed_reverse (EV_P_ W w) { array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2); rfeeds [rfeedcnt++] = w; } inline_size void feed_reverse_done (EV_P_ int revents) { do ev_feed_event (EV_A_ rfeeds [--rfeedcnt], revents); while (rfeedcnt); } inline_speed void queue_events (EV_P_ W *events, int eventcnt, int type) { int i; for (i = 0; i < eventcnt; ++i) ev_feed_event (EV_A_ events [i], type); } /*****************************************************************************/ inline_speed void fd_event_nocheck (EV_P_ int fd, int revents) { ANFD *anfd = anfds + fd; ev_io *w; for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next) { int ev = w->events & revents; if (ev) ev_feed_event (EV_A_ (W)w, ev); } } /* do not submit kernel events for fds that have reify set */ /* because that means they changed while we were polling for new events */ inline_speed void fd_event (EV_P_ int fd, int revents) { ANFD *anfd = anfds + fd; if (expect_true (!anfd->reify)) fd_event_nocheck (EV_A_ fd, revents); } void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW { if (fd >= 0 && fd < anfdmax) fd_event_nocheck (EV_A_ fd, revents); } /* make sure the external fd watch events are in-sync */ /* with the kernel/libev internal state */ inline_size void fd_reify (EV_P) { int i; #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP for (i = 0; i < fdchangecnt; ++i) { int fd = fdchanges [i]; ANFD *anfd = anfds + fd; if (anfd->reify & EV__IOFDSET && anfd->head) { SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd); if (handle != anfd->handle) { unsigned long arg; assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0)); /* handle changed, but fd didn't - we need to do it in two steps */ backend_modify (EV_A_ fd, anfd->events, 0); anfd->events = 0; anfd->handle = handle; } } } #endif for (i = 0; i < fdchangecnt; ++i) { int fd = fdchanges [i]; ANFD *anfd = anfds + fd; ev_io *w; unsigned char o_events = anfd->events; unsigned char o_reify = anfd->reify; anfd->reify = 0; /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */ { anfd->events = 0; for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next) anfd->events |= (unsigned char)w->events; if (o_events != anfd->events) o_reify = EV__IOFDSET; /* actually |= */ } if (o_reify & EV__IOFDSET) backend_modify (EV_A_ fd, o_events, anfd->events); } fdchangecnt = 0; } /* something about the given fd changed */ inline_size void fd_change (EV_P_ int fd, int flags) { unsigned char reify = anfds [fd].reify; anfds [fd].reify |= flags; if (expect_true (!reify)) { ++fdchangecnt; array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2); fdchanges [fdchangecnt - 1] = fd; } } /* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */ inline_speed ecb_cold void fd_kill (EV_P_ int fd) { ev_io *w; while ((w = (ev_io *)anfds [fd].head)) { ev_io_stop (EV_A_ w); ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE); } } /* check whether the given fd is actually valid, for error recovery */ inline_size ecb_cold int fd_valid (int fd) { #ifdef _WIN32 return EV_FD_TO_WIN32_HANDLE (fd) != -1; #else return fcntl (fd, F_GETFD) != -1; #endif } /* called on EBADF to verify fds */ noinline ecb_cold static void fd_ebadf (EV_P) { int fd; for (fd = 0; fd < anfdmax; ++fd) if (anfds [fd].events) if (!fd_valid (fd) && errno == EBADF) fd_kill (EV_A_ fd); } /* called on ENOMEM in select/poll to kill some fds and retry */ noinline ecb_cold static void fd_enomem (EV_P) { int fd; for (fd = anfdmax; fd--; ) if (anfds [fd].events) { fd_kill (EV_A_ fd); break; } } /* usually called after fork if backend needs to re-arm all fds from scratch */ noinline static void fd_rearm_all (EV_P) { int fd; for (fd = 0; fd < anfdmax; ++fd) if (anfds [fd].events) { anfds [fd].events = 0; anfds [fd].emask = 0; fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY); } } /* used to prepare libev internal fd's */ /* this is not fork-safe */ inline_speed void fd_intern (int fd) { #ifdef _WIN32 unsigned long arg = 1; ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg); #else fcntl (fd, F_SETFD, FD_CLOEXEC); fcntl (fd, F_SETFL, O_NONBLOCK); #endif } /*****************************************************************************/ /* * the heap functions want a real array index. array index 0 is guaranteed to not * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives * the branching factor of the d-tree. */ /* * at the moment we allow libev the luxury of two heaps, * a small-code-size 2-heap one and a ~1.5kb larger 4-heap * which is more cache-efficient. * the difference is about 5% with 50000+ watchers. */ #if EV_USE_4HEAP #define DHEAP 4 #define HEAP0 (DHEAP - 1) /* index of first element in heap */ #define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0) #define UPHEAP_DONE(p,k) ((p) == (k)) /* away from the root */ inline_speed void downheap (ANHE *heap, int N, int k) { ANHE he = heap [k]; ANHE *E = heap + N + HEAP0; for (;;) { ev_tstamp minat; ANHE *minpos; ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1; /* find minimum child */ if (expect_true (pos + DHEAP - 1 < E)) { /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); } else if (pos < E) { /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); } else break; if (ANHE_at (he) <= minat) break; heap [k] = *minpos; ev_active (ANHE_w (*minpos)) = k; k = minpos - heap; } heap [k] = he; ev_active (ANHE_w (he)) = k; } #else /* 4HEAP */ #define HEAP0 1 #define HPARENT(k) ((k) >> 1) #define UPHEAP_DONE(p,k) (!(p)) /* away from the root */ inline_speed void downheap (ANHE *heap, int N, int k) { ANHE he = heap [k]; for (;;) { int c = k << 1; if (c >= N + HEAP0) break; c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1]) ? 1 : 0; if (ANHE_at (he) <= ANHE_at (heap [c])) break; heap [k] = heap [c]; ev_active (ANHE_w (heap [k])) = k; k = c; } heap [k] = he; ev_active (ANHE_w (he)) = k; } #endif /* towards the root */ inline_speed void upheap (ANHE *heap, int k) { ANHE he = heap [k]; for (;;) { int p = HPARENT (k); if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he)) break; heap [k] = heap [p]; ev_active (ANHE_w (heap [k])) = k; k = p; } heap [k] = he; ev_active (ANHE_w (he)) = k; } /* move an element suitably so it is in a correct place */ inline_size void adjustheap (ANHE *heap, int N, int k) { if (k > HEAP0 && ANHE_at (heap [k]) <= ANHE_at (heap [HPARENT (k)])) upheap (heap, k); else downheap (heap, N, k); } /* rebuild the heap: this function is used only once and executed rarely */ inline_size void reheap (ANHE *heap, int N) { int i; /* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */ /* also, this is easy to implement and correct for both 2-heaps and 4-heaps */ for (i = 0; i < N; ++i) upheap (heap, i + HEAP0); } /*****************************************************************************/ /* associate signal watchers to a signal signal */ typedef struct { EV_ATOMIC_T pending; #if EV_MULTIPLICITY EV_P; #endif WL head; } ANSIG; static ANSIG signals [EV_NSIG - 1]; /*****************************************************************************/ #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE noinline ecb_cold static void evpipe_init (EV_P) { if (!ev_is_active (&pipe_w)) { int fds [2]; # if EV_USE_EVENTFD fds [0] = -1; fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); if (fds [1] < 0 && errno == EINVAL) fds [1] = eventfd (0, 0); if (fds [1] < 0) # endif { while (pipe (fds)) ev_syserr ("(libev) error creating signal/async pipe"); fd_intern (fds [0]); } evpipe [0] = fds [0]; if (evpipe [1] < 0) evpipe [1] = fds [1]; /* first call, set write fd */ else { /* on subsequent calls, do not change evpipe [1] */ /* so that evpipe_write can always rely on its value. */ /* this branch does not do anything sensible on windows, */ /* so must not be executed on windows */ dup2 (fds [1], evpipe [1]); close (fds [1]); } fd_intern (evpipe [1]); ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ); ev_io_start (EV_A_ &pipe_w); ev_unref (EV_A); /* watcher should not keep loop alive */ } } inline_speed void evpipe_write (EV_P_ EV_ATOMIC_T *flag) { ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */ if (expect_true (*flag)) return; *flag = 1; ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */ pipe_write_skipped = 1; ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */ if (pipe_write_wanted) { int old_errno; pipe_write_skipped = 0; ECB_MEMORY_FENCE_RELEASE; old_errno = errno; /* save errno because write will clobber it */ #if EV_USE_EVENTFD if (evpipe [0] < 0) { uint64_t counter = 1; write (evpipe [1], &counter, sizeof (uint64_t)); } else #endif { #ifdef _WIN32 WSABUF buf; DWORD sent; buf.buf = &buf; buf.len = 1; WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0); #else write (evpipe [1], &(evpipe [1]), 1); #endif } errno = old_errno; } } /* called whenever the libev signal pipe */ /* got some events (signal, async) */ static void pipecb (EV_P_ ev_io *iow, int revents) { int i; if (revents & EV_READ) { #if EV_USE_EVENTFD if (evpipe [0] < 0) { uint64_t counter; read (evpipe [1], &counter, sizeof (uint64_t)); } else #endif { char dummy[4]; #ifdef _WIN32 WSABUF buf; DWORD recvd; DWORD flags = 0; buf.buf = dummy; buf.len = sizeof (dummy); WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0); #else read (evpipe [0], &dummy, sizeof (dummy)); #endif } } pipe_write_skipped = 0; ECB_MEMORY_FENCE; /* push out skipped, acquire flags */ #if EV_SIGNAL_ENABLE if (sig_pending) { sig_pending = 0; ECB_MEMORY_FENCE; for (i = EV_NSIG - 1; i--; ) if (expect_false (signals [i].pending)) ev_feed_signal_event (EV_A_ i + 1); } #endif #if EV_ASYNC_ENABLE if (async_pending) { async_pending = 0; ECB_MEMORY_FENCE; for (i = asynccnt; i--; ) if (asyncs [i]->sent) { asyncs [i]->sent = 0; ECB_MEMORY_FENCE_RELEASE; ev_feed_event (EV_A_ asyncs [i], EV_ASYNC); } } #endif } /*****************************************************************************/ void ev_feed_signal (int signum) EV_THROW { #if EV_MULTIPLICITY EV_P; ECB_MEMORY_FENCE_ACQUIRE; EV_A = signals [signum - 1].loop; if (!EV_A) return; #endif signals [signum - 1].pending = 1; evpipe_write (EV_A_ &sig_pending); } static void ev_sighandler (int signum) { #ifdef _WIN32 signal (signum, ev_sighandler); #endif ev_feed_signal (signum); } noinline void ev_feed_signal_event (EV_P_ int signum) EV_THROW { WL w; if (expect_false (signum <= 0 || signum >= EV_NSIG)) return; --signum; #if EV_MULTIPLICITY /* it is permissible to try to feed a signal to the wrong loop */ /* or, likely more useful, feeding a signal nobody is waiting for */ if (expect_false (signals [signum].loop != EV_A)) return; #endif signals [signum].pending = 0; ECB_MEMORY_FENCE_RELEASE; for (w = signals [signum].head; w; w = w->next) ev_feed_event (EV_A_ (W)w, EV_SIGNAL); } #if EV_USE_SIGNALFD static void sigfdcb (EV_P_ ev_io *iow, int revents) { struct signalfd_siginfo si[2], *sip; /* these structs are big */ for (;;) { ssize_t res = read (sigfd, si, sizeof (si)); /* not ISO-C, as res might be -1, but works with SuS */ for (sip = si; (char *)sip < (char *)si + res; ++sip) ev_feed_signal_event (EV_A_ sip->ssi_signo); if (res < (ssize_t)sizeof (si)) break; } } #endif #endif /*****************************************************************************/ #if EV_CHILD_ENABLE static WL childs [EV_PID_HASHSIZE]; static ev_signal childev; #ifndef WIFCONTINUED # define WIFCONTINUED(status) 0 #endif /* handle a single child status event */ inline_speed void child_reap (EV_P_ int chain, int pid, int status) { ev_child *w; int traced = WIFSTOPPED (status) || WIFCONTINUED (status); for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) { if ((w->pid == pid || !w->pid) && (!traced || (w->flags & 1))) { ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */ w->rpid = pid; w->rstatus = status; ev_feed_event (EV_A_ (W)w, EV_CHILD); } } } #ifndef WCONTINUED # define WCONTINUED 0 #endif /* called on sigchld etc., calls waitpid */ static void childcb (EV_P_ ev_signal *sw, int revents) { int pid, status; /* some systems define WCONTINUED but then fail to support it (linux 2.4) */ if (0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED))) if (!WCONTINUED || errno != EINVAL || 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED))) return; /* make sure we are called again until all children have been reaped */ /* we need to do it this way so that the callback gets called before we continue */ ev_feed_event (EV_A_ (W)sw, EV_SIGNAL); child_reap (EV_A_ pid, pid, status); if ((EV_PID_HASHSIZE) > 1) child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */ } #endif /*****************************************************************************/ #if EV_USE_IOCP # include "ev_iocp.c" #endif #if EV_USE_PORT # include "ev_port.c" #endif #if EV_USE_KQUEUE # include "ev_kqueue.c" #endif #if EV_USE_EPOLL # include "ev_epoll.c" #endif #if EV_USE_POLL # include "ev_poll.c" #endif #if EV_USE_SELECT # include "ev_select.c" #endif ecb_cold int ev_version_major (void) EV_THROW { return EV_VERSION_MAJOR; } ecb_cold int ev_version_minor (void) EV_THROW { return EV_VERSION_MINOR; } /* return true if we are running with elevated privileges and should ignore env variables */ inline_size ecb_cold int enable_secure (void) { #ifdef _WIN32 return 0; #else return getuid () != geteuid () || getgid () != getegid (); #endif } ecb_cold unsigned int ev_supported_backends (void) EV_THROW { unsigned int flags = 0; if (EV_USE_PORT ) flags |= EVBACKEND_PORT; if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE; if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL; if (EV_USE_POLL ) flags |= EVBACKEND_POLL; if (EV_USE_SELECT) flags |= EVBACKEND_SELECT; return flags; } ecb_cold unsigned int ev_recommended_backends (void) EV_THROW { unsigned int flags = ev_supported_backends (); #ifndef __NetBSD__ /* kqueue is borked on everything but netbsd apparently */ /* it usually doesn't work correctly on anything but sockets and pipes */ flags &= ~EVBACKEND_KQUEUE; #endif #ifdef __APPLE__ /* only select works correctly on that "unix-certified" platform */ flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */ flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */ #endif #ifdef __FreeBSD__ flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */ #endif return flags; } ecb_cold unsigned int ev_embeddable_backends (void) EV_THROW { int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT; /* epoll embeddability broken on all linux versions up to at least 2.6.23 */ if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */ flags &= ~EVBACKEND_EPOLL; return flags; } unsigned int ev_backend (EV_P) EV_THROW { return backend; } #if EV_FEATURE_API unsigned int ev_iteration (EV_P) EV_THROW { return loop_count; } unsigned int ev_depth (EV_P) EV_THROW { return loop_depth; } void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW { io_blocktime = interval; } void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW { timeout_blocktime = interval; } void ev_set_userdata (EV_P_ void *data) EV_THROW { userdata = data; } void * ev_userdata (EV_P) EV_THROW { return userdata; } void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW { invoke_cb = invoke_pending_cb; } void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW { release_cb = release; acquire_cb = acquire; } #endif /* initialise a loop structure, must be zero-initialised */ noinline ecb_cold static void loop_init (EV_P_ unsigned int flags) EV_THROW { if (!backend) { origflags = flags; #if EV_USE_REALTIME if (!have_realtime) { struct timespec ts; if (!clock_gettime (CLOCK_REALTIME, &ts)) have_realtime = 1; } #endif #if EV_USE_MONOTONIC if (!have_monotonic) { struct timespec ts; if (!clock_gettime (CLOCK_MONOTONIC, &ts)) have_monotonic = 1; } #endif /* pid check not overridable via env */ #ifndef _WIN32 if (flags & EVFLAG_FORKCHECK) curpid = getpid (); #endif if (!(flags & EVFLAG_NOENV) && !enable_secure () && getenv ("LIBEV_FLAGS")) flags = atoi (getenv ("LIBEV_FLAGS")); ev_rt_now = ev_time (); mn_now = get_clock (); now_floor = mn_now; rtmn_diff = ev_rt_now - mn_now; #if EV_FEATURE_API invoke_cb = ev_invoke_pending; #endif io_blocktime = 0.; timeout_blocktime = 0.; backend = 0; backend_fd = -1; sig_pending = 0; #if EV_ASYNC_ENABLE async_pending = 0; #endif pipe_write_skipped = 0; pipe_write_wanted = 0; evpipe [0] = -1; evpipe [1] = -1; #if EV_USE_INOTIFY fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2; #endif #if EV_USE_SIGNALFD sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1; #endif if (!(flags & EVBACKEND_MASK)) flags |= ev_recommended_backends (); #if EV_USE_IOCP if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags); #endif #if EV_USE_PORT if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags); #endif #if EV_USE_KQUEUE if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags); #endif #if EV_USE_EPOLL if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags); #endif #if EV_USE_POLL if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags); #endif #if EV_USE_SELECT if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags); #endif ev_prepare_init (&pending_w, pendingcb); #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE ev_init (&pipe_w, pipecb); ev_set_priority (&pipe_w, EV_MAXPRI); #endif } } /* free up a loop structure */ ecb_cold void ev_loop_destroy (EV_P) { int i; #if EV_MULTIPLICITY /* mimic free (0) */ if (!EV_A) return; #endif #if EV_CLEANUP_ENABLE /* queue cleanup watchers (and execute them) */ if (expect_false (cleanupcnt)) { queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP); EV_INVOKE_PENDING; } #endif #if EV_CHILD_ENABLE if (ev_is_default_loop (EV_A) && ev_is_active (&childev)) { ev_ref (EV_A); /* child watcher */ ev_signal_stop (EV_A_ &childev); } #endif if (ev_is_active (&pipe_w)) { /*ev_ref (EV_A);*/ /*ev_io_stop (EV_A_ &pipe_w);*/ if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]); if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]); } #if EV_USE_SIGNALFD if (ev_is_active (&sigfd_w)) close (sigfd); #endif #if EV_USE_INOTIFY if (fs_fd >= 0) close (fs_fd); #endif if (backend_fd >= 0) close (backend_fd); #if EV_USE_IOCP if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A); #endif #if EV_USE_PORT if (backend == EVBACKEND_PORT ) port_destroy (EV_A); #endif #if EV_USE_KQUEUE if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A); #endif #if EV_USE_EPOLL if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A); #endif #if EV_USE_POLL if (backend == EVBACKEND_POLL ) poll_destroy (EV_A); #endif #if EV_USE_SELECT if (backend == EVBACKEND_SELECT) select_destroy (EV_A); #endif for (i = NUMPRI; i--; ) { array_free (pending, [i]); #if EV_IDLE_ENABLE array_free (idle, [i]); #endif } ev_free (anfds); anfds = 0; anfdmax = 0; /* have to use the microsoft-never-gets-it-right macro */ array_free (rfeed, EMPTY); array_free (fdchange, EMPTY); array_free (timer, EMPTY); #if EV_PERIODIC_ENABLE array_free (periodic, EMPTY); #endif #if EV_FORK_ENABLE array_free (fork, EMPTY); #endif #if EV_CLEANUP_ENABLE array_free (cleanup, EMPTY); #endif array_free (prepare, EMPTY); array_free (check, EMPTY); #if EV_ASYNC_ENABLE array_free (async, EMPTY); #endif backend = 0; #if EV_MULTIPLICITY if (ev_is_default_loop (EV_A)) #endif ev_default_loop_ptr = 0; #if EV_MULTIPLICITY else ev_free (EV_A); #endif } #if EV_USE_INOTIFY inline_size void infy_fork (EV_P); #endif inline_size void loop_fork (EV_P) { #if EV_USE_PORT if (backend == EVBACKEND_PORT ) port_fork (EV_A); #endif #if EV_USE_KQUEUE if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A); #endif #if EV_USE_EPOLL if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A); #endif #if EV_USE_INOTIFY infy_fork (EV_A); #endif #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE if (ev_is_active (&pipe_w) && postfork != 2) { /* pipe_write_wanted must be false now, so modifying fd vars should be safe */ ev_ref (EV_A); ev_io_stop (EV_A_ &pipe_w); if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]); evpipe_init (EV_A); /* iterate over everything, in case we missed something before */ ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); } #endif postfork = 0; } #if EV_MULTIPLICITY ecb_cold struct ev_loop * ev_loop_new (unsigned int flags) EV_THROW { EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop)); memset (EV_A, 0, sizeof (struct ev_loop)); loop_init (EV_A_ flags); if (ev_backend (EV_A)) return EV_A; ev_free (EV_A); return 0; } #endif /* multiplicity */ #if EV_VERIFY noinline ecb_cold static void verify_watcher (EV_P_ W w) { assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI)); if (w->pending) assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w)); } noinline ecb_cold static void verify_heap (EV_P_ ANHE *heap, int N) { int i; for (i = HEAP0; i < N + HEAP0; ++i) { assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i)); assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i]))); assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i])))); verify_watcher (EV_A_ (W)ANHE_w (heap [i])); } } noinline ecb_cold static void array_verify (EV_P_ W *ws, int cnt) { while (cnt--) { assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1)); verify_watcher (EV_A_ ws [cnt]); } } #endif #if EV_FEATURE_API void ecb_cold ev_verify (EV_P) EV_THROW { #if EV_VERIFY int i; WL w, w2; assert (activecnt >= -1); assert (fdchangemax >= fdchangecnt); for (i = 0; i < fdchangecnt; ++i) assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0)); assert (anfdmax >= 0); for (i = 0; i < anfdmax; ++i) { int j = 0; for (w = w2 = anfds [i].head; w; w = w->next) { verify_watcher (EV_A_ (W)w); if (j++ & 1) { assert (("libev: io watcher list contains a loop", w != w2)); w2 = w2->next; } assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1)); assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i)); } } assert (timermax >= timercnt); verify_heap (EV_A_ timers, timercnt); #if EV_PERIODIC_ENABLE assert (periodicmax >= periodiccnt); verify_heap (EV_A_ periodics, periodiccnt); #endif for (i = NUMPRI; i--; ) { assert (pendingmax [i] >= pendingcnt [i]); #if EV_IDLE_ENABLE assert (idleall >= 0); assert (idlemax [i] >= idlecnt [i]); array_verify (EV_A_ (W *)idles [i], idlecnt [i]); #endif } #if EV_FORK_ENABLE assert (forkmax >= forkcnt); array_verify (EV_A_ (W *)forks, forkcnt); #endif #if EV_CLEANUP_ENABLE assert (cleanupmax >= cleanupcnt); array_verify (EV_A_ (W *)cleanups, cleanupcnt); #endif #if EV_ASYNC_ENABLE assert (asyncmax >= asynccnt); array_verify (EV_A_ (W *)asyncs, asynccnt); #endif #if EV_PREPARE_ENABLE assert (preparemax >= preparecnt); array_verify (EV_A_ (W *)prepares, preparecnt); #endif #if EV_CHECK_ENABLE assert (checkmax >= checkcnt); array_verify (EV_A_ (W *)checks, checkcnt); #endif # if 0 #if EV_CHILD_ENABLE for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) for (signum = EV_NSIG; signum--; ) if (signals [signum].pending) #endif # endif #endif } #endif #if EV_MULTIPLICITY ecb_cold struct ev_loop * #else int #endif ev_default_loop (unsigned int flags) EV_THROW { if (!ev_default_loop_ptr) { #if EV_MULTIPLICITY EV_P = ev_default_loop_ptr = &default_loop_struct; #else ev_default_loop_ptr = 1; #endif loop_init (EV_A_ flags); if (ev_backend (EV_A)) { #if EV_CHILD_ENABLE ev_signal_init (&childev, childcb, SIGCHLD); ev_set_priority (&childev, EV_MAXPRI); ev_signal_start (EV_A_ &childev); ev_unref (EV_A); /* child watcher should not keep loop alive */ #endif } else ev_default_loop_ptr = 0; } return ev_default_loop_ptr; } void ev_loop_fork (EV_P) EV_THROW { postfork = 1; } /*****************************************************************************/ void ev_invoke (EV_P_ void *w, int revents) { EV_CB_INVOKE ((W)w, revents); } unsigned int ev_pending_count (EV_P) EV_THROW { int pri; unsigned int count = 0; for (pri = NUMPRI; pri--; ) count += pendingcnt [pri]; return count; } noinline void ev_invoke_pending (EV_P) { pendingpri = NUMPRI; while (pendingpri) /* pendingpri possibly gets modified in the inner loop */ { --pendingpri; while (pendingcnt [pendingpri]) { ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri]; p->w->pending = 0; EV_CB_INVOKE (p->w, p->events); EV_FREQUENT_CHECK; } } } #if EV_IDLE_ENABLE /* make idle watchers pending. this handles the "call-idle */ /* only when higher priorities are idle" logic */ inline_size void idle_reify (EV_P) { if (expect_false (idleall)) { int pri; for (pri = NUMPRI; pri--; ) { if (pendingcnt [pri]) break; if (idlecnt [pri]) { queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE); break; } } } } #endif /* make timers pending */ inline_size void timers_reify (EV_P) { EV_FREQUENT_CHECK; if (timercnt && ANHE_at (timers [HEAP0]) < mn_now) { do { ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]); /*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/ /* first reschedule or stop timer */ if (w->repeat) { ev_at (w) += w->repeat; if (ev_at (w) < mn_now) ev_at (w) = mn_now; assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.)); ANHE_at_cache (timers [HEAP0]); downheap (timers, timercnt, HEAP0); } else ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ EV_FREQUENT_CHECK; feed_reverse (EV_A_ (W)w); } while (timercnt && ANHE_at (timers [HEAP0]) < mn_now); feed_reverse_done (EV_A_ EV_TIMER); } } #if EV_PERIODIC_ENABLE noinline static void periodic_recalc (EV_P_ ev_periodic *w) { ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL; ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval); /* the above almost always errs on the low side */ while (at <= ev_rt_now) { ev_tstamp nat = at + w->interval; /* when resolution fails us, we use ev_rt_now */ if (expect_false (nat == at)) { at = ev_rt_now; break; } at = nat; } ev_at (w) = at; } /* make periodics pending */ inline_size void periodics_reify (EV_P) { EV_FREQUENT_CHECK; while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now) { do { ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]); /*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/ /* first reschedule or stop timer */ if (w->reschedule_cb) { ev_at (w) = w->reschedule_cb (w, ev_rt_now); assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now)); ANHE_at_cache (periodics [HEAP0]); downheap (periodics, periodiccnt, HEAP0); } else if (w->interval) { periodic_recalc (EV_A_ w); ANHE_at_cache (periodics [HEAP0]); downheap (periodics, periodiccnt, HEAP0); } else ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ EV_FREQUENT_CHECK; feed_reverse (EV_A_ (W)w); } while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now); feed_reverse_done (EV_A_ EV_PERIODIC); } } /* simply recalculate all periodics */ /* TODO: maybe ensure that at least one event happens when jumping forward? */ noinline ecb_cold static void periodics_reschedule (EV_P) { int i; /* adjust periodics after time jump */ for (i = HEAP0; i < periodiccnt + HEAP0; ++i) { ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]); if (w->reschedule_cb) ev_at (w) = w->reschedule_cb (w, ev_rt_now); else if (w->interval) periodic_recalc (EV_A_ w); ANHE_at_cache (periodics [i]); } reheap (periodics, periodiccnt); } #endif /* adjust all timers by a given offset */ noinline ecb_cold static void timers_reschedule (EV_P_ ev_tstamp adjust) { int i; for (i = 0; i < timercnt; ++i) { ANHE *he = timers + i + HEAP0; ANHE_w (*he)->at += adjust; ANHE_at_cache (*he); } } /* fetch new monotonic and realtime times from the kernel */ /* also detect if there was a timejump, and act accordingly */ inline_speed void time_update (EV_P_ ev_tstamp max_block) { #if EV_USE_MONOTONIC if (expect_true (have_monotonic)) { int i; ev_tstamp odiff = rtmn_diff; mn_now = get_clock (); /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */ /* interpolate in the meantime */ if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5)) { ev_rt_now = rtmn_diff + mn_now; return; } now_floor = mn_now; ev_rt_now = ev_time (); /* loop a few times, before making important decisions. * on the choice of "4": one iteration isn't enough, * in case we get preempted during the calls to * ev_time and get_clock. a second call is almost guaranteed * to succeed in that case, though. and looping a few more times * doesn't hurt either as we only do this on time-jumps or * in the unlikely event of having been preempted here. */ for (i = 4; --i; ) { ev_tstamp diff; rtmn_diff = ev_rt_now - mn_now; diff = odiff - rtmn_diff; if (expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP)) return; /* all is well */ ev_rt_now = ev_time (); mn_now = get_clock (); now_floor = mn_now; } /* no timer adjustment, as the monotonic clock doesn't jump */ /* timers_reschedule (EV_A_ rtmn_diff - odiff) */ # if EV_PERIODIC_ENABLE periodics_reschedule (EV_A); # endif } else #endif { ev_rt_now = ev_time (); if (expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + MIN_TIMEJUMP)) { /* adjust timers. this is easy, as the offset is the same for all of them */ timers_reschedule (EV_A_ ev_rt_now - mn_now); #if EV_PERIODIC_ENABLE periodics_reschedule (EV_A); #endif } mn_now = ev_rt_now; } } int ev_run (EV_P_ int flags) { #if EV_FEATURE_API ++loop_depth; #endif assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE)); loop_done = EVBREAK_CANCEL; EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */ do { #if EV_VERIFY >= 2 ev_verify (EV_A); #endif #ifndef _WIN32 if (expect_false (curpid)) /* penalise the forking check even more */ if (expect_false (getpid () != curpid)) { curpid = getpid (); postfork = 1; } #endif #if EV_FORK_ENABLE /* we might have forked, so queue fork handlers */ if (expect_false (postfork)) if (forkcnt) { queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); EV_INVOKE_PENDING; } #endif #if EV_PREPARE_ENABLE /* queue prepare watchers (and execute them) */ if (expect_false (preparecnt)) { queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE); EV_INVOKE_PENDING; } #endif if (expect_false (loop_done)) break; /* we might have forked, so reify kernel state if necessary */ if (expect_false (postfork)) loop_fork (EV_A); /* update fd-related kernel structures */ fd_reify (EV_A); /* calculate blocking time */ { ev_tstamp waittime = 0.; ev_tstamp sleeptime = 0.; /* remember old timestamp for io_blocktime calculation */ ev_tstamp prev_mn_now = mn_now; /* update time to cancel out callback processing overhead */ time_update (EV_A_ 1e100); /* from now on, we want a pipe-wake-up */ pipe_write_wanted = 1; ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */ if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) { waittime = MAX_BLOCKTIME; if (timercnt) { ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; if (waittime > to) waittime = to; } #if EV_PERIODIC_ENABLE if (periodiccnt) { ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now; if (waittime > to) waittime = to; } #endif /* don't let timeouts decrease the waittime below timeout_blocktime */ if (expect_false (waittime < timeout_blocktime)) waittime = timeout_blocktime; /* at this point, we NEED to wait, so we have to ensure */ /* to pass a minimum nonzero value to the backend */ if (expect_false (waittime < backend_mintime)) waittime = backend_mintime; /* extra check because io_blocktime is commonly 0 */ if (expect_false (io_blocktime)) { sleeptime = io_blocktime - (mn_now - prev_mn_now); if (sleeptime > waittime - backend_mintime) sleeptime = waittime - backend_mintime; if (expect_true (sleeptime > 0.)) { ev_sleep (sleeptime); waittime -= sleeptime; } } } #if EV_FEATURE_API ++loop_count; #endif assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ backend_poll (EV_A_ waittime); assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ pipe_write_wanted = 0; /* just an optimisation, no fence needed */ ECB_MEMORY_FENCE_ACQUIRE; if (pipe_write_skipped) { assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); } /* update ev_rt_now, do magic */ time_update (EV_A_ waittime + sleeptime); } /* queue pending timers and reschedule them */ timers_reify (EV_A); /* relative timers called last */ #if EV_PERIODIC_ENABLE periodics_reify (EV_A); /* absolute timers called first */ #endif #if EV_IDLE_ENABLE /* queue idle watchers unless other events are pending */ idle_reify (EV_A); #endif #if EV_CHECK_ENABLE /* queue check watchers, to be executed first */ if (expect_false (checkcnt)) queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); #endif EV_INVOKE_PENDING; } while (expect_true ( activecnt && !loop_done && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT)) )); if (loop_done == EVBREAK_ONE) loop_done = EVBREAK_CANCEL; #if EV_FEATURE_API --loop_depth; #endif return activecnt; } void ev_break (EV_P_ int how) EV_THROW { loop_done = how; } void ev_ref (EV_P) EV_THROW { ++activecnt; } void ev_unref (EV_P) EV_THROW { --activecnt; } void ev_now_update (EV_P) EV_THROW { time_update (EV_A_ 1e100); } void ev_suspend (EV_P) EV_THROW { ev_now_update (EV_A); } void ev_resume (EV_P) EV_THROW { ev_tstamp mn_prev = mn_now; ev_now_update (EV_A); timers_reschedule (EV_A_ mn_now - mn_prev); #if EV_PERIODIC_ENABLE /* TODO: really do this? */ periodics_reschedule (EV_A); #endif } /*****************************************************************************/ /* singly-linked list management, used when the expected list length is short */ inline_size void wlist_add (WL *head, WL elem) { elem->next = *head; *head = elem; } inline_size void wlist_del (WL *head, WL elem) { while (*head) { if (expect_true (*head == elem)) { *head = elem->next; break; } head = &(*head)->next; } } /* internal, faster, version of ev_clear_pending */ inline_speed void clear_pending (EV_P_ W w) { if (w->pending) { pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w; w->pending = 0; } } int ev_clear_pending (EV_P_ void *w) EV_THROW { W w_ = (W)w; int pending = w_->pending; if (expect_true (pending)) { ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1; p->w = (W)&pending_w; w_->pending = 0; return p->events; } else return 0; } inline_size void pri_adjust (EV_P_ W w) { int pri = ev_priority (w); pri = pri < EV_MINPRI ? EV_MINPRI : pri; pri = pri > EV_MAXPRI ? EV_MAXPRI : pri; ev_set_priority (w, pri); } inline_speed void ev_start (EV_P_ W w, int active) { pri_adjust (EV_A_ w); w->active = active; ev_ref (EV_A); } inline_size void ev_stop (EV_P_ W w) { ev_unref (EV_A); w->active = 0; } /*****************************************************************************/ noinline void ev_io_start (EV_P_ ev_io *w) EV_THROW { int fd = w->fd; if (expect_false (ev_is_active (w))) return; assert (("libev: ev_io_start called with negative fd", fd >= 0)); assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, 1); array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero); wlist_add (&anfds[fd].head, (WL)w); /* common bug, apparently */ assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w)); fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY); w->events &= ~EV__IOFDSET; EV_FREQUENT_CHECK; } noinline void ev_io_stop (EV_P_ ev_io *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); EV_FREQUENT_CHECK; wlist_del (&anfds[w->fd].head, (WL)w); ev_stop (EV_A_ (W)w); fd_change (EV_A_ w->fd, EV_ANFD_REIFY); EV_FREQUENT_CHECK; } noinline void ev_timer_start (EV_P_ ev_timer *w) EV_THROW { if (expect_false (ev_is_active (w))) return; ev_at (w) += mn_now; assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.)); EV_FREQUENT_CHECK; ++timercnt; ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1); array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2); ANHE_w (timers [ev_active (w)]) = (WT)w; ANHE_at_cache (timers [ev_active (w)]); upheap (timers, ev_active (w)); EV_FREQUENT_CHECK; /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/ } noinline void ev_timer_stop (EV_P_ ev_timer *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w)); --timercnt; if (expect_true (active < timercnt + HEAP0)) { timers [active] = timers [timercnt + HEAP0]; adjustheap (timers, timercnt, active); } } ev_at (w) -= mn_now; ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } noinline void ev_timer_again (EV_P_ ev_timer *w) EV_THROW { EV_FREQUENT_CHECK; clear_pending (EV_A_ (W)w); if (ev_is_active (w)) { if (w->repeat) { ev_at (w) = mn_now + w->repeat; ANHE_at_cache (timers [ev_active (w)]); adjustheap (timers, timercnt, ev_active (w)); } else ev_timer_stop (EV_A_ w); } else if (w->repeat) { ev_at (w) = w->repeat; ev_timer_start (EV_A_ w); } EV_FREQUENT_CHECK; } ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW { return ev_at (w) - (ev_is_active (w) ? mn_now : 0.); } #if EV_PERIODIC_ENABLE noinline void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW { if (expect_false (ev_is_active (w))) return; if (w->reschedule_cb) ev_at (w) = w->reschedule_cb (w, ev_rt_now); else if (w->interval) { assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.)); periodic_recalc (EV_A_ w); } else ev_at (w) = w->offset; EV_FREQUENT_CHECK; ++periodiccnt; ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1); array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2); ANHE_w (periodics [ev_active (w)]) = (WT)w; ANHE_at_cache (periodics [ev_active (w)]); upheap (periodics, ev_active (w)); EV_FREQUENT_CHECK; /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/ } noinline void ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w)); --periodiccnt; if (expect_true (active < periodiccnt + HEAP0)) { periodics [active] = periodics [periodiccnt + HEAP0]; adjustheap (periodics, periodiccnt, active); } } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } noinline void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW { /* TODO: use adjustheap and recalculation */ ev_periodic_stop (EV_A_ w); ev_periodic_start (EV_A_ w); } #endif #ifndef SA_RESTART # define SA_RESTART 0 #endif #if EV_SIGNAL_ENABLE noinline void ev_signal_start (EV_P_ ev_signal *w) EV_THROW { if (expect_false (ev_is_active (w))) return; assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG)); #if EV_MULTIPLICITY assert (("libev: a signal must not be attached to two different loops", !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop)); signals [w->signum - 1].loop = EV_A; ECB_MEMORY_FENCE_RELEASE; #endif EV_FREQUENT_CHECK; #if EV_USE_SIGNALFD if (sigfd == -2) { sigfd = signalfd (-1, &sigfd_set, SFD_NONBLOCK | SFD_CLOEXEC); if (sigfd < 0 && errno == EINVAL) sigfd = signalfd (-1, &sigfd_set, 0); /* retry without flags */ if (sigfd >= 0) { fd_intern (sigfd); /* doing it twice will not hurt */ sigemptyset (&sigfd_set); ev_io_init (&sigfd_w, sigfdcb, sigfd, EV_READ); ev_set_priority (&sigfd_w, EV_MAXPRI); ev_io_start (EV_A_ &sigfd_w); ev_unref (EV_A); /* signalfd watcher should not keep loop alive */ } } if (sigfd >= 0) { /* TODO: check .head */ sigaddset (&sigfd_set, w->signum); sigprocmask (SIG_BLOCK, &sigfd_set, 0); signalfd (sigfd, &sigfd_set, 0); } #endif ev_start (EV_A_ (W)w, 1); wlist_add (&signals [w->signum - 1].head, (WL)w); if (!((WL)w)->next) # if EV_USE_SIGNALFD if (sigfd < 0) /*TODO*/ # endif { # ifdef _WIN32 evpipe_init (EV_A); signal (w->signum, ev_sighandler); # else struct sigaction sa; evpipe_init (EV_A); sa.sa_handler = ev_sighandler; sigfillset (&sa.sa_mask); sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */ sigaction (w->signum, &sa, 0); if (origflags & EVFLAG_NOSIGMASK) { sigemptyset (&sa.sa_mask); sigaddset (&sa.sa_mask, w->signum); sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0); } #endif } EV_FREQUENT_CHECK; } noinline void ev_signal_stop (EV_P_ ev_signal *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; wlist_del (&signals [w->signum - 1].head, (WL)w); ev_stop (EV_A_ (W)w); if (!signals [w->signum - 1].head) { #if EV_MULTIPLICITY signals [w->signum - 1].loop = 0; /* unattach from signal */ #endif #if EV_USE_SIGNALFD if (sigfd >= 0) { sigset_t ss; sigemptyset (&ss); sigaddset (&ss, w->signum); sigdelset (&sigfd_set, w->signum); signalfd (sigfd, &sigfd_set, 0); sigprocmask (SIG_UNBLOCK, &ss, 0); } else #endif signal (w->signum, SIG_DFL); } EV_FREQUENT_CHECK; } #endif #if EV_CHILD_ENABLE void ev_child_start (EV_P_ ev_child *w) EV_THROW { #if EV_MULTIPLICITY assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr)); #endif if (expect_false (ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, 1); wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); EV_FREQUENT_CHECK; } void ev_child_stop (EV_P_ ev_child *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_STAT_ENABLE # ifdef _WIN32 # undef lstat # define lstat(a,b) _stati64 (a,b) # endif #define DEF_STAT_INTERVAL 5.0074891 #define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */ #define MIN_STAT_INTERVAL 0.1074891 noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents); #if EV_USE_INOTIFY /* the * 2 is to allow for alignment padding, which for some reason is >> 8 */ # define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX) noinline static void infy_add (EV_P_ ev_stat *w) { w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_DONT_FOLLOW | IN_MASK_ADD); if (w->wd >= 0) { struct statfs sfs; /* now local changes will be tracked by inotify, but remote changes won't */ /* unless the filesystem is known to be local, we therefore still poll */ /* also do poll on <2.6.25, but with normal frequency */ if (!fs_2625) w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; else if (!statfs (w->path, &sfs) && (sfs.f_type == 0x1373 /* devfs */ || sfs.f_type == 0x4006 /* fat */ || sfs.f_type == 0x4d44 /* msdos */ || sfs.f_type == 0xEF53 /* ext2/3 */ || sfs.f_type == 0x72b6 /* jffs2 */ || sfs.f_type == 0x858458f6 /* ramfs */ || sfs.f_type == 0x5346544e /* ntfs */ || sfs.f_type == 0x3153464a /* jfs */ || sfs.f_type == 0x9123683e /* btrfs */ || sfs.f_type == 0x52654973 /* reiser3 */ || sfs.f_type == 0x01021994 /* tmpfs */ || sfs.f_type == 0x58465342 /* xfs */)) w->timer.repeat = 0.; /* filesystem is local, kernel new enough */ else w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */ } else { /* can't use inotify, continue to stat */ w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; /* if path is not there, monitor some parent directory for speedup hints */ /* note that exceeding the hardcoded path limit is not a correctness issue, */ /* but an efficiency issue only */ if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096) { char path [4096]; strcpy (path, w->path); do { int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF | (errno == EACCES ? IN_ATTRIB : IN_CREATE | IN_MOVED_TO); char *pend = strrchr (path, '/'); if (!pend || pend == path) break; *pend = 0; w->wd = inotify_add_watch (fs_fd, path, mask); } while (w->wd < 0 && (errno == ENOENT || errno == EACCES)); } } if (w->wd >= 0) wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); /* now re-arm timer, if required */ if (ev_is_active (&w->timer)) ev_ref (EV_A); ev_timer_again (EV_A_ &w->timer); if (ev_is_active (&w->timer)) ev_unref (EV_A); } noinline static void infy_del (EV_P_ ev_stat *w) { int slot; int wd = w->wd; if (wd < 0) return; w->wd = -2; slot = wd & ((EV_INOTIFY_HASHSIZE) - 1); wlist_del (&fs_hash [slot].head, (WL)w); /* remove this watcher, if others are watching it, they will rearm */ inotify_rm_watch (fs_fd, wd); } noinline static void infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev) { if (slot < 0) /* overflow, need to check for all hash slots */ for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) infy_wd (EV_A_ slot, wd, ev); else { WL w_; for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; ) { ev_stat *w = (ev_stat *)w_; w_ = w_->next; /* lets us remove this watcher and all before it */ if (w->wd == wd || wd == -1) { if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF)) { wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); w->wd = -1; infy_add (EV_A_ w); /* re-add, no matter what */ } stat_timer_cb (EV_A_ &w->timer, 0); } } } } static void infy_cb (EV_P_ ev_io *w, int revents) { char buf [EV_INOTIFY_BUFSIZE]; int ofs; int len = read (fs_fd, buf, sizeof (buf)); for (ofs = 0; ofs < len; ) { struct inotify_event *ev = (struct inotify_event *)(buf + ofs); infy_wd (EV_A_ ev->wd, ev->wd, ev); ofs += sizeof (struct inotify_event) + ev->len; } } inline_size ecb_cold void ev_check_2625 (EV_P) { /* kernels < 2.6.25 are borked * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html */ if (ev_linux_version () < 0x020619) return; fs_2625 = 1; } inline_size int infy_newfd (void) { #if defined IN_CLOEXEC && defined IN_NONBLOCK int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK); if (fd >= 0) return fd; #endif return inotify_init (); } inline_size void infy_init (EV_P) { if (fs_fd != -2) return; fs_fd = -1; ev_check_2625 (EV_A); fs_fd = infy_newfd (); if (fs_fd >= 0) { fd_intern (fs_fd); ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ); ev_set_priority (&fs_w, EV_MAXPRI); ev_io_start (EV_A_ &fs_w); ev_unref (EV_A); } } inline_size void infy_fork (EV_P) { int slot; if (fs_fd < 0) return; ev_ref (EV_A); ev_io_stop (EV_A_ &fs_w); close (fs_fd); fs_fd = infy_newfd (); if (fs_fd >= 0) { fd_intern (fs_fd); ev_io_set (&fs_w, fs_fd, EV_READ); ev_io_start (EV_A_ &fs_w); ev_unref (EV_A); } for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) { WL w_ = fs_hash [slot].head; fs_hash [slot].head = 0; while (w_) { ev_stat *w = (ev_stat *)w_; w_ = w_->next; /* lets us add this watcher */ w->wd = -1; if (fs_fd >= 0) infy_add (EV_A_ w); /* re-add, no matter what */ else { w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; if (ev_is_active (&w->timer)) ev_ref (EV_A); ev_timer_again (EV_A_ &w->timer); if (ev_is_active (&w->timer)) ev_unref (EV_A); } } } } #endif #ifdef _WIN32 # define EV_LSTAT(p,b) _stati64 (p, b) #else # define EV_LSTAT(p,b) lstat (p, b) #endif void ev_stat_stat (EV_P_ ev_stat *w) EV_THROW { if (lstat (w->path, &w->attr) < 0) w->attr.st_nlink = 0; else if (!w->attr.st_nlink) w->attr.st_nlink = 1; } noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents) { ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer)); ev_statdata prev = w->attr; ev_stat_stat (EV_A_ w); /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */ if ( prev.st_dev != w->attr.st_dev || prev.st_ino != w->attr.st_ino || prev.st_mode != w->attr.st_mode || prev.st_nlink != w->attr.st_nlink || prev.st_uid != w->attr.st_uid || prev.st_gid != w->attr.st_gid || prev.st_rdev != w->attr.st_rdev || prev.st_size != w->attr.st_size || prev.st_atime != w->attr.st_atime || prev.st_mtime != w->attr.st_mtime || prev.st_ctime != w->attr.st_ctime ) { /* we only update w->prev on actual differences */ /* in case we test more often than invoke the callback, */ /* to ensure that prev is always different to attr */ w->prev = prev; #if EV_USE_INOTIFY if (fs_fd >= 0) { infy_del (EV_A_ w); infy_add (EV_A_ w); ev_stat_stat (EV_A_ w); /* avoid race... */ } #endif ev_feed_event (EV_A_ w, EV_STAT); } } void ev_stat_start (EV_P_ ev_stat *w) EV_THROW { if (expect_false (ev_is_active (w))) return; ev_stat_stat (EV_A_ w); if (w->interval < MIN_STAT_INTERVAL && w->interval) w->interval = MIN_STAT_INTERVAL; ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL); ev_set_priority (&w->timer, ev_priority (w)); #if EV_USE_INOTIFY infy_init (EV_A); if (fs_fd >= 0) infy_add (EV_A_ w); else #endif { ev_timer_again (EV_A_ &w->timer); ev_unref (EV_A); } ev_start (EV_A_ (W)w, 1); EV_FREQUENT_CHECK; } void ev_stat_stop (EV_P_ ev_stat *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; #if EV_USE_INOTIFY infy_del (EV_A_ w); #endif if (ev_is_active (&w->timer)) { ev_ref (EV_A); ev_timer_stop (EV_A_ &w->timer); } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_IDLE_ENABLE void ev_idle_start (EV_P_ ev_idle *w) EV_THROW { if (expect_false (ev_is_active (w))) return; pri_adjust (EV_A_ (W)w); EV_FREQUENT_CHECK; { int active = ++idlecnt [ABSPRI (w)]; ++idleall; ev_start (EV_A_ (W)w, active); array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2); idles [ABSPRI (w)][active - 1] = w; } EV_FREQUENT_CHECK; } void ev_idle_stop (EV_P_ ev_idle *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]]; ev_active (idles [ABSPRI (w)][active - 1]) = active; ev_stop (EV_A_ (W)w); --idleall; } EV_FREQUENT_CHECK; } #endif #if EV_PREPARE_ENABLE void ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW { if (expect_false (ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, ++preparecnt); array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2); prepares [preparecnt - 1] = w; EV_FREQUENT_CHECK; } void ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); prepares [active - 1] = prepares [--preparecnt]; ev_active (prepares [active - 1]) = active; } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_CHECK_ENABLE void ev_check_start (EV_P_ ev_check *w) EV_THROW { if (expect_false (ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, ++checkcnt); array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2); checks [checkcnt - 1] = w; EV_FREQUENT_CHECK; } void ev_check_stop (EV_P_ ev_check *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); checks [active - 1] = checks [--checkcnt]; ev_active (checks [active - 1]) = active; } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_EMBED_ENABLE noinline void ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW { ev_run (w->other, EVRUN_NOWAIT); } static void embed_io_cb (EV_P_ ev_io *io, int revents) { ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io)); if (ev_cb (w)) ev_feed_event (EV_A_ (W)w, EV_EMBED); else ev_run (w->other, EVRUN_NOWAIT); } static void embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents) { ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare)); { EV_P = w->other; while (fdchangecnt) { fd_reify (EV_A); ev_run (EV_A_ EVRUN_NOWAIT); } } } static void embed_fork_cb (EV_P_ ev_fork *fork_w, int revents) { ev_embed *w = (ev_embed *)(((char *)fork_w) - offsetof (ev_embed, fork)); ev_embed_stop (EV_A_ w); { EV_P = w->other; ev_loop_fork (EV_A); ev_run (EV_A_ EVRUN_NOWAIT); } ev_embed_start (EV_A_ w); } #if 0 static void embed_idle_cb (EV_P_ ev_idle *idle, int revents) { ev_idle_stop (EV_A_ idle); } #endif void ev_embed_start (EV_P_ ev_embed *w) EV_THROW { if (expect_false (ev_is_active (w))) return; { EV_P = w->other; assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ())); ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ); } EV_FREQUENT_CHECK; ev_set_priority (&w->io, ev_priority (w)); ev_io_start (EV_A_ &w->io); ev_prepare_init (&w->prepare, embed_prepare_cb); ev_set_priority (&w->prepare, EV_MINPRI); ev_prepare_start (EV_A_ &w->prepare); ev_fork_init (&w->fork, embed_fork_cb); ev_fork_start (EV_A_ &w->fork); /*ev_idle_init (&w->idle, e,bed_idle_cb);*/ ev_start (EV_A_ (W)w, 1); EV_FREQUENT_CHECK; } void ev_embed_stop (EV_P_ ev_embed *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_io_stop (EV_A_ &w->io); ev_prepare_stop (EV_A_ &w->prepare); ev_fork_stop (EV_A_ &w->fork); ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_FORK_ENABLE void ev_fork_start (EV_P_ ev_fork *w) EV_THROW { if (expect_false (ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, ++forkcnt); array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2); forks [forkcnt - 1] = w; EV_FREQUENT_CHECK; } void ev_fork_stop (EV_P_ ev_fork *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); forks [active - 1] = forks [--forkcnt]; ev_active (forks [active - 1]) = active; } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_CLEANUP_ENABLE void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW { if (expect_false (ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, ++cleanupcnt); array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2); cleanups [cleanupcnt - 1] = w; /* cleanup watchers should never keep a refcount on the loop */ ev_unref (EV_A); EV_FREQUENT_CHECK; } void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; ev_ref (EV_A); { int active = ev_active (w); cleanups [active - 1] = cleanups [--cleanupcnt]; ev_active (cleanups [active - 1]) = active; } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } #endif #if EV_ASYNC_ENABLE void ev_async_start (EV_P_ ev_async *w) EV_THROW { if (expect_false (ev_is_active (w))) return; w->sent = 0; evpipe_init (EV_A); EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, ++asynccnt); array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2); asyncs [asynccnt - 1] = w; EV_FREQUENT_CHECK; } void ev_async_stop (EV_P_ ev_async *w) EV_THROW { clear_pending (EV_A_ (W)w); if (expect_false (!ev_is_active (w))) return; EV_FREQUENT_CHECK; { int active = ev_active (w); asyncs [active - 1] = asyncs [--asynccnt]; ev_active (asyncs [active - 1]) = active; } ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } void ev_async_send (EV_P_ ev_async *w) EV_THROW { w->sent = 1; evpipe_write (EV_A_ &async_pending); } #endif /*****************************************************************************/ struct ev_once { ev_io io; ev_timer to; void (*cb)(int revents, void *arg); void *arg; }; static void once_cb (EV_P_ struct ev_once *once, int revents) { void (*cb)(int revents, void *arg) = once->cb; void *arg = once->arg; ev_io_stop (EV_A_ &once->io); ev_timer_stop (EV_A_ &once->to); ev_free (once); cb (revents, arg); } static void once_cb_io (EV_P_ ev_io *w, int revents) { struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io)); once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->to)); } static void once_cb_to (EV_P_ ev_timer *w, int revents) { struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to)); once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->io)); } void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW { struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once)); if (expect_false (!once)) { cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg); return; } once->cb = cb; once->arg = arg; ev_init (&once->io, once_cb_io); if (fd >= 0) { ev_io_set (&once->io, fd, events); ev_io_start (EV_A_ &once->io); } ev_init (&once->to, once_cb_to); if (timeout >= 0.) { ev_timer_set (&once->to, timeout, 0.); ev_timer_start (EV_A_ &once->to); } } /*****************************************************************************/ #if EV_WALK_ENABLE ecb_cold void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW { int i, j; ev_watcher_list *wl, *wn; if (types & (EV_IO | EV_EMBED)) for (i = 0; i < anfdmax; ++i) for (wl = anfds [i].head; wl; ) { wn = wl->next; #if EV_EMBED_ENABLE if (ev_cb ((ev_io *)wl) == embed_io_cb) { if (types & EV_EMBED) cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io)); } else #endif #if EV_USE_INOTIFY if (ev_cb ((ev_io *)wl) == infy_cb) ; else #endif if ((ev_io *)wl != &pipe_w) if (types & EV_IO) cb (EV_A_ EV_IO, wl); wl = wn; } if (types & (EV_TIMER | EV_STAT)) for (i = timercnt + HEAP0; i-- > HEAP0; ) #if EV_STAT_ENABLE /*TODO: timer is not always active*/ if (ev_cb ((ev_timer *)ANHE_w (timers [i])) == stat_timer_cb) { if (types & EV_STAT) cb (EV_A_ EV_STAT, ((char *)ANHE_w (timers [i])) - offsetof (struct ev_stat, timer)); } else #endif if (types & EV_TIMER) cb (EV_A_ EV_TIMER, ANHE_w (timers [i])); #if EV_PERIODIC_ENABLE if (types & EV_PERIODIC) for (i = periodiccnt + HEAP0; i-- > HEAP0; ) cb (EV_A_ EV_PERIODIC, ANHE_w (periodics [i])); #endif #if EV_IDLE_ENABLE if (types & EV_IDLE) for (j = NUMPRI; j--; ) for (i = idlecnt [j]; i--; ) cb (EV_A_ EV_IDLE, idles [j][i]); #endif #if EV_FORK_ENABLE if (types & EV_FORK) for (i = forkcnt; i--; ) if (ev_cb (forks [i]) != embed_fork_cb) cb (EV_A_ EV_FORK, forks [i]); #endif #if EV_ASYNC_ENABLE if (types & EV_ASYNC) for (i = asynccnt; i--; ) cb (EV_A_ EV_ASYNC, asyncs [i]); #endif #if EV_PREPARE_ENABLE if (types & EV_PREPARE) for (i = preparecnt; i--; ) # if EV_EMBED_ENABLE if (ev_cb (prepares [i]) != embed_prepare_cb) # endif cb (EV_A_ EV_PREPARE, prepares [i]); #endif #if EV_CHECK_ENABLE if (types & EV_CHECK) for (i = checkcnt; i--; ) cb (EV_A_ EV_CHECK, checks [i]); #endif #if EV_SIGNAL_ENABLE if (types & EV_SIGNAL) for (i = 0; i < EV_NSIG - 1; ++i) for (wl = signals [i].head; wl; ) { wn = wl->next; cb (EV_A_ EV_SIGNAL, wl); wl = wn; } #endif #if EV_CHILD_ENABLE if (types & EV_CHILD) for (i = (EV_PID_HASHSIZE); i--; ) for (wl = childs [i]; wl; ) { wn = wl->next; cb (EV_A_ EV_CHILD, wl); wl = wn; } #endif /* EV_STAT 0x00001000 /* stat data changed */ /* EV_EMBED 0x00010000 /* embedded event loop needs sweep */ } #endif #if EV_MULTIPLICITY #include "ev_wrap.h" #endif gvpe-3.0/libev/ev.h0000644000000000000000000007146012725447135011112 00000000000000/* * libev native API header * * Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef EV_H_ #define EV_H_ #ifdef __cplusplus # define EV_CPP(x) x # if __cplusplus >= 201103L # define EV_THROW noexcept # else # define EV_THROW throw () # endif #else # define EV_CPP(x) # define EV_THROW #endif EV_CPP(extern "C" {) /*****************************************************************************/ /* pre-4.0 compatibility */ #ifndef EV_COMPAT3 # define EV_COMPAT3 1 #endif #ifndef EV_FEATURES # if defined __OPTIMIZE_SIZE__ # define EV_FEATURES 0x7c # else # define EV_FEATURES 0x7f # endif #endif #define EV_FEATURE_CODE ((EV_FEATURES) & 1) #define EV_FEATURE_DATA ((EV_FEATURES) & 2) #define EV_FEATURE_CONFIG ((EV_FEATURES) & 4) #define EV_FEATURE_API ((EV_FEATURES) & 8) #define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16) #define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32) #define EV_FEATURE_OS ((EV_FEATURES) & 64) /* these priorities are inclusive, higher priorities will be invoked earlier */ #ifndef EV_MINPRI # define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0) #endif #ifndef EV_MAXPRI # define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0) #endif #ifndef EV_MULTIPLICITY # define EV_MULTIPLICITY EV_FEATURE_CONFIG #endif #ifndef EV_PERIODIC_ENABLE # define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_STAT_ENABLE # define EV_STAT_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_PREPARE_ENABLE # define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_CHECK_ENABLE # define EV_CHECK_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_IDLE_ENABLE # define EV_IDLE_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_FORK_ENABLE # define EV_FORK_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_CLEANUP_ENABLE # define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_SIGNAL_ENABLE # define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_CHILD_ENABLE # ifdef _WIN32 # define EV_CHILD_ENABLE 0 # else # define EV_CHILD_ENABLE EV_FEATURE_WATCHERS #endif #endif #ifndef EV_ASYNC_ENABLE # define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_EMBED_ENABLE # define EV_EMBED_ENABLE EV_FEATURE_WATCHERS #endif #ifndef EV_WALK_ENABLE # define EV_WALK_ENABLE 0 /* not yet */ #endif /*****************************************************************************/ #if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE # undef EV_SIGNAL_ENABLE # define EV_SIGNAL_ENABLE 1 #endif /*****************************************************************************/ typedef double ev_tstamp; #include /* for memmove */ #ifndef EV_ATOMIC_T # include # define EV_ATOMIC_T sig_atomic_t volatile #endif #if EV_STAT_ENABLE # ifdef _WIN32 # include # include # endif # include #endif /* support multiple event loops? */ #if EV_MULTIPLICITY struct ev_loop; # define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */ # define EV_P_ EV_P, /* a loop as first of multiple parameters */ # define EV_A loop /* a loop as sole argument to a function call */ # define EV_A_ EV_A, /* a loop as first of multiple arguments */ # define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */ # define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */ # define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */ # define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */ #else # define EV_P void # define EV_P_ # define EV_A # define EV_A_ # define EV_DEFAULT # define EV_DEFAULT_ # define EV_DEFAULT_UC # define EV_DEFAULT_UC_ # undef EV_EMBED_ENABLE #endif /* EV_INLINE is used for functions in header files */ #if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 # define EV_INLINE static inline #else # define EV_INLINE static #endif #ifdef EV_API_STATIC # define EV_API_DECL static #else # define EV_API_DECL extern #endif /* EV_PROTOTYPES can be used to switch of prototype declarations */ #ifndef EV_PROTOTYPES # define EV_PROTOTYPES 1 #endif /*****************************************************************************/ #define EV_VERSION_MAJOR 4 #define EV_VERSION_MINOR 22 /* eventmask, revents, events... */ enum { EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */ EV_NONE = 0x00, /* no events */ EV_READ = 0x01, /* ev_io detected read will not block */ EV_WRITE = 0x02, /* ev_io detected write will not block */ EV__IOFDSET = 0x80, /* internal use only */ EV_IO = EV_READ, /* alias for type-detection */ EV_TIMER = 0x00000100, /* timer timed out */ #if EV_COMPAT3 EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */ #endif EV_PERIODIC = 0x00000200, /* periodic timer timed out */ EV_SIGNAL = 0x00000400, /* signal was received */ EV_CHILD = 0x00000800, /* child/pid had status change */ EV_STAT = 0x00001000, /* stat data changed */ EV_IDLE = 0x00002000, /* event loop is idling */ EV_PREPARE = 0x00004000, /* event loop about to poll */ EV_CHECK = 0x00008000, /* event loop finished poll */ EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ EV_FORK = 0x00020000, /* event loop resumed in child */ EV_CLEANUP = 0x00040000, /* event loop resumed in child */ EV_ASYNC = 0x00080000, /* async intra-loop signal */ EV_CUSTOM = 0x01000000, /* for use by user code */ EV_ERROR = (int)0x80000000 /* sent when an error occurs */ }; /* can be used to add custom fields to all watchers, while losing binary compatibility */ #ifndef EV_COMMON # define EV_COMMON void *data; #endif #ifndef EV_CB_DECLARE # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents); #endif #ifndef EV_CB_INVOKE # define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents)) #endif /* not official, do not use */ #define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents) /* * struct member types: * private: you may look at them, but not change them, * and they might not mean anything to you. * ro: can be read anytime, but only changed when the watcher isn't active. * rw: can be read and modified anytime, even when the watcher is active. * * some internal details that might be helpful for debugging: * * active is either 0, which means the watcher is not active, * or the array index of the watcher (periodics, timers) * or the array index + 1 (most other watchers) * or simply 1 for watchers that aren't in some array. * pending is either 0, in which case the watcher isn't, * or the array index + 1 in the pendings array. */ #if EV_MINPRI == EV_MAXPRI # define EV_DECL_PRIORITY #elif !defined (EV_DECL_PRIORITY) # define EV_DECL_PRIORITY int priority; #endif /* shared by all watchers */ #define EV_WATCHER(type) \ int active; /* private */ \ int pending; /* private */ \ EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */ #define EV_WATCHER_LIST(type) \ EV_WATCHER (type) \ struct ev_watcher_list *next; /* private */ #define EV_WATCHER_TIME(type) \ EV_WATCHER (type) \ ev_tstamp at; /* private */ /* base class, nothing to see here unless you subclass */ typedef struct ev_watcher { EV_WATCHER (ev_watcher) } ev_watcher; /* base class, nothing to see here unless you subclass */ typedef struct ev_watcher_list { EV_WATCHER_LIST (ev_watcher_list) } ev_watcher_list; /* base class, nothing to see here unless you subclass */ typedef struct ev_watcher_time { EV_WATCHER_TIME (ev_watcher_time) } ev_watcher_time; /* invoked when fd is either EV_READable or EV_WRITEable */ /* revent EV_READ, EV_WRITE */ typedef struct ev_io { EV_WATCHER_LIST (ev_io) int fd; /* ro */ int events; /* ro */ } ev_io; /* invoked after a specific time, repeatable (based on monotonic clock) */ /* revent EV_TIMEOUT */ typedef struct ev_timer { EV_WATCHER_TIME (ev_timer) ev_tstamp repeat; /* rw */ } ev_timer; /* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */ /* revent EV_PERIODIC */ typedef struct ev_periodic { EV_WATCHER_TIME (ev_periodic) ev_tstamp offset; /* rw */ ev_tstamp interval; /* rw */ ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */ } ev_periodic; /* invoked when the given signal has been received */ /* revent EV_SIGNAL */ typedef struct ev_signal { EV_WATCHER_LIST (ev_signal) int signum; /* ro */ } ev_signal; /* invoked when sigchld is received and waitpid indicates the given pid */ /* revent EV_CHILD */ /* does not support priorities */ typedef struct ev_child { EV_WATCHER_LIST (ev_child) int flags; /* private */ int pid; /* ro */ int rpid; /* rw, holds the received pid */ int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */ } ev_child; #if EV_STAT_ENABLE /* st_nlink = 0 means missing file or other error */ # ifdef _WIN32 typedef struct _stati64 ev_statdata; # else typedef struct stat ev_statdata; # endif /* invoked each time the stat data changes for a given path */ /* revent EV_STAT */ typedef struct ev_stat { EV_WATCHER_LIST (ev_stat) ev_timer timer; /* private */ ev_tstamp interval; /* ro */ const char *path; /* ro */ ev_statdata prev; /* ro */ ev_statdata attr; /* ro */ int wd; /* wd for inotify, fd for kqueue */ } ev_stat; #endif #if EV_IDLE_ENABLE /* invoked when the nothing else needs to be done, keeps the process from blocking */ /* revent EV_IDLE */ typedef struct ev_idle { EV_WATCHER (ev_idle) } ev_idle; #endif /* invoked for each run of the mainloop, just before the blocking call */ /* you can still change events in any way you like */ /* revent EV_PREPARE */ typedef struct ev_prepare { EV_WATCHER (ev_prepare) } ev_prepare; /* invoked for each run of the mainloop, just after the blocking call */ /* revent EV_CHECK */ typedef struct ev_check { EV_WATCHER (ev_check) } ev_check; #if EV_FORK_ENABLE /* the callback gets invoked before check in the child process when a fork was detected */ /* revent EV_FORK */ typedef struct ev_fork { EV_WATCHER (ev_fork) } ev_fork; #endif #if EV_CLEANUP_ENABLE /* is invoked just before the loop gets destroyed */ /* revent EV_CLEANUP */ typedef struct ev_cleanup { EV_WATCHER (ev_cleanup) } ev_cleanup; #endif #if EV_EMBED_ENABLE /* used to embed an event loop inside another */ /* the callback gets invoked when the event loop has handled events, and can be 0 */ typedef struct ev_embed { EV_WATCHER (ev_embed) struct ev_loop *other; /* ro */ ev_io io; /* private */ ev_prepare prepare; /* private */ ev_check check; /* unused */ ev_timer timer; /* unused */ ev_periodic periodic; /* unused */ ev_idle idle; /* unused */ ev_fork fork; /* private */ #if EV_CLEANUP_ENABLE ev_cleanup cleanup; /* unused */ #endif } ev_embed; #endif #if EV_ASYNC_ENABLE /* invoked when somebody calls ev_async_send on the watcher */ /* revent EV_ASYNC */ typedef struct ev_async { EV_WATCHER (ev_async) EV_ATOMIC_T sent; /* private */ } ev_async; # define ev_async_pending(w) (+(w)->sent) #endif /* the presence of this union forces similar struct layout */ union ev_any_watcher { struct ev_watcher w; struct ev_watcher_list wl; struct ev_io io; struct ev_timer timer; struct ev_periodic periodic; struct ev_signal signal; struct ev_child child; #if EV_STAT_ENABLE struct ev_stat stat; #endif #if EV_IDLE_ENABLE struct ev_idle idle; #endif struct ev_prepare prepare; struct ev_check check; #if EV_FORK_ENABLE struct ev_fork fork; #endif #if EV_CLEANUP_ENABLE struct ev_cleanup cleanup; #endif #if EV_EMBED_ENABLE struct ev_embed embed; #endif #if EV_ASYNC_ENABLE struct ev_async async; #endif }; /* flag bits for ev_default_loop and ev_loop_new */ enum { /* the default */ EVFLAG_AUTO = 0x00000000U, /* not quite a mask */ /* flag bits */ EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */ EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */ /* debugging/feature disable */ EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */ #if EV_COMPAT3 EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */ #endif EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */ EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */ }; /* method bits to be ored together */ enum { EVBACKEND_SELECT = 0x00000001U, /* available just about anywhere */ EVBACKEND_POLL = 0x00000002U, /* !win, !aix, broken on osx */ EVBACKEND_EPOLL = 0x00000004U, /* linux */ EVBACKEND_KQUEUE = 0x00000008U, /* bsd, broken on osx */ EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */ EVBACKEND_PORT = 0x00000020U, /* solaris 10 */ EVBACKEND_ALL = 0x0000003FU, /* all known backends */ EVBACKEND_MASK = 0x0000FFFFU /* all future backends */ }; #if EV_PROTOTYPES EV_API_DECL int ev_version_major (void) EV_THROW; EV_API_DECL int ev_version_minor (void) EV_THROW; EV_API_DECL unsigned int ev_supported_backends (void) EV_THROW; EV_API_DECL unsigned int ev_recommended_backends (void) EV_THROW; EV_API_DECL unsigned int ev_embeddable_backends (void) EV_THROW; EV_API_DECL ev_tstamp ev_time (void) EV_THROW; EV_API_DECL void ev_sleep (ev_tstamp delay) EV_THROW; /* sleep for a while */ /* Sets the allocation function to use, works like realloc. * It is used to allocate and free memory. * If it returns zero when memory needs to be allocated, the library might abort * or take some potentially destructive action. * The default is your system realloc function. */ EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW; /* set the callback function to call on a * retryable syscall error * (such as failed select, poll, epoll_wait) */ EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW; #if EV_MULTIPLICITY /* the default loop is the only one that handles signals and child watchers */ /* you can call this as often as you like */ EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; #ifdef EV_API_STATIC EV_API_DECL struct ev_loop *ev_default_loop_ptr; #endif EV_INLINE struct ev_loop * ev_default_loop_uc_ (void) EV_THROW { extern struct ev_loop *ev_default_loop_ptr; return ev_default_loop_ptr; } EV_INLINE int ev_is_default_loop (EV_P) EV_THROW { return EV_A == EV_DEFAULT_UC; } /* create and destroy alternative loops that don't handle signals */ EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_THROW; EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */ #else EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; /* returns true when successful */ EV_API_DECL ev_tstamp ev_rt_now; EV_INLINE ev_tstamp ev_now (void) EV_THROW { return ev_rt_now; } /* looks weird, but ev_is_default_loop (EV_A) still works if this exists */ EV_INLINE int ev_is_default_loop (void) EV_THROW { return 1; } #endif /* multiplicity */ /* destroy event loops, also works for the default loop */ EV_API_DECL void ev_loop_destroy (EV_P); /* this needs to be called after fork, to duplicate the loop */ /* when you want to re-use it in the child */ /* you can call it in either the parent or the child */ /* you can actually call it at any time, anywhere :) */ EV_API_DECL void ev_loop_fork (EV_P) EV_THROW; EV_API_DECL unsigned int ev_backend (EV_P) EV_THROW; /* backend in use by loop */ EV_API_DECL void ev_now_update (EV_P) EV_THROW; /* update event loop time */ #if EV_WALK_ENABLE /* walk (almost) all watchers in the loop of a given type, invoking the */ /* callback on every such watcher. The callback might stop the watcher, */ /* but do nothing else with the loop */ EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW; #endif #endif /* prototypes */ /* ev_run flags values */ enum { EVRUN_NOWAIT = 1, /* do not block/wait */ EVRUN_ONCE = 2 /* block *once* only */ }; /* ev_break how values */ enum { EVBREAK_CANCEL = 0, /* undo unloop */ EVBREAK_ONE = 1, /* unloop once */ EVBREAK_ALL = 2 /* unloop all loops */ }; #if EV_PROTOTYPES EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0)); EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_THROW; /* break out of the loop */ /* * ref/unref can be used to add or remove a refcount on the mainloop. every watcher * keeps one reference. if you have a long-running watcher you never unregister that * should not keep ev_loop from running, unref() after starting, and ref() before stopping. */ EV_API_DECL void ev_ref (EV_P) EV_THROW; EV_API_DECL void ev_unref (EV_P) EV_THROW; /* * convenience function, wait for a single event, without registering an event watcher * if timeout is < 0, do wait indefinitely */ EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW; # if EV_FEATURE_API EV_API_DECL unsigned int ev_iteration (EV_P) EV_THROW; /* number of loop iterations */ EV_API_DECL unsigned int ev_depth (EV_P) EV_THROW; /* #ev_loop enters - #ev_loop leaves */ EV_API_DECL void ev_verify (EV_P) EV_THROW; /* abort if loop data corrupted */ EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */ EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */ /* advanced stuff for threading etc. support, see docs */ EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW; EV_API_DECL void *ev_userdata (EV_P) EV_THROW; typedef void (*ev_loop_callback)(EV_P); EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW; /* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */ EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW; EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */ EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */ /* * stop/start the timer handling. */ EV_API_DECL void ev_suspend (EV_P) EV_THROW; EV_API_DECL void ev_resume (EV_P) EV_THROW; #endif #endif /* these may evaluate ev multiple times, and the other arguments at most once */ /* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */ #define ev_init(ev,cb_) do { \ ((ev_watcher *)(void *)(ev))->active = \ ((ev_watcher *)(void *)(ev))->pending = 0; \ ev_set_priority ((ev), 0); \ ev_set_cb ((ev), cb_); \ } while (0) #define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0) #define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0) #define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0) #define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0) #define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0) #define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0) #define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_check_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0) #define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_async_set(ev) /* nop, yes, this is a serious in-joke */ #define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0) #define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0) #define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0) #define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0) #define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0) #define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0) #define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0) #define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0) #define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0) #define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0) #define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0) #define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0) #define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0) #define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */ #define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */ #define ev_cb_(ev) (ev)->cb /* rw */ #define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb) #if EV_MINPRI == EV_MAXPRI # define ev_priority(ev) ((ev), EV_MINPRI) # define ev_set_priority(ev,pri) ((ev), (pri)) #else # define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority)) # define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri) #endif #define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at) #ifndef ev_set_cb # define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev)))) #endif /* stopping (enabling, adding) a watcher does nothing if it is already running */ /* stopping (disabling, deleting) a watcher does nothing unless it's already running */ #if EV_PROTOTYPES /* feeds an event into a watcher as if the event actually occurred */ /* accepts any ev_watcher type */ EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_THROW; EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW; #if EV_SIGNAL_ENABLE EV_API_DECL void ev_feed_signal (int signum) EV_THROW; EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_THROW; #endif EV_API_DECL void ev_invoke (EV_P_ void *w, int revents); EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_THROW; EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_THROW; EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_THROW; EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_THROW; EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_THROW; /* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */ EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_THROW; /* return remaining time */ EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW; #if EV_PERIODIC_ENABLE EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW; EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW; EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW; #endif /* only supported in the default loop */ #if EV_SIGNAL_ENABLE EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_THROW; EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_THROW; #endif /* only supported in the default loop */ # if EV_CHILD_ENABLE EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_THROW; EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_THROW; # endif # if EV_STAT_ENABLE EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_THROW; EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_THROW; EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_THROW; # endif # if EV_IDLE_ENABLE EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_THROW; EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_THROW; # endif #if EV_PREPARE_ENABLE EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW; EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW; #endif #if EV_CHECK_ENABLE EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_THROW; EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_THROW; #endif # if EV_FORK_ENABLE EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_THROW; EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_THROW; # endif # if EV_CLEANUP_ENABLE EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW; EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW; # endif # if EV_EMBED_ENABLE /* only supported when loop to be embedded is in fact embeddable */ EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_THROW; EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_THROW; EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW; # endif # if EV_ASYNC_ENABLE EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_THROW; EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_THROW; EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_THROW; # endif #if EV_COMPAT3 #define EVLOOP_NONBLOCK EVRUN_NOWAIT #define EVLOOP_ONESHOT EVRUN_ONCE #define EVUNLOOP_CANCEL EVBREAK_CANCEL #define EVUNLOOP_ONE EVBREAK_ONE #define EVUNLOOP_ALL EVBREAK_ALL #if EV_PROTOTYPES EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); } EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); } EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); } EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); } #if EV_FEATURE_API EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); } EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); } EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); } #endif #endif #else typedef struct ev_loop ev_loop; #endif #endif EV_CPP(}) #endif gvpe-3.0/libev/libev.m40000644000000000000000000000304012337443634011656 00000000000000dnl this file is part of libev, do not make local modifications dnl http://software.schmorp.de/pkg/libev dnl libev support AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h) AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd) AC_CHECK_FUNCS(clock_gettime, [], [ dnl on linux, try syscall wrapper first if test $(uname) = Linux; then AC_MSG_CHECKING(for clock_gettime syscall) AC_LINK_IFELSE([AC_LANG_PROGRAM( [#include #include #include ], [struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])], [ac_have_clock_syscall=1 AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, Define to 1 to use the syscall interface for clock_gettime) AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) fi if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then AC_CHECK_LIB(rt, clock_gettime) unset ac_cv_func_clock_gettime AC_CHECK_FUNCS(clock_gettime) fi ]) AC_CHECK_FUNCS(nanosleep, [], [ if test -z "$LIBEV_M4_AVOID_LIBRT"; then AC_CHECK_LIB(rt, nanosleep) unset ac_cv_func_nanosleep AC_CHECK_FUNCS(nanosleep) fi ]) if test -z "$LIBEV_M4_AVOID_LIBM"; then LIBM=m fi AC_SEARCH_LIBS(floor, $LIBM, [AC_DEFINE(HAVE_FLOOR, 1, Define to 1 if the floor function is available)]) gvpe-3.0/libev/ev++.h0000644000000000000000000004773712544251217011243 00000000000000/* * libev simple C++ wrapper classes * * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef EVPP_H__ #define EVPP_H__ #ifdef EV_H # include EV_H #else # include "ev.h" #endif #ifndef EV_USE_STDEXCEPT # define EV_USE_STDEXCEPT 1 #endif #if EV_USE_STDEXCEPT # include #endif namespace ev { typedef ev_tstamp tstamp; enum { UNDEF = EV_UNDEF, NONE = EV_NONE, READ = EV_READ, WRITE = EV_WRITE, #if EV_COMPAT3 TIMEOUT = EV_TIMEOUT, #endif TIMER = EV_TIMER, PERIODIC = EV_PERIODIC, SIGNAL = EV_SIGNAL, CHILD = EV_CHILD, STAT = EV_STAT, IDLE = EV_IDLE, CHECK = EV_CHECK, PREPARE = EV_PREPARE, FORK = EV_FORK, ASYNC = EV_ASYNC, EMBED = EV_EMBED, # undef ERROR // some systems stupidly #define ERROR ERROR = EV_ERROR }; enum { AUTO = EVFLAG_AUTO, NOENV = EVFLAG_NOENV, FORKCHECK = EVFLAG_FORKCHECK, SELECT = EVBACKEND_SELECT, POLL = EVBACKEND_POLL, EPOLL = EVBACKEND_EPOLL, KQUEUE = EVBACKEND_KQUEUE, DEVPOLL = EVBACKEND_DEVPOLL, PORT = EVBACKEND_PORT }; enum { #if EV_COMPAT3 NONBLOCK = EVLOOP_NONBLOCK, ONESHOT = EVLOOP_ONESHOT, #endif NOWAIT = EVRUN_NOWAIT, ONCE = EVRUN_ONCE }; enum how_t { ONE = EVBREAK_ONE, ALL = EVBREAK_ALL }; struct bad_loop #if EV_USE_STDEXCEPT : std::runtime_error #endif { #if EV_USE_STDEXCEPT bad_loop () : std::runtime_error ("libev event loop cannot be initialized, bad value of LIBEV_FLAGS?") { } #endif }; #ifdef EV_AX # undef EV_AX #endif #ifdef EV_AX_ # undef EV_AX_ #endif #if EV_MULTIPLICITY # define EV_AX raw_loop # define EV_AX_ raw_loop, #else # define EV_AX # define EV_AX_ #endif struct loop_ref { loop_ref (EV_P) throw () #if EV_MULTIPLICITY : EV_AX (EV_A) #endif { } bool operator == (const loop_ref &other) const throw () { #if EV_MULTIPLICITY return EV_AX == other.EV_AX; #else return true; #endif } bool operator != (const loop_ref &other) const throw () { #if EV_MULTIPLICITY return ! (*this == other); #else return false; #endif } #if EV_MULTIPLICITY bool operator == (const EV_P) const throw () { return this->EV_AX == EV_A; } bool operator != (const EV_P) const throw () { return (*this == EV_A); } operator struct ev_loop * () const throw () { return EV_AX; } operator const struct ev_loop * () const throw () { return EV_AX; } bool is_default () const throw () { return EV_AX == ev_default_loop (0); } #endif #if EV_COMPAT3 void loop (int flags = 0) { ev_run (EV_AX_ flags); } void unloop (how_t how = ONE) throw () { ev_break (EV_AX_ how); } #endif void run (int flags = 0) { ev_run (EV_AX_ flags); } void break_loop (how_t how = ONE) throw () { ev_break (EV_AX_ how); } void post_fork () throw () { ev_loop_fork (EV_AX); } unsigned int backend () const throw () { return ev_backend (EV_AX); } tstamp now () const throw () { return ev_now (EV_AX); } void ref () throw () { ev_ref (EV_AX); } void unref () throw () { ev_unref (EV_AX); } #if EV_FEATURE_API unsigned int iteration () const throw () { return ev_iteration (EV_AX); } unsigned int depth () const throw () { return ev_depth (EV_AX); } void set_io_collect_interval (tstamp interval) throw () { ev_set_io_collect_interval (EV_AX_ interval); } void set_timeout_collect_interval (tstamp interval) throw () { ev_set_timeout_collect_interval (EV_AX_ interval); } #endif // function callback void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) throw () { ev_once (EV_AX_ fd, events, timeout, cb, arg); } // method callback template void once (int fd, int events, tstamp timeout, K *object) throw () { once (fd, events, timeout, method_thunk, object); } // default method == operator () template void once (int fd, int events, tstamp timeout, K *object) throw () { once (fd, events, timeout, method_thunk, object); } template static void method_thunk (int revents, void *arg) { (static_cast(arg)->*method) (revents); } // no-argument method callback template void once (int fd, int events, tstamp timeout, K *object) throw () { once (fd, events, timeout, method_noargs_thunk, object); } template static void method_noargs_thunk (int revents, void *arg) { (static_cast(arg)->*method) (); } // simpler function callback template void once (int fd, int events, tstamp timeout) throw () { once (fd, events, timeout, simpler_func_thunk); } template static void simpler_func_thunk (int revents, void *arg) { (*cb) (revents); } // simplest function callback template void once (int fd, int events, tstamp timeout) throw () { once (fd, events, timeout, simplest_func_thunk); } template static void simplest_func_thunk (int revents, void *arg) { (*cb) (); } void feed_fd_event (int fd, int revents) throw () { ev_feed_fd_event (EV_AX_ fd, revents); } void feed_signal_event (int signum) throw () { ev_feed_signal_event (EV_AX_ signum); } #if EV_MULTIPLICITY struct ev_loop* EV_AX; #endif }; #if EV_MULTIPLICITY struct dynamic_loop : loop_ref { dynamic_loop (unsigned int flags = AUTO) throw (bad_loop) : loop_ref (ev_loop_new (flags)) { if (!EV_AX) throw bad_loop (); } ~dynamic_loop () throw () { ev_loop_destroy (EV_AX); EV_AX = 0; } private: dynamic_loop (const dynamic_loop &); dynamic_loop & operator= (const dynamic_loop &); }; #endif struct default_loop : loop_ref { default_loop (unsigned int flags = AUTO) throw (bad_loop) #if EV_MULTIPLICITY : loop_ref (ev_default_loop (flags)) #endif { if ( #if EV_MULTIPLICITY !EV_AX #else !ev_default_loop (flags) #endif ) throw bad_loop (); } private: default_loop (const default_loop &); default_loop &operator = (const default_loop &); }; inline loop_ref get_default_loop () throw () { #if EV_MULTIPLICITY return ev_default_loop (0); #else return loop_ref (); #endif } #undef EV_AX #undef EV_AX_ #undef EV_PX #undef EV_PX_ #if EV_MULTIPLICITY # define EV_PX loop_ref EV_A # define EV_PX_ loop_ref EV_A_ #else # define EV_PX # define EV_PX_ #endif template struct base : ev_watcher { #if EV_MULTIPLICITY EV_PX; // loop set void set (EV_P) throw () { this->EV_A = EV_A; } #endif base (EV_PX) throw () #if EV_MULTIPLICITY : EV_A (EV_A) #endif { ev_init (this, 0); } void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw () { this->data = (void *)data; ev_set_cb (static_cast(this), cb); } // function callback template void set (void *data = 0) throw () { set_ (data, function_thunk); } template static void function_thunk (EV_P_ ev_watcher *w, int revents) { function (*static_cast(w), revents); } // method callback template void set (K *object) throw () { set_ (object, method_thunk); } // default method == operator () template void set (K *object) throw () { set_ (object, method_thunk); } template static void method_thunk (EV_P_ ev_watcher *w, int revents) { (static_cast(w->data)->*method) (*static_cast(w), revents); } // no-argument callback template void set (K *object) throw () { set_ (object, method_noargs_thunk); } template static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents) { (static_cast(w->data)->*method) (); } void operator ()(int events = EV_UNDEF) { return ev_cb (static_cast(this)) (static_cast(this), events); } bool is_active () const throw () { return ev_is_active (static_cast(this)); } bool is_pending () const throw () { return ev_is_pending (static_cast(this)); } void feed_event (int revents) throw () { ev_feed_event (EV_A_ static_cast(this), revents); } }; inline tstamp now (EV_P) throw () { return ev_now (EV_A); } inline void delay (tstamp interval) throw () { ev_sleep (interval); } inline int version_major () throw () { return ev_version_major (); } inline int version_minor () throw () { return ev_version_minor (); } inline unsigned int supported_backends () throw () { return ev_supported_backends (); } inline unsigned int recommended_backends () throw () { return ev_recommended_backends (); } inline unsigned int embeddable_backends () throw () { return ev_embeddable_backends (); } inline void set_allocator (void *(*cb)(void *ptr, long size) throw ()) throw () { ev_set_allocator (cb); } inline void set_syserr_cb (void (*cb)(const char *msg) throw ()) throw () { ev_set_syserr_cb (cb); } #if EV_MULTIPLICITY #define EV_CONSTRUCT(cppstem,cstem) \ (EV_PX = get_default_loop ()) throw () \ : base (EV_A) \ { \ } #else #define EV_CONSTRUCT(cppstem,cstem) \ () throw () \ { \ } #endif /* using a template here would require quite a few more lines, * so a macro solution was chosen */ #define EV_BEGIN_WATCHER(cppstem,cstem) \ \ struct cppstem : base \ { \ void start () throw () \ { \ ev_ ## cstem ## _start (EV_A_ static_cast(this)); \ } \ \ void stop () throw () \ { \ ev_ ## cstem ## _stop (EV_A_ static_cast(this)); \ } \ \ cppstem EV_CONSTRUCT(cppstem,cstem) \ \ ~cppstem () throw () \ { \ stop (); \ } \ \ using base::set; \ \ private: \ \ cppstem (const cppstem &o); \ \ cppstem &operator =(const cppstem &o); \ \ public: #define EV_END_WATCHER(cppstem,cstem) \ }; EV_BEGIN_WATCHER (io, io) void set (int fd, int events) throw () { int active = is_active (); if (active) stop (); ev_io_set (static_cast(this), fd, events); if (active) start (); } void set (int events) throw () { int active = is_active (); if (active) stop (); ev_io_set (static_cast(this), fd, events); if (active) start (); } void start (int fd, int events) throw () { set (fd, events); start (); } EV_END_WATCHER (io, io) EV_BEGIN_WATCHER (timer, timer) void set (ev_tstamp after, ev_tstamp repeat = 0.) throw () { int active = is_active (); if (active) stop (); ev_timer_set (static_cast(this), after, repeat); if (active) start (); } void start (ev_tstamp after, ev_tstamp repeat = 0.) throw () { set (after, repeat); start (); } void again () throw () { ev_timer_again (EV_A_ static_cast(this)); } ev_tstamp remaining () { return ev_timer_remaining (EV_A_ static_cast(this)); } EV_END_WATCHER (timer, timer) #if EV_PERIODIC_ENABLE EV_BEGIN_WATCHER (periodic, periodic) void set (ev_tstamp at, ev_tstamp interval = 0.) throw () { int active = is_active (); if (active) stop (); ev_periodic_set (static_cast(this), at, interval, 0); if (active) start (); } void start (ev_tstamp at, ev_tstamp interval = 0.) throw () { set (at, interval); start (); } void again () throw () { ev_periodic_again (EV_A_ static_cast(this)); } EV_END_WATCHER (periodic, periodic) #endif #if EV_SIGNAL_ENABLE EV_BEGIN_WATCHER (sig, signal) void set (int signum) throw () { int active = is_active (); if (active) stop (); ev_signal_set (static_cast(this), signum); if (active) start (); } void start (int signum) throw () { set (signum); start (); } EV_END_WATCHER (sig, signal) #endif #if EV_CHILD_ENABLE EV_BEGIN_WATCHER (child, child) void set (int pid, int trace = 0) throw () { int active = is_active (); if (active) stop (); ev_child_set (static_cast(this), pid, trace); if (active) start (); } void start (int pid, int trace = 0) throw () { set (pid, trace); start (); } EV_END_WATCHER (child, child) #endif #if EV_STAT_ENABLE EV_BEGIN_WATCHER (stat, stat) void set (const char *path, ev_tstamp interval = 0.) throw () { int active = is_active (); if (active) stop (); ev_stat_set (static_cast(this), path, interval); if (active) start (); } void start (const char *path, ev_tstamp interval = 0.) throw () { stop (); set (path, interval); start (); } void update () throw () { ev_stat_stat (EV_A_ static_cast(this)); } EV_END_WATCHER (stat, stat) #endif #if EV_IDLE_ENABLE EV_BEGIN_WATCHER (idle, idle) void set () throw () { } EV_END_WATCHER (idle, idle) #endif #if EV_PREPARE_ENABLE EV_BEGIN_WATCHER (prepare, prepare) void set () throw () { } EV_END_WATCHER (prepare, prepare) #endif #if EV_CHECK_ENABLE EV_BEGIN_WATCHER (check, check) void set () throw () { } EV_END_WATCHER (check, check) #endif #if EV_EMBED_ENABLE EV_BEGIN_WATCHER (embed, embed) void set_embed (struct ev_loop *embedded_loop) throw () { int active = is_active (); if (active) stop (); ev_embed_set (static_cast(this), embedded_loop); if (active) start (); } void start (struct ev_loop *embedded_loop) throw () { set (embedded_loop); start (); } void sweep () { ev_embed_sweep (EV_A_ static_cast(this)); } EV_END_WATCHER (embed, embed) #endif #if EV_FORK_ENABLE EV_BEGIN_WATCHER (fork, fork) void set () throw () { } EV_END_WATCHER (fork, fork) #endif #if EV_ASYNC_ENABLE EV_BEGIN_WATCHER (async, async) void send () throw () { ev_async_send (EV_A_ static_cast(this)); } bool async_pending () throw () { return ev_async_pending (static_cast(this)); } EV_END_WATCHER (async, async) #endif #undef EV_PX #undef EV_PX_ #undef EV_CONSTRUCT #undef EV_BEGIN_WATCHER #undef EV_END_WATCHER } #endif gvpe-3.0/libev/ev_epoll.c0000644000000000000000000002321612661245652012273 00000000000000/* * libev epoll fd activity backend * * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ /* * general notes about epoll: * * a) epoll silently removes fds from the fd set. as nothing tells us * that an fd has been removed otherwise, we have to continually * "rearm" fds that we suspect *might* have changed (same * problem with kqueue, but much less costly there). * b) the fact that ADD != MOD creates a lot of extra syscalls due to a) * and seems not to have any advantage. * c) the inability to handle fork or file descriptors (think dup) * limits the applicability over poll, so this is not a generic * poll replacement. * d) epoll doesn't work the same as select with many file descriptors * (such as files). while not critical, no other advanced interface * seems to share this (rather non-unixy) limitation. * e) epoll claims to be embeddable, but in practise you never get * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32). * f) epoll_ctl returning EPERM means the fd is always ready. * * lots of "weird code" and complication handling in this file is due * to these design problems with epoll, as we try very hard to avoid * epoll_ctl syscalls for common usage patterns and handle the breakage * ensuing from receiving events for closed and otherwise long gone * file descriptors. */ #include #define EV_EMASK_EPERM 0x80 static void epoll_modify (EV_P_ int fd, int oev, int nev) { struct epoll_event ev; unsigned char oldmask; /* * we handle EPOLL_CTL_DEL by ignoring it here * on the assumption that the fd is gone anyways * if that is wrong, we have to handle the spurious * event in epoll_poll. * if the fd is added again, we try to ADD it, and, if that * fails, we assume it still has the same eventmask. */ if (!nev) return; oldmask = anfds [fd].emask; anfds [fd].emask = nev; /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */ ev.data.u64 = (uint64_t)(uint32_t)fd | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); ev.events = (nev & EV_READ ? EPOLLIN : 0) | (nev & EV_WRITE ? EPOLLOUT : 0); if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) return; if (expect_true (errno == ENOENT)) { /* if ENOENT then the fd went away, so try to do the right thing */ if (!nev) goto dec_egen; if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev)) return; } else if (expect_true (errno == EEXIST)) { /* EEXIST means we ignored a previous DEL, but the fd is still active */ /* if the kernel mask is the same as the new mask, we assume it hasn't changed */ if (oldmask == nev) goto dec_egen; if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev)) return; } else if (expect_true (errno == EPERM)) { /* EPERM means the fd is always ready, but epoll is too snobbish */ /* to handle it, unlike select or poll. */ anfds [fd].emask = EV_EMASK_EPERM; /* add fd to epoll_eperms, if not already inside */ if (!(oldmask & EV_EMASK_EPERM)) { array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2); epoll_eperms [epoll_epermcnt++] = fd; } return; } fd_kill (EV_A_ fd); dec_egen: /* we didn't successfully call epoll_ctl, so decrement the generation counter again */ --anfds [fd].egen; } static void epoll_poll (EV_P_ ev_tstamp timeout) { int i; int eventcnt; if (expect_false (epoll_epermcnt)) timeout = 0.; /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */ /* the default libev max wait time, however. */ EV_RELEASE_CB; eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, timeout * 1e3); EV_ACQUIRE_CB; if (expect_false (eventcnt < 0)) { if (errno != EINTR) ev_syserr ("(libev) epoll_wait"); return; } for (i = 0; i < eventcnt; ++i) { struct epoll_event *ev = epoll_events + i; int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ int want = anfds [fd].events; int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); /* * check for spurious notification. * this only finds spurious notifications on egen updates * other spurious notifications will be found by epoll_ctl, below * we assume that fd is always in range, as we never shrink the anfds array */ if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) { /* recreate kernel state */ postfork |= 2; continue; } if (expect_false (got & ~want)) { anfds [fd].emask = want; /* * we received an event but are not interested in it, try mod or del * this often happens because we optimistically do not unregister fds * when we are no longer interested in them, but also when we get spurious * notifications for fds from another process. this is partially handled * above with the gencounter check (== our fd is not the event fd), and * partially here, when epoll_ctl returns an error (== a child has the fd * but we closed it). */ ev->events = (want & EV_READ ? EPOLLIN : 0) | (want & EV_WRITE ? EPOLLOUT : 0); /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ /* which is fortunately easy to do for us. */ if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) { postfork |= 2; /* an error occurred, recreate kernel state */ continue; } } fd_event (EV_A_ fd, got); } /* if the receive array was full, increase its size */ if (expect_false (eventcnt == epoll_eventmax)) { ev_free (epoll_events); epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1); epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); } /* now synthesize events for all fds where epoll fails, while select works... */ for (i = epoll_epermcnt; i--; ) { int fd = epoll_eperms [i]; unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); if (anfds [fd].emask & EV_EMASK_EPERM && events) fd_event (EV_A_ fd, events); else { epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; anfds [fd].emask = 0; } } } inline_size int epoll_init (EV_P_ int flags) { #ifdef EPOLL_CLOEXEC backend_fd = epoll_create1 (EPOLL_CLOEXEC); if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS)) #endif backend_fd = epoll_create (256); if (backend_fd < 0) return 0; fcntl (backend_fd, F_SETFD, FD_CLOEXEC); backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */ backend_modify = epoll_modify; backend_poll = epoll_poll; epoll_eventmax = 64; /* initial number of events receivable per poll */ epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); return EVBACKEND_EPOLL; } inline_size void epoll_destroy (EV_P) { ev_free (epoll_events); array_free (epoll_eperm, EMPTY); } inline_size void epoll_fork (EV_P) { close (backend_fd); while ((backend_fd = epoll_create (256)) < 0) ev_syserr ("(libev) epoll_create"); fcntl (backend_fd, F_SETFD, FD_CLOEXEC); fd_rearm_all (EV_A); } gvpe-3.0/libev/ev_kqueue.c0000644000000000000000000001523212661245707012457 00000000000000/* * libev kqueue backend * * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #include #include #include #include #include inline_speed void kqueue_change (EV_P_ int fd, int filter, int flags, int fflags) { ++kqueue_changecnt; array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, EMPTY2); EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0); } /* OS X at least needs this */ #ifndef EV_ENABLE # define EV_ENABLE 0 #endif #ifndef NOTE_EOF # define NOTE_EOF 0 #endif static void kqueue_modify (EV_P_ int fd, int oev, int nev) { if (oev != nev) { if (oev & EV_READ) kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0); if (oev & EV_WRITE) kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0); } /* to detect close/reopen reliably, we have to re-add */ /* event requests even when oev == nev */ if (nev & EV_READ) kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF); if (nev & EV_WRITE) kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF); } static void kqueue_poll (EV_P_ ev_tstamp timeout) { int res, i; struct timespec ts; /* need to resize so there is enough space for errors */ if (kqueue_changecnt > kqueue_eventmax) { ev_free (kqueue_events); kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt); kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); } EV_RELEASE_CB; EV_TS_SET (ts, timeout); res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts); EV_ACQUIRE_CB; kqueue_changecnt = 0; if (expect_false (res < 0)) { if (errno != EINTR) ev_syserr ("(libev) kevent"); return; } for (i = 0; i < res; ++i) { int fd = kqueue_events [i].ident; if (expect_false (kqueue_events [i].flags & EV_ERROR)) { int err = kqueue_events [i].data; /* we are only interested in errors for fds that we are interested in :) */ if (anfds [fd].events) { if (err == ENOENT) /* resubmit changes on ENOENT */ kqueue_modify (EV_A_ fd, 0, anfds [fd].events); else if (err == EBADF) /* on EBADF, we re-check the fd */ { if (fd_valid (fd)) kqueue_modify (EV_A_ fd, 0, anfds [fd].events); else fd_kill (EV_A_ fd); } else /* on all other errors, we error out on the fd */ fd_kill (EV_A_ fd); } } else fd_event ( EV_A_ fd, kqueue_events [i].filter == EVFILT_READ ? EV_READ : kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE : 0 ); } if (expect_false (res == kqueue_eventmax)) { ev_free (kqueue_events); kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1); kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); } } inline_size int kqueue_init (EV_P_ int flags) { /* initialize the kernel queue */ kqueue_fd_pid = getpid (); if ((backend_fd = kqueue ()) < 0) return 0; fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */ backend_mintime = 1e-9; /* apparently, they did the right thing in freebsd */ backend_modify = kqueue_modify; backend_poll = kqueue_poll; kqueue_eventmax = 64; /* initial number of events receivable per poll */ kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); kqueue_changes = 0; kqueue_changemax = 0; kqueue_changecnt = 0; return EVBACKEND_KQUEUE; } inline_size void kqueue_destroy (EV_P) { ev_free (kqueue_events); ev_free (kqueue_changes); } inline_size void kqueue_fork (EV_P) { /* some BSD kernels don't just destroy the kqueue itself, * but also close the fd, which isn't documented, and * impossible to support properly. * we remember the pid of the kqueue call and only close * the fd if the pid is still the same. * this leaks fds on sane kernels, but BSD interfaces are * notoriously buggy and rarely get fixed. */ pid_t newpid = getpid (); if (newpid == kqueue_fd_pid) close (backend_fd); kqueue_fd_pid = newpid; while ((backend_fd = kqueue ()) < 0) ev_syserr ("(libev) kqueue"); fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* re-register interest in fds */ fd_rearm_all (EV_A); } /* sys/event.h defines EV_ERROR */ #undef EV_ERROR gvpe-3.0/libev/ev_poll.c0000644000000000000000000001053312661245726012126 00000000000000/* * libev poll fd activity backend * * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #include inline_size void pollidx_init (int *base, int count) { /* consider using memset (.., -1, ...), which is practically guaranteed * to work on all systems implementing poll */ while (count--) *base++ = -1; } static void poll_modify (EV_P_ int fd, int oev, int nev) { int idx; if (oev == nev) return; array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init); idx = pollidxs [fd]; if (idx < 0) /* need to allocate a new pollfd */ { pollidxs [fd] = idx = pollcnt++; array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2); polls [idx].fd = fd; } assert (polls [idx].fd == fd); if (nev) polls [idx].events = (nev & EV_READ ? POLLIN : 0) | (nev & EV_WRITE ? POLLOUT : 0); else /* remove pollfd */ { pollidxs [fd] = -1; if (expect_true (idx < --pollcnt)) { polls [idx] = polls [pollcnt]; pollidxs [polls [idx].fd] = idx; } } } static void poll_poll (EV_P_ ev_tstamp timeout) { struct pollfd *p; int res; EV_RELEASE_CB; res = poll (polls, pollcnt, timeout * 1e3); EV_ACQUIRE_CB; if (expect_false (res < 0)) { if (errno == EBADF) fd_ebadf (EV_A); else if (errno == ENOMEM && !syserr_cb) fd_enomem (EV_A); else if (errno != EINTR) ev_syserr ("(libev) poll"); } else for (p = polls; res; ++p) { assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt)); if (expect_false (p->revents)) /* this expect is debatable */ { --res; if (expect_false (p->revents & POLLNVAL)) fd_kill (EV_A_ p->fd); else fd_event ( EV_A_ p->fd, (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) ); } } } inline_size int poll_init (EV_P_ int flags) { backend_mintime = 1e-3; backend_modify = poll_modify; backend_poll = poll_poll; pollidxs = 0; pollidxmax = 0; polls = 0; pollmax = 0; pollcnt = 0; return EVBACKEND_POLL; } inline_size void poll_destroy (EV_P) { ev_free (pollidxs); ev_free (polls); } gvpe-3.0/libev/ev_select.c0000644000000000000000000002115512661245773012443 00000000000000/* * libev select fd activity backend * * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef _WIN32 /* for unix systems */ # include # ifndef __hpux /* for REAL unix systems */ # include # endif #endif #ifndef EV_SELECT_USE_FD_SET # ifdef NFDBITS # define EV_SELECT_USE_FD_SET 0 # else # define EV_SELECT_USE_FD_SET 1 # endif #endif #if EV_SELECT_IS_WINSOCKET # undef EV_SELECT_USE_FD_SET # define EV_SELECT_USE_FD_SET 1 # undef NFDBITS # define NFDBITS 0 #endif #if !EV_SELECT_USE_FD_SET # define NFDBYTES (NFDBITS / 8) #endif #include static void select_modify (EV_P_ int fd, int oev, int nev) { if (oev == nev) return; { #if EV_SELECT_USE_FD_SET #if EV_SELECT_IS_WINSOCKET SOCKET handle = anfds [fd].handle; #else int handle = fd; #endif assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE)); /* FD_SET is broken on windows (it adds the fd to a set twice or more, * which eventually leads to overflows). Need to call it only on changes. */ #if EV_SELECT_IS_WINSOCKET if ((oev ^ nev) & EV_READ) #endif if (nev & EV_READ) FD_SET (handle, (fd_set *)vec_ri); else FD_CLR (handle, (fd_set *)vec_ri); #if EV_SELECT_IS_WINSOCKET if ((oev ^ nev) & EV_WRITE) #endif if (nev & EV_WRITE) FD_SET (handle, (fd_set *)vec_wi); else FD_CLR (handle, (fd_set *)vec_wi); #else int word = fd / NFDBITS; fd_mask mask = 1UL << (fd % NFDBITS); if (expect_false (vec_max <= word)) { int new_max = word + 1; vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES); vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */ vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES); vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */ #ifdef _WIN32 vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */ #endif for (; vec_max < new_max; ++vec_max) ((fd_mask *)vec_ri) [vec_max] = ((fd_mask *)vec_wi) [vec_max] = 0; } ((fd_mask *)vec_ri) [word] |= mask; if (!(nev & EV_READ)) ((fd_mask *)vec_ri) [word] &= ~mask; ((fd_mask *)vec_wi) [word] |= mask; if (!(nev & EV_WRITE)) ((fd_mask *)vec_wi) [word] &= ~mask; #endif } } static void select_poll (EV_P_ ev_tstamp timeout) { struct timeval tv; int res; int fd_setsize; EV_RELEASE_CB; EV_TV_SET (tv, timeout); #if EV_SELECT_USE_FD_SET fd_setsize = sizeof (fd_set); #else fd_setsize = vec_max * NFDBYTES; #endif memcpy (vec_ro, vec_ri, fd_setsize); memcpy (vec_wo, vec_wi, fd_setsize); #ifdef _WIN32 /* pass in the write set as except set. * the idea behind this is to work around a windows bug that causes * errors to be reported as an exception and not by setting * the writable bit. this is so uncontrollably lame. */ memcpy (vec_eo, vec_wi, fd_setsize); res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv); #elif EV_SELECT_USE_FD_SET fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE; res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); #else res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); #endif EV_ACQUIRE_CB; if (expect_false (res < 0)) { #if EV_SELECT_IS_WINSOCKET errno = WSAGetLastError (); #endif #ifdef WSABASEERR /* on windows, select returns incompatible error codes, fix this */ if (errno >= WSABASEERR && errno < WSABASEERR + 1000) if (errno == WSAENOTSOCK) errno = EBADF; else errno -= WSABASEERR; #endif #ifdef _WIN32 /* select on windows erroneously returns EINVAL when no fd sets have been * provided (this is documented). what microsoft doesn't tell you that this bug * exists even when the fd sets _are_ provided, so we have to check for this bug * here and emulate by sleeping manually. * we also get EINVAL when the timeout is invalid, but we ignore this case here * and assume that EINVAL always means: you have to wait manually. */ if (errno == EINVAL) { if (timeout) { unsigned long ms = timeout * 1e3; Sleep (ms ? ms : 1); } return; } #endif if (errno == EBADF) fd_ebadf (EV_A); else if (errno == ENOMEM && !syserr_cb) fd_enomem (EV_A); else if (errno != EINTR) ev_syserr ("(libev) select"); return; } #if EV_SELECT_USE_FD_SET { int fd; for (fd = 0; fd < anfdmax; ++fd) if (anfds [fd].events) { int events = 0; #if EV_SELECT_IS_WINSOCKET SOCKET handle = anfds [fd].handle; #else int handle = fd; #endif if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ; if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE; #ifdef _WIN32 if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE; #endif if (expect_true (events)) fd_event (EV_A_ fd, events); } } #else { int word, bit; for (word = vec_max; word--; ) { fd_mask word_r = ((fd_mask *)vec_ro) [word]; fd_mask word_w = ((fd_mask *)vec_wo) [word]; #ifdef _WIN32 word_w |= ((fd_mask *)vec_eo) [word]; #endif if (word_r || word_w) for (bit = NFDBITS; bit--; ) { fd_mask mask = 1UL << bit; int events = 0; events |= word_r & mask ? EV_READ : 0; events |= word_w & mask ? EV_WRITE : 0; if (expect_true (events)) fd_event (EV_A_ word * NFDBITS + bit, events); } } } #endif } inline_size int select_init (EV_P_ int flags) { backend_mintime = 1e-6; backend_modify = select_modify; backend_poll = select_poll; #if EV_SELECT_USE_FD_SET vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri); vec_ro = ev_malloc (sizeof (fd_set)); vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi); vec_wo = ev_malloc (sizeof (fd_set)); #ifdef _WIN32 vec_eo = ev_malloc (sizeof (fd_set)); #endif #else vec_max = 0; vec_ri = 0; vec_ro = 0; vec_wi = 0; vec_wo = 0; #ifdef _WIN32 vec_eo = 0; #endif #endif return EVBACKEND_SELECT; } inline_size void select_destroy (EV_P) { ev_free (vec_ri); ev_free (vec_ro); ev_free (vec_wi); ev_free (vec_wo); #ifdef _WIN32 ev_free (vec_eo); #endif } gvpe-3.0/libev/ev_vars.h0000644000000000000000000001412512403673005012126 00000000000000/* * loop member variable declarations * * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #define VARx(type,name) VAR(name, type name) VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */ VARx(ev_tstamp, mn_now) /* monotonic clock "now" */ VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */ /* for reverse feeding of events */ VARx(W *, rfeeds) VARx(int, rfeedmax) VARx(int, rfeedcnt) VAR (pendings, ANPENDING *pendings [NUMPRI]) VAR (pendingmax, int pendingmax [NUMPRI]) VAR (pendingcnt, int pendingcnt [NUMPRI]) VARx(int, pendingpri) /* highest priority currently pending */ VARx(ev_prepare, pending_w) /* dummy pending watcher */ VARx(ev_tstamp, io_blocktime) VARx(ev_tstamp, timeout_blocktime) VARx(int, backend) VARx(int, activecnt) /* total number of active events ("refcount") */ VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */ VARx(int, backend_fd) VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */ VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev)) VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout)) VARx(ANFD *, anfds) VARx(int, anfdmax) VAR (evpipe, int evpipe [2]) VARx(ev_io, pipe_w) VARx(EV_ATOMIC_T, pipe_write_wanted) VARx(EV_ATOMIC_T, pipe_write_skipped) #if !defined(_WIN32) || EV_GENWRAP VARx(pid_t, curpid) #endif VARx(char, postfork) /* true if we need to recreate kernel state after fork */ #if EV_USE_SELECT || EV_GENWRAP VARx(void *, vec_ri) VARx(void *, vec_ro) VARx(void *, vec_wi) VARx(void *, vec_wo) #if defined(_WIN32) || EV_GENWRAP VARx(void *, vec_eo) #endif VARx(int, vec_max) #endif #if EV_USE_POLL || EV_GENWRAP VARx(struct pollfd *, polls) VARx(int, pollmax) VARx(int, pollcnt) VARx(int *, pollidxs) /* maps fds into structure indices */ VARx(int, pollidxmax) #endif #if EV_USE_EPOLL || EV_GENWRAP VARx(struct epoll_event *, epoll_events) VARx(int, epoll_eventmax) VARx(int *, epoll_eperms) VARx(int, epoll_epermcnt) VARx(int, epoll_epermmax) #endif #if EV_USE_KQUEUE || EV_GENWRAP VARx(pid_t, kqueue_fd_pid) VARx(struct kevent *, kqueue_changes) VARx(int, kqueue_changemax) VARx(int, kqueue_changecnt) VARx(struct kevent *, kqueue_events) VARx(int, kqueue_eventmax) #endif #if EV_USE_PORT || EV_GENWRAP VARx(struct port_event *, port_events) VARx(int, port_eventmax) #endif #if EV_USE_IOCP || EV_GENWRAP VARx(HANDLE, iocp) #endif VARx(int *, fdchanges) VARx(int, fdchangemax) VARx(int, fdchangecnt) VARx(ANHE *, timers) VARx(int, timermax) VARx(int, timercnt) #if EV_PERIODIC_ENABLE || EV_GENWRAP VARx(ANHE *, periodics) VARx(int, periodicmax) VARx(int, periodiccnt) #endif #if EV_IDLE_ENABLE || EV_GENWRAP VAR (idles, ev_idle **idles [NUMPRI]) VAR (idlemax, int idlemax [NUMPRI]) VAR (idlecnt, int idlecnt [NUMPRI]) #endif VARx(int, idleall) /* total number */ VARx(struct ev_prepare **, prepares) VARx(int, preparemax) VARx(int, preparecnt) VARx(struct ev_check **, checks) VARx(int, checkmax) VARx(int, checkcnt) #if EV_FORK_ENABLE || EV_GENWRAP VARx(struct ev_fork **, forks) VARx(int, forkmax) VARx(int, forkcnt) #endif #if EV_CLEANUP_ENABLE || EV_GENWRAP VARx(struct ev_cleanup **, cleanups) VARx(int, cleanupmax) VARx(int, cleanupcnt) #endif #if EV_ASYNC_ENABLE || EV_GENWRAP VARx(EV_ATOMIC_T, async_pending) VARx(struct ev_async **, asyncs) VARx(int, asyncmax) VARx(int, asynccnt) #endif #if EV_USE_INOTIFY || EV_GENWRAP VARx(int, fs_fd) VARx(ev_io, fs_w) VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */ VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE]) #endif VARx(EV_ATOMIC_T, sig_pending) #if EV_USE_SIGNALFD || EV_GENWRAP VARx(int, sigfd) VARx(ev_io, sigfd_w) VARx(sigset_t, sigfd_set) #endif VARx(unsigned int, origflags) /* original loop flags */ #if EV_FEATURE_API || EV_GENWRAP VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */ VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */ VARx(void *, userdata) /* C++ doesn't support the ev_loop_callback typedef here. stinks. */ VAR (release_cb, void (*release_cb)(EV_P) EV_THROW) VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW) VAR (invoke_cb , ev_loop_callback invoke_cb) #endif #undef VARx gvpe-3.0/libev/ev_win32.c0000644000000000000000000001231012621034613012100 00000000000000/* * libev win32 compatibility cruft (_not_ a backend) * * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifdef _WIN32 /* note: the comment below could not be substantiated, but what would I care */ /* MSDN says this is required to handle SIGFPE */ /* my wild guess would be that using something floating-pointy is required */ /* for the crt to do something about it */ volatile double SIGFPE_REQ = 0.0f; static SOCKET ev_tcp_socket (void) { #if EV_USE_WSASOCKET return WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0); #else return socket (AF_INET, SOCK_STREAM, 0); #endif } /* oh, the humanity! */ static int ev_pipe (int filedes [2]) { struct sockaddr_in addr = { 0 }; int addr_size = sizeof (addr); struct sockaddr_in adr2; int adr2_size = sizeof (adr2); SOCKET listener; SOCKET sock [2] = { -1, -1 }; if ((listener = ev_tcp_socket ()) == INVALID_SOCKET) return -1; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); addr.sin_port = 0; if (bind (listener, (struct sockaddr *)&addr, addr_size)) goto fail; if (getsockname (listener, (struct sockaddr *)&addr, &addr_size)) goto fail; if (listen (listener, 1)) goto fail; if ((sock [0] = ev_tcp_socket ()) == INVALID_SOCKET) goto fail; if (connect (sock [0], (struct sockaddr *)&addr, addr_size)) goto fail; /* TODO: returns INVALID_SOCKET on winsock accept, not < 0. fix it */ /* when convenient, probably by just removing error checking altogether? */ if ((sock [1] = accept (listener, 0, 0)) < 0) goto fail; /* windows vista returns fantasy port numbers for sockets: * example for two interconnected tcp sockets: * * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364 * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363 * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363 * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365 * * wow! tridirectional sockets! * * this way of checking ports seems to work: */ if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size)) goto fail; if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size)) goto fail; errno = WSAEINVAL; if (addr_size != adr2_size || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */ || addr.sin_port != adr2.sin_port) goto fail; closesocket (listener); #if EV_SELECT_IS_WINSOCKET filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]); filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]); #else /* when select isn't winsocket, we also expect socket, connect, accept etc. * to work on fds */ filedes [0] = sock [0]; filedes [1] = sock [1]; #endif return 0; fail: closesocket (listener); if (sock [0] != INVALID_SOCKET) closesocket (sock [0]); if (sock [1] != INVALID_SOCKET) closesocket (sock [1]); return -1; } #undef pipe #define pipe(filedes) ev_pipe (filedes) #define EV_HAVE_EV_TIME 1 ev_tstamp ev_time (void) { FILETIME ft; ULARGE_INTEGER ui; GetSystemTimeAsFileTime (&ft); ui.u.LowPart = ft.dwLowDateTime; ui.u.HighPart = ft.dwHighDateTime; /* msvc cannot convert ulonglong to double... yes, it is that sucky */ return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7; } #endif gvpe-3.0/libev/ev_wrap.h0000644000000000000000000001260612635614725012141 00000000000000/* DO NOT EDIT, automatically generated by update_ev_wrap */ #ifndef EV_WRAP_H #define EV_WRAP_H #define acquire_cb ((loop)->acquire_cb) #define activecnt ((loop)->activecnt) #define anfdmax ((loop)->anfdmax) #define anfds ((loop)->anfds) #define async_pending ((loop)->async_pending) #define asynccnt ((loop)->asynccnt) #define asyncmax ((loop)->asyncmax) #define asyncs ((loop)->asyncs) #define backend ((loop)->backend) #define backend_fd ((loop)->backend_fd) #define backend_mintime ((loop)->backend_mintime) #define backend_modify ((loop)->backend_modify) #define backend_poll ((loop)->backend_poll) #define checkcnt ((loop)->checkcnt) #define checkmax ((loop)->checkmax) #define checks ((loop)->checks) #define cleanupcnt ((loop)->cleanupcnt) #define cleanupmax ((loop)->cleanupmax) #define cleanups ((loop)->cleanups) #define curpid ((loop)->curpid) #define epoll_epermcnt ((loop)->epoll_epermcnt) #define epoll_epermmax ((loop)->epoll_epermmax) #define epoll_eperms ((loop)->epoll_eperms) #define epoll_eventmax ((loop)->epoll_eventmax) #define epoll_events ((loop)->epoll_events) #define evpipe ((loop)->evpipe) #define fdchangecnt ((loop)->fdchangecnt) #define fdchangemax ((loop)->fdchangemax) #define fdchanges ((loop)->fdchanges) #define forkcnt ((loop)->forkcnt) #define forkmax ((loop)->forkmax) #define forks ((loop)->forks) #define fs_2625 ((loop)->fs_2625) #define fs_fd ((loop)->fs_fd) #define fs_hash ((loop)->fs_hash) #define fs_w ((loop)->fs_w) #define idleall ((loop)->idleall) #define idlecnt ((loop)->idlecnt) #define idlemax ((loop)->idlemax) #define idles ((loop)->idles) #define invoke_cb ((loop)->invoke_cb) #define io_blocktime ((loop)->io_blocktime) #define iocp ((loop)->iocp) #define kqueue_changecnt ((loop)->kqueue_changecnt) #define kqueue_changemax ((loop)->kqueue_changemax) #define kqueue_changes ((loop)->kqueue_changes) #define kqueue_eventmax ((loop)->kqueue_eventmax) #define kqueue_events ((loop)->kqueue_events) #define kqueue_fd_pid ((loop)->kqueue_fd_pid) #define loop_count ((loop)->loop_count) #define loop_depth ((loop)->loop_depth) #define loop_done ((loop)->loop_done) #define mn_now ((loop)->mn_now) #define now_floor ((loop)->now_floor) #define origflags ((loop)->origflags) #define pending_w ((loop)->pending_w) #define pendingcnt ((loop)->pendingcnt) #define pendingmax ((loop)->pendingmax) #define pendingpri ((loop)->pendingpri) #define pendings ((loop)->pendings) #define periodiccnt ((loop)->periodiccnt) #define periodicmax ((loop)->periodicmax) #define periodics ((loop)->periodics) #define pipe_w ((loop)->pipe_w) #define pipe_write_skipped ((loop)->pipe_write_skipped) #define pipe_write_wanted ((loop)->pipe_write_wanted) #define pollcnt ((loop)->pollcnt) #define pollidxmax ((loop)->pollidxmax) #define pollidxs ((loop)->pollidxs) #define pollmax ((loop)->pollmax) #define polls ((loop)->polls) #define port_eventmax ((loop)->port_eventmax) #define port_events ((loop)->port_events) #define postfork ((loop)->postfork) #define preparecnt ((loop)->preparecnt) #define preparemax ((loop)->preparemax) #define prepares ((loop)->prepares) #define release_cb ((loop)->release_cb) #define rfeedcnt ((loop)->rfeedcnt) #define rfeedmax ((loop)->rfeedmax) #define rfeeds ((loop)->rfeeds) #define rtmn_diff ((loop)->rtmn_diff) #define sig_pending ((loop)->sig_pending) #define sigfd ((loop)->sigfd) #define sigfd_set ((loop)->sigfd_set) #define sigfd_w ((loop)->sigfd_w) #define timeout_blocktime ((loop)->timeout_blocktime) #define timercnt ((loop)->timercnt) #define timermax ((loop)->timermax) #define timers ((loop)->timers) #define userdata ((loop)->userdata) #define vec_eo ((loop)->vec_eo) #define vec_max ((loop)->vec_max) #define vec_ri ((loop)->vec_ri) #define vec_ro ((loop)->vec_ro) #define vec_wi ((loop)->vec_wi) #define vec_wo ((loop)->vec_wo) #else #undef EV_WRAP_H #undef acquire_cb #undef activecnt #undef anfdmax #undef anfds #undef async_pending #undef asynccnt #undef asyncmax #undef asyncs #undef backend #undef backend_fd #undef backend_mintime #undef backend_modify #undef backend_poll #undef checkcnt #undef checkmax #undef checks #undef cleanupcnt #undef cleanupmax #undef cleanups #undef curpid #undef epoll_epermcnt #undef epoll_epermmax #undef epoll_eperms #undef epoll_eventmax #undef epoll_events #undef evpipe #undef fdchangecnt #undef fdchangemax #undef fdchanges #undef forkcnt #undef forkmax #undef forks #undef fs_2625 #undef fs_fd #undef fs_hash #undef fs_w #undef idleall #undef idlecnt #undef idlemax #undef idles #undef invoke_cb #undef io_blocktime #undef iocp #undef kqueue_changecnt #undef kqueue_changemax #undef kqueue_changes #undef kqueue_eventmax #undef kqueue_events #undef kqueue_fd_pid #undef loop_count #undef loop_depth #undef loop_done #undef mn_now #undef now_floor #undef origflags #undef pending_w #undef pendingcnt #undef pendingmax #undef pendingpri #undef pendings #undef periodiccnt #undef periodicmax #undef periodics #undef pipe_w #undef pipe_write_skipped #undef pipe_write_wanted #undef pollcnt #undef pollidxmax #undef pollidxs #undef pollmax #undef polls #undef port_eventmax #undef port_events #undef postfork #undef preparecnt #undef preparemax #undef prepares #undef release_cb #undef rfeedcnt #undef rfeedmax #undef rfeeds #undef rtmn_diff #undef sig_pending #undef sigfd #undef sigfd_set #undef sigfd_w #undef timeout_blocktime #undef timercnt #undef timermax #undef timers #undef userdata #undef vec_eo #undef vec_max #undef vec_ri #undef vec_ro #undef vec_wi #undef vec_wo #endif gvpe-3.0/po/0000755000000000000000000000000013011103357007674 500000000000000gvpe-3.0/po/Makefile.in.in0000644000000000000000000002431411046631517012304 00000000000000# Makefile for PO directory in any package using GNU gettext. # Copyright (C) 1995-1997, 2000-2002 by Ulrich Drepper # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU General Public # License but which still want to provide support for the GNU gettext # functionality. # Please note that the actual code of GNU gettext is covered by the GNU # General Public License and is *not* in the public domain. PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ localedir = $(datadir)/locale gettextsrcdir = $(datadir)/gettext/po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @MKINSTALLDIRS@ mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(top_builddir)/$(MKINSTALLDIRS)" ;; esac` GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ MSGMERGE = msgmerge MSGMERGE_UPDATE = @MSGMERGE@ --update MSGINIT = msginit MSGCONV = msgconv MSGFILTER = msgfilter POFILES = @POFILES@ GMOFILES = @GMOFILES@ UPDATEPOFILES = @UPDATEPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@ DISTFILES.common = Makefile.in.in Makevars remove-potcdate.sin \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) DISTFILES = $(DISTFILES.common) POTFILES.in $(DOMAIN).pot \ $(POFILES) $(GMOFILES) \ $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) POTFILES = \ CATALOGS = @CATALOGS@ # Makevars gets inserted here. (Don't remove this line!) .SUFFIXES: .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-update .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update $(POFILES): $(srcdir)/$(DOMAIN).pot @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext"; then \ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ for file in $(DISTFILES.common); do \ $(INSTALL_DATA) $(srcdir)/$$file \ $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi install-data-no: all install-data-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ fi; \ done; \ done install-strip: install installdirs: installdirs-exec installdirs-data installdirs-exec: installdirs-data: installdirs-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext"; then \ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ else \ : ; \ fi installdirs-data-no: installdirs-data-yes: $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done # Define this as empty until I found a useful application. installcheck: uninstall: uninstall-exec uninstall-data uninstall-exec: uninstall-data: uninstall-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext"; then \ for file in $(DISTFILES.common); do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi uninstall-data-no: uninstall-data-yes: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ done; \ done check: all dvi info tags TAGS ID: mostlyclean: rm -f remove-potcdate.sed rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po rm -fr *.o clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES *.mo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f $(GMOFILES) distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(MAKE) update-po @$(MAKE) dist2 # This is a separate target because 'update-po' must be executed before. dist2: $(DISTFILES) dists="$(DISTFILES)"; \ if test -f $(srcdir)/ChangeLog; then dists="$$dists ChangeLog"; fi; \ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ for file in $$dists; do \ if test -f $$file; then \ cp -p $$file $(distdir); \ else \ cp -p $(srcdir)/$$file $(distdir); \ fi; \ done update-po: Makefile $(MAKE) $(DOMAIN).pot-update $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for updating PO files. .nop.po-update: @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: Makefile: Makefile.in.in $(top_builddir)/config.status POTFILES.in cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ $(SHELL) ./config.status force: # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gvpe-3.0/po/Makevars0000644000000000000000000000205111046631517011320 00000000000000# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Marc Lehmann # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = gvpe-3.0/po/remove-potcdate.sin0000644000000000000000000000066011046631517013441 00000000000000# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } gvpe-3.0/po/quot.sed0000644000000000000000000000023111046631517011307 00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g gvpe-3.0/po/boldquot.sed0000644000000000000000000000033111046631517012151 00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g s/“/“/g s/”/”/g s/‘/‘/g s/’/’/g gvpe-3.0/po/en@quot.header0000644000000000000000000000226311046631517012416 00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # gvpe-3.0/po/en@boldquot.header0000644000000000000000000000247111046631517013260 00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # # This catalog furthermore displays the text between the quotation marks in # bold face, assuming the VT100/XTerm escape sequences. # gvpe-3.0/po/insert-header.sin0000644000000000000000000000124011046631517013070 00000000000000# Sed script that inserts the file called HEADER before the header entry. # # At each occurrence of a line starting with "msgid ", we execute the following # commands. At the first occurrence, insert the file. At the following # occurrences, do nothing. The distinction between the first and the following # occurrences is achieved by looking at the hold space. /^msgid /{ x # Test if the hold space is empty. s/m/m/ ta # Yes it was empty. First occurrence. Read the file. r HEADER # Output the file's contents by reading the next line. But don't lose the # current line while doing this. g N bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } gvpe-3.0/po/Rules-quot0000644000000000000000000000323111046631517011630 00000000000000# Special Makefile rules for English message catalogs with quotation marks. DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot .SUFFIXES: .insert-header .po-update-en en@quot.po-update: en@quot.po-update-en en@boldquot.po-update: en@boldquot.po-update-en .insert-header.po-update-en: @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ ll=`echo $$lang | sed -e 's/@.*//'`; \ LC_ALL=C; export LC_ALL; \ cd $(srcdir); \ if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "creation of $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi en@quot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header en@boldquot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header mostlyclean: mostlyclean-quot mostlyclean-quot: rm -f *.insert-header gvpe-3.0/po/POTFILES.in0000644000000000000000000000134111525407040011374 00000000000000lib/pidfile.c src/tincd/cygwin/device.c src/tincd/darwin/device.c src/tincd/freebsd/device.c src/tincd/linux/device.c src/tincd/mingw/common.h src/tincd/mingw/device.c src/tincd/netbsd/device.c src/tincd/openbsd/device.c src/tincd/raw_socket/device.c src/tincd/solaris/device.c src/tincd/uml_socket/device.c src/callback.h src/conf.C src/conf.h src/connection.C src/connection.h src/device-cygwin.C src/device-linux.C src/device-tincd.C src/device-darwin.C src/device.C src/device.h src/ether_emu.C src/global.h src/gvpe.C src/gvpectrl.C src/lzf/lzf.h src/lzf/lzfP.h src/lzf/lzf_c.c src/lzf/lzf_d.c src/netcompat.h src/slog.C src/slog.h src/sockinfo.C src/sockinfo.h src/util.C src/util.h src/vpn.C src/vpn.h src/vpn_dns.C src/vpn_tcp.C gvpe-3.0/po/gvpe.pot0000644000000000000000000006406613011103357011315 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Marc Lehmann # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-11-10 15:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: src/tincd/cygwin/device.c:62 src/tincd/mingw/device.c:140 #, c-format msgid "Unable to read registry: %s" msgstr "" #: src/tincd/cygwin/device.c:114 src/tincd/mingw/device.c:191 msgid "No Windows tap device found!" msgstr "" #: src/tincd/cygwin/device.c:131 src/tincd/cygwin/device.c:162 #: src/tincd/mingw/device.c:59 src/tincd/mingw/device.c:68 #: src/tincd/mingw/device.c:73 src/tincd/mingw/device.c:229 #: src/tincd/mingw/device.c:236 src/tincd/mingw/device.c:241 #: src/tincd/mingw/device.c:248 src/tincd/mingw/device.c:257 #: src/tincd/mingw/device.c:264 src/tincd/uml_socket/device.c:82 #: src/tincd/uml_socket/device.c:96 src/tincd/uml_socket/device.c:123 #: src/tincd/uml_socket/device.c:187 #, c-format msgid "System call `%s' failed: %s" msgstr "" #: src/tincd/cygwin/device.c:140 #, c-format msgid "Could not open Windows tap device %s (%s) for writing: %s" msgstr "" #: src/tincd/cygwin/device.c:149 src/tincd/mingw/device.c:216 #, c-format msgid "Could not get MAC address from Windows tap device %s (%s): %s" msgstr "" #: src/tincd/cygwin/device.c:178 #, c-format msgid "Could not open Windows tap device %s (%s) for reading: %s" msgstr "" #: src/tincd/cygwin/device.c:184 msgid "Tap reader forked and running." msgstr "" #: src/tincd/cygwin/device.c:201 msgid "Tap reader failed!" msgstr "" #: src/tincd/cygwin/device.c:205 src/tincd/mingw/device.c:275 msgid "Windows tap device" msgstr "" #: src/tincd/cygwin/device.c:207 src/tincd/mingw/device.c:277 #, c-format msgid "%s (%s) is a %s" msgstr "" #: src/tincd/cygwin/device.c:230 src/tincd/darwin/device.c:70 #: src/tincd/freebsd/device.c:70 src/tincd/linux/device.c:129 #: src/tincd/linux/device.c:140 src/tincd/linux/device.c:151 #: src/tincd/mingw/device.c:96 src/tincd/mingw/device.c:296 #: src/tincd/netbsd/device.c:73 src/tincd/openbsd/device.c:76 #: src/tincd/raw_socket/device.c:95 src/tincd/solaris/device.c:120 #: src/tincd/uml_socket/device.c:232 #, c-format msgid "Error while reading from %s %s: %s" msgstr "" #: src/tincd/cygwin/device.c:239 src/tincd/darwin/device.c:82 #: src/tincd/freebsd/device.c:79 src/tincd/linux/device.c:162 #: src/tincd/mingw/device.c:305 src/tincd/netbsd/device.c:85 #: src/tincd/openbsd/device.c:103 src/tincd/raw_socket/device.c:104 #: src/tincd/solaris/device.c:145 src/tincd/uml_socket/device.c:242 #, c-format msgid "Read packet of %d bytes from %s" msgstr "" #: src/tincd/cygwin/device.c:251 src/tincd/darwin/device.c:92 #: src/tincd/freebsd/device.c:89 src/tincd/linux/device.c:172 #: src/tincd/mingw/device.c:318 src/tincd/netbsd/device.c:95 #: src/tincd/openbsd/device.c:117 src/tincd/raw_socket/device.c:114 #: src/tincd/solaris/device.c:155 src/tincd/uml_socket/device.c:260 #, c-format msgid "Writing packet of %d bytes to %s" msgstr "" #: src/tincd/cygwin/device.c:255 src/tincd/darwin/device.c:96 #: src/tincd/freebsd/device.c:93 src/tincd/mingw/device.c:322 #, c-format msgid "Error while writing to %s %s: %s" msgstr "" #: src/tincd/cygwin/device.c:268 src/tincd/darwin/device.c:110 #: src/tincd/freebsd/device.c:107 src/tincd/linux/device.c:211 #: src/tincd/mingw/device.c:335 src/tincd/netbsd/device.c:113 #: src/tincd/openbsd/device.c:156 src/tincd/raw_socket/device.c:132 #: src/tincd/solaris/device.c:173 src/tincd/uml_socket/device.c:281 #, c-format msgid "Statistics for %s %s:" msgstr "" #: src/tincd/cygwin/device.c:269 src/tincd/darwin/device.c:111 #: src/tincd/freebsd/device.c:108 src/tincd/linux/device.c:212 #: src/tincd/mingw/device.c:336 src/tincd/netbsd/device.c:114 #: src/tincd/openbsd/device.c:157 src/tincd/raw_socket/device.c:133 #: src/tincd/solaris/device.c:174 src/tincd/uml_socket/device.c:282 #, c-format msgid " total bytes in: %10d" msgstr "" #: src/tincd/cygwin/device.c:270 src/tincd/darwin/device.c:112 #: src/tincd/freebsd/device.c:109 src/tincd/linux/device.c:213 #: src/tincd/mingw/device.c:337 src/tincd/netbsd/device.c:115 #: src/tincd/openbsd/device.c:158 src/tincd/raw_socket/device.c:134 #: src/tincd/solaris/device.c:175 src/tincd/uml_socket/device.c:283 #, c-format msgid " total bytes out: %10d" msgstr "" #: src/tincd/darwin/device.c:45 src/tincd/freebsd/device.c:45 #: src/tincd/linux/device.c:68 src/tincd/netbsd/device.c:48 #: src/tincd/openbsd/device.c:49 src/tincd/raw_socket/device.c:52 #: src/tincd/solaris/device.c:52 src/tincd/uml_socket/device.c:115 #, c-format msgid "Could not open %s: %s" msgstr "" #: src/tincd/darwin/device.c:49 msgid "MacOS/X tun device" msgstr "" #: src/tincd/darwin/device.c:51 src/tincd/freebsd/device.c:51 #: src/tincd/linux/device.c:106 src/tincd/netbsd/device.c:54 #: src/tincd/openbsd/device.c:55 src/tincd/raw_socket/device.c:76 #: src/tincd/solaris/device.c:101 src/tincd/uml_socket/device.c:142 #: src/device-linux.C:126 #, c-format msgid "%s is a %s" msgstr "" #: src/tincd/freebsd/device.c:49 msgid "FreeBSD tap device" msgstr "" #: src/tincd/linux/device.c:79 msgid "Linux tun/tap device (tun mode)" msgstr "" #: src/tincd/linux/device.c:83 msgid "Linux tun/tap device (tap mode)" msgstr "" #: src/tincd/linux/device.c:93 #, c-format msgid "Old ioctl() request was needed for %s" msgstr "" #: src/tincd/linux/device.c:101 msgid "Linux ethertap device" msgstr "" #: src/tincd/linux/device.c:179 src/tincd/linux/device.c:186 #: src/tincd/linux/device.c:195 src/tincd/netbsd/device.c:99 #: src/tincd/openbsd/device.c:142 src/tincd/raw_socket/device.c:118 #: src/tincd/solaris/device.c:159 src/tincd/uml_socket/device.c:265 #, c-format msgid "Can't write to %s %s: %s" msgstr "" #: src/tincd/mingw/device.c:77 msgid "Tap reader running" msgstr "" #: src/tincd/mingw/device.c:209 #, c-format msgid "%s (%s) is not a usable Windows tap device: %s" msgstr "" #: src/tincd/netbsd/device.c:52 msgid "NetBSD tun device" msgstr "" #: src/tincd/openbsd/device.c:53 msgid "OpenBSD tun device" msgstr "" #: src/tincd/openbsd/device.c:94 #, c-format msgid "Unknown address family %d while reading packet from %s %s" msgstr "" #: src/tincd/openbsd/device.c:131 #, c-format msgid "Unknown address family %d while writing packet to %s %s" msgstr "" #: src/tincd/raw_socket/device.c:49 msgid "raw socket" msgstr "" #: src/tincd/raw_socket/device.c:61 #, c-format msgid "Can't find interface %s: %s" msgstr "" #: src/tincd/raw_socket/device.c:72 src/tincd/uml_socket/device.c:130 #, c-format msgid "Could not bind %s to %s: %s" msgstr "" #: src/tincd/solaris/device.c:64 #, c-format msgid "Could not open /dev/ip: %s" msgstr "" #: src/tincd/solaris/device.c:70 #, c-format msgid "Can't assign new interface: %s" msgstr "" #: src/tincd/solaris/device.c:75 #, c-format msgid "Could not open %s twice: %s" msgstr "" #: src/tincd/solaris/device.c:81 #, c-format msgid "Can't push IP module: %s" msgstr "" #: src/tincd/solaris/device.c:87 #, c-format msgid "Can't set PPA %d: %s" msgstr "" #: src/tincd/solaris/device.c:92 #, c-format msgid "Can't link TUN device to IP: %s" msgstr "" #: src/tincd/solaris/device.c:99 msgid "Solaris tun device" msgstr "" #: src/tincd/solaris/device.c:136 #, c-format msgid "Unknown IP version %d while reading packet from %s %s" msgstr "" #: src/tincd/uml_socket/device.c:71 msgid "UML network socket" msgstr "" #: src/tincd/uml_socket/device.c:74 #, c-format msgid "Could not open write %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:88 #, c-format msgid "Could not open data %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:109 #, c-format msgid "Could not bind data %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:135 #, c-format msgid "Could not listen on %s %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:182 #, c-format msgid "Could not accept connection to %s %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:202 #, c-format msgid "Error while reading request from %s %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:209 #, c-format msgid "Unknown magic %x, version %d, request type %d from %s %s" msgstr "" #: src/tincd/uml_socket/device.c:216 #, c-format msgid "Could not bind write %s: %s" msgstr "" #: src/tincd/uml_socket/device.c:224 msgid "Connection with UML established" msgstr "" #: src/tincd/uml_socket/device.c:255 #, c-format msgid "Dropping packet of %d bytes to %s: not connected to UML yet" msgstr "" #: src/conf.C:232 msgid "" "illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored" msgstr "" #: src/conf.C:266 msgid "no value given for variable, ignored" msgstr "" #: src/conf.C:289 msgid "unknown loglevel, ignored" msgstr "" #: src/conf.C:305 msgid "user specified for chuser not found" msgstr "" #: src/conf.C:463 msgid "" "illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or " "'disabled', ignored" msgstr "" #: src/conf.C:509 msgid "unknown configuration directive - ignored" msgstr "" #: src/conf.C:519 #, c-format msgid "%s: max-queue value invalid, setting it to 1." msgstr "" #: src/conf.C:545 #, c-format msgid "%s, at '%s', line %d." msgstr "" #: src/conf.C:552 #, c-format msgid "unable to read config file '%s': %s" msgstr "" #: src/conf.C:581 #, c-format msgid "unable to read private rsa key file '%s': %s" msgstr "" #: src/conf.C:593 #, c-format msgid "unable to open private rsa key file '%s': %s" msgstr "" #: src/conf.C:619 #, c-format msgid "unable to open public rsa key file '%s': %s" msgstr "" #: src/conf.C:629 #, c-format msgid "unable to read public rsa key file '%s': %s" msgstr "" #: src/conf.C:648 #, c-format msgid "local node ('%s') not found in config file, aborting." msgstr "" #: src/conf.C:656 #, c-format msgid "private hostkey and public node key mismatch: is '%s' the correct node?" msgstr "" #: src/conf.C:692 #, c-format msgid "command line option '%s' refers to unknown node, ignoring." msgstr "" #: src/conf.C:702 #, c-format msgid "%s, while parsing command line option '%s'." msgstr "" #: src/conf.C:746 #, c-format msgid "" "\n" "Configuration\n" "\n" msgstr "" #: src/conf.C:747 #, c-format msgid "# of nodes: %d\n" msgstr "" #: src/conf.C:748 #, c-format msgid "this node: %s\n" msgstr "" #: src/conf.C:749 #, c-format msgid "MTU: %d\n" msgstr "" #: src/conf.C:750 #, c-format msgid "rekeying interval: %d\n" msgstr "" #: src/conf.C:751 #, c-format msgid "keepalive interval: %d\n" msgstr "" #: src/conf.C:752 #, c-format msgid "interface: %s\n" msgstr "" #: src/conf.C:753 #, c-format msgid "primary rsa key: %s\n" msgstr "" #: src/conf.C:754 #, c-format msgid "rsa key size: %d\n" msgstr "" #: src/conf.C:758 msgid "ID#" msgstr "" #: src/conf.C:758 msgid "MAC" msgstr "" #: src/conf.C:758 msgid "Com" msgstr "" #: src/conf.C:758 msgid "Conmode" msgstr "" #: src/conf.C:758 msgid "Node" msgstr "" #: src/conf.C:758 msgid "Prot" msgstr "" #: src/conf.C:758 msgid "Host:Port" msgstr "" #: src/connection.C:592 #, c-format msgid "%s(%s): major version mismatch (remote %d <=> local %d)" msgstr "" #: src/connection.C:595 #, c-format msgid "%s(%s): cipher algo mismatch (remote %x <=> local %x)" msgstr "" #: src/connection.C:598 #, c-format msgid "%s(%s): mac algo mismatch (remote %x <=> local %x)" msgstr "" #: src/connection.C:601 #, c-format msgid "%s(%s): auth algo mismatch (remote %x <=> local %x)" msgstr "" #: src/connection.C:608 #, c-format msgid "%s(%s): remote serial newer than local serial - outdated config?" msgstr "" #: src/connection.C:690 #, c-format msgid "%s(%s): connection established (%s), protocol version %d.%d." msgstr "" #: src/connection.C:699 msgid "node-up command execution failed, continuing." msgstr "" #: src/connection.C:739 #, c-format msgid "%s: direct connection denied by config." msgstr "" #: src/connection.C:756 #, c-format msgid "%s: no common protocol, trying to route through %s." msgstr "" #: src/connection.C:761 #, c-format msgid "%s: node unreachable, no common protocol or no router available." msgstr "" #: src/connection.C:881 #, c-format msgid "%s: sending direct connection request to %s." msgstr "" #: src/connection.C:916 #, c-format msgid "%s(%s): connection lost (%s)" msgstr "" #: src/connection.C:923 msgid "node-down command execution failed, continuing." msgstr "" #: src/connection.C:1080 #, c-format msgid "%s(%s): protocol magic mismatch - stray packet?" msgstr "" #: src/connection.C:1086 #, c-format msgid "%s(%s): protocol minor version mismatch: ours is %d, %s's is %d." msgstr "" #: src/connection.C:1102 #, c-format msgid "" "%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?" msgstr "" #: src/connection.C:1142 #, c-format msgid "%s(%s): unrequested or outdated auth response, ignoring." msgstr "" #: src/connection.C:1182 #, c-format msgid "" "%s(%s): hmac authentication error, received invalid packet\n" "could be an attack, or just corruption or a synchronization error." msgstr "" #: src/connection.C:1205 #, c-format msgid "%s(%s): changing socket address to %s." msgstr "" #: src/connection.C:1214 msgid "node-change command execution failed, continuing." msgstr "" #: src/connection.C:1224 #, c-format msgid "" "received very old packet (received %08lx, expected %08lx). possible replay " "attack, or just packet duplication/delay, ignoring." msgstr "" #: src/connection.C:1227 #, c-format msgid "" "received recent duplicated packet (received %08lx, expected %08lx). possible " "replay attack, or just packet duplication, ignoring." msgstr "" #: src/connection.C:1231 #, c-format msgid "" "received out-of-sync (far future) packet (received %08lx, expected %08lx). " "probably just massive packet loss, sending reset." msgstr "" #: src/connection.C:1271 src/connection.C:1310 #, c-format msgid "" "received authenticated connection request from unknown node #%d, config file " "mismatch?" msgstr "" #: src/device-cygwin.C:83 msgid "(unable to format errormessage)" msgstr "" #: src/device-cygwin.C:134 msgid "cygwin cipe/openvpn tap device" msgstr "" #: src/device-cygwin.C:162 #, c-format msgid "WIN32 TAP: unable to read registry: %s" msgstr "" #: src/device-cygwin.C:214 msgid "WIN32 TAP: no windows tap device found!" msgstr "" #: src/device-cygwin.C:231 #, c-format msgid "WIN32 TAP: %s is not a usable windows tap device %s: %s" msgstr "" #: src/device-cygwin.C:245 #, c-format msgid "WIN32 TAP: could not get MAC address from windows tap device %s: %s" msgstr "" #: src/device-cygwin.C:281 msgid "WIN32 TAP: i/o thread delivered incomplete pkt length" msgstr "" #: src/device-cygwin.C:288 msgid "WIN32 TAP: i/o thread delivered incomplete pkt" msgstr "" #: src/device-cygwin.C:327 #, c-format msgid "WIN32 TAP: can't write to %s %s: %s" msgstr "" #: src/device-linux.C:67 msgid "Linux tun/tap device" msgstr "" #: src/device-linux.C:86 src/device-darwin.C:72 #, c-format msgid "could not open device %s: %s" msgstr "" #: src/device-linux.C:109 #, c-format msgid "unable to configure tun/tap interface, exiting: %s" msgstr "" #: src/device-linux.C:118 #, c-format msgid "cannot set MAC address for device %s, exiting: %s" msgstr "" #: src/device-linux.C:124 #, c-format msgid "cannot set persistency mode for device %s: %s" msgstr "" #: src/device-linux.C:148 src/device-darwin.C:96 #, c-format msgid "error while reading from %s %s: %s" msgstr "" #: src/device-linux.C:179 #, c-format msgid "can't write %d byte packet to %s %s: %s" msgstr "" #: src/device-tincd.C:98 #, c-format msgid "tincd layer asking for unknown config '%s'" msgstr "" #: src/device-tincd.C:166 msgid "tincd compatibility layer" msgstr "" #: src/device-tincd.C:180 src/device-darwin.C:76 #, c-format msgid "interface %s on %s initialized" msgstr "" #: src/device-tincd.C:186 #, c-format msgid "error while configuring tincd device %s on %s" msgstr "" #: src/device-tincd.C:204 #, c-format msgid "can't read from to %s %s: %s" msgstr "" #: src/device-tincd.C:232 src/device-darwin.C:108 #, c-format msgid "can't write to %s %s: %s" msgstr "" #: src/device-darwin.C:57 msgid "darwin tap driver" msgstr "" #: src/device.C:48 #, c-format msgid "" "FATAL: allocation for network packet larger than max supported packet size " "(%d > %d)." msgstr "" #: src/gvpe.C:96 src/gvpectrl.C:104 #, c-format msgid "Try `%s --help' for more information.\n" msgstr "" #: src/gvpe.C:99 #, c-format msgid "" "Usage: %s [option]... NODENAME\n" "\n" msgstr "" #: src/gvpe.C:101 #, c-format msgid "" " -c, --config=DIR Read configuration options from DIR.\n" " -D, --no-detach Don't fork and detach.\n" " -l, --log-level=LEVEL Set logging level (info, notice, warn are " "common).\n" " -L, --mlock Lock gvpe into main memory.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n" "\n" msgstr "" #: src/gvpe.C:107 src/gvpectrl.C:117 #, c-format msgid "Report bugs to .\n" msgstr "" #: src/gvpe.C:165 #, c-format msgid "terminating with exit code %d" msgstr "" #: src/gvpe.C:243 #, c-format msgid "unable to open seed device '%s': %s, exiting." msgstr "" #: src/gvpe.C:290 src/gvpectrl.C:384 #, c-format msgid "%s version %s (built %s %s, protocol version %d.%d)\n" msgstr "" #: src/gvpe.C:292 src/gvpectrl.C:386 #, c-format msgid "Built with kernel interface %s/%s.\n" msgstr "" #: src/gvpe.C:294 #, c-format msgid "" "Copyright (C) 2003-2011 Marc Lehmann and others.\n" "See the AUTHORS file for a complete list.\n" "\n" "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" "see the file COPYING for details.\n" msgstr "" #: src/gvpe.C:313 #, c-format msgid "system call `%s' failed: %s" msgstr "" #: src/gvpe.C:324 msgid "unable to initialise the event loop (bad $LIBEV_METHODS?)" msgstr "" #: src/gvpe.C:338 #, c-format msgid "" "current node not set, or node '%s' not found in configfile, specify the " "nodename when starting gvpe." msgstr "" #: src/gvpe.C:355 msgid "unrecoverable error while setting up network, exiting." msgstr "" #: src/gvpectrl.C:107 #, c-format msgid "" "Usage: %s [option]...\n" "\n" msgstr "" #: src/gvpectrl.C:109 #, c-format msgid "" " -c, --config=DIR Read configuration options from DIR.\n" " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n" " -g, --generate-key=file Generate public/private RSA keypair.\n" " -G, --generate-keys Generate all public/private RSA keypairs.\n" " -s, --show-config Display the configuration information.\n" " -q, --quiet Be quite quiet.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n" "\n" msgstr "" #: src/gvpectrl.C:165 #, c-format msgid "" "Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, " "USR1, USR2, WINCH, INT or ALRM.\n" msgstr "" #: src/gvpectrl.C:335 #, c-format msgid "generated %d bits key for %s.\n" msgstr "" #: src/gvpectrl.C:338 #, c-format msgid "'%s' keypair already exists, skipping node %s.\n" msgstr "" #: src/gvpectrl.C:359 #, c-format msgid "generated %d bits key as %s.\n" msgstr "" #: src/gvpectrl.C:363 #, c-format msgid "'%s' keypair already exists, not generating key.\n" msgstr "" #: src/gvpectrl.C:388 #, c-format msgid "" "Copyright (C) 2003-2013 Marc Lehmann and others.\n" "See the AUTHORS file for a complete list.\n" "\n" "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" "see the file COPYING for details.\n" msgstr "" #: src/slog.h:56 msgid "" "unknown loglevel, try 'noise', 'debug', 'info', 'notice', 'warn', 'error' or " "'critical'" msgstr "" #: src/sockinfo.C:82 #, c-format msgid "unable to resolve host '%s'" msgstr "" #: src/util.C:75 #, c-format msgid "A gvpe daemon is already running with pid %d.\n" msgstr "" #: src/util.C:95 #, c-format msgid "No other gvpe daemon is running.\n" msgstr "" #: src/util.C:104 #, c-format msgid "The gvpe daemon is no longer running. " msgstr "" #: src/util.C:106 #, c-format msgid "Removing stale lock file.\n" msgstr "" #: src/util.C:131 #, c-format msgid "couldn't detach from terminal: %s" msgstr "" #: src/util.C:145 #, c-format msgid "gvpe daemon %s (%s %s) starting up." msgstr "" #: src/util.C:185 #, c-format msgid "waiting for an external command failed: %s." msgstr "" #: src/util.C:191 #, c-format msgid "external command returned with exit status %d (%04x)." msgstr "" #: src/util.C:199 #, c-format msgid "unable to fork, exiting: %s" msgstr "" #: src/util.C:408 msgid "" "Not enough random entropy to generate secure keys. Using weaker pseudo-" "random session keys." msgstr "" #: src/util.C:410 msgid "RAND_bytes failed, aborting." msgstr "" #: src/vpn.C:154 #, c-format msgid "unable to create %s socket: %s." msgstr "" #: src/vpn.C:164 #, c-format msgid "unable to set nfmark on %s socket: %s" msgstr "" #: src/vpn.C:199 #, c-format msgid "can't bind ipv4 socket on %s: %s, exiting." msgstr "" #: src/vpn.C:239 #, c-format msgid "can't bind udpv4 on %s: %s, exiting." msgstr "" #: src/vpn.C:285 #, c-format msgid "can't bind icmpv4 on %s: %s, exiting." msgstr "" #: src/vpn.C:314 #, c-format msgid "can't bind tcpv4 on %s: %s, exiting." msgstr "" #: src/vpn.C:320 #, c-format msgid "can't listen tcpv4 on %s: %s, exiting." msgstr "" #: src/vpn.C:366 #, c-format msgid "can't bind dnsv4 on %s: %s, exiting." msgstr "" #: src/vpn.C:379 msgid "no protocols enabled." msgstr "" #: src/vpn.C:390 #, c-format msgid "cannot create network interface '%s'." msgstr "" #: src/vpn.C:402 #, c-format msgid "interface initialization command '%s' failed." msgstr "" #: src/vpn.C:410 msgid "if-up command execution failed." msgstr "" #: src/vpn.C:429 msgid "unable to create anonymous root path." msgstr "" #: src/vpn.C:435 msgid "unable to create anonymous root directory." msgstr "" #: src/vpn.C:441 msgid "unable to change to anonymous root directory." msgstr "" #: src/vpn.C:446 msgid "unable to remove anonymous root directory, continuing." msgstr "" #: src/vpn.C:452 #, c-format msgid "%s: unable to change to specified root directory." msgstr "" #: src/vpn.C:459 msgid "unable to set new root directory." msgstr "" #: src/vpn.C:465 msgid "unable to set cwd to new root directory." msgstr "" #: src/vpn.C:473 #, c-format msgid "unable to change group id to %d." msgstr "" #: src/vpn.C:480 #, c-format msgid "unable to change user id to %d." msgstr "" #: src/vpn.C:572 #, c-format msgid "< %d) stream skipping a byte..." msgstr "" #: src/vpn_dns.C:1084 #, c-format msgid "DNS: client %d connects (version %d, req_cdc %d)" msgstr "" #: src/vpn_dns.C:1210 #, c-format msgid "DNS: got tunnel meta command %02x" msgstr "" #: src/vpn_dns.C:1214 msgid "DNS: got tunnel RST request." msgstr "" #: src/vpn_dns.C:1221 msgid "DNS: got tunnel SYN reply, server likes us." msgstr "" #: src/vpn_dns.C:1228 msgid "" "DNS: got tunnel CSE reply, globally downgrading to case-insensitive protocol." msgstr "" #: src/vpn_dns.C:1235 msgid "DNS: got tunnel CSE reply, server likes us." msgstr "" #: src/vpn_dns.C:1241 msgid "DNS: got tunnel REJ reply, server does not like us." msgstr "" #: src/vpn_dns.C:1246 #, c-format msgid "DNS: got unknown meta command %02x" msgstr "" #: src/vpn_dns.C:1251 #, c-format msgid "DNS: got spurious a record %d.%d.%d.%d" msgstr "" #: src/vpn_dns.C:1262 msgid "DNS: got dns tunnel response with wrong clientid, ignoring" msgstr "" #: src/vpn_dns.C:1267 msgid "" "DNS: got dns tunnel response with wrong seqno, badly caching nameserver?" msgstr "" #: src/vpn_tcp.C:156 #, c-format msgid "%s: accepted tcp connection" msgstr "" #: src/vpn_tcp.C:345 #, c-format msgid "(%s): unable to do proxy-forwarding, short response" msgstr "" #: src/vpn_tcp.C:353 #, c-format msgid "(%s): malformed or unexpected proxy response (%.12s)" msgstr "" #: src/vpn_tcp.C:401 #, c-format msgid "unable to resolve http proxy hostname '%s', trying direct" msgstr "" gvpe-3.0/po/ChangeLog0000644000000000000000000000014611046631517011401 000000000000002003-02-21 gettextize * Makefile.in.in: New file, from gettext-0.11.5. gvpe-3.0/README0000644000000000000000000002411011046631516010065 00000000000000 ==== NAME ==== GNU-VPE - Overview of the GNU Virtual Private Ethernet suite. ==== DESCRIPTION ==== GVPE is a suite designed to provide a virtual private network for multiple nodes over an untrusted network. This document first gives an introduction to VPNs in general and then describes the specific implementation of GVPE. == WHAT IS A VPN? == VPN is an acronym, it stands for: : Virtual means that no physical network is created (of course), but a network is *emulated* by creating multiple tunnels between the member nodes by encapsulating and sending data over another transport network. Usually the emulated network is a normal IP or Ethernet, and the transport network is the Internet. However, using a VPN system like GVPE to connect nodes over other untrusted networks such as Wireless LAN is not uncommon. : Private means that non-participating nodes cannot decode ("sniff)" nor inject ("spoof") packets. This means that nodes can be connected over untrusted networks such as the public Internet without fear of being eavesdropped while at the same time being able to trust data sent by other nodes. In the case of GVPE, even participating nodes cannot sniff packets send to other nodes or spoof packets as if sent from other nodes, so communications between any two nodes is private to those two nodes. : Network means that more than two parties can participate in the network, so for instance it's possible to connect multiple branches of a company into a single network. Many so-called "vpn" solutions only create point-to-point tunnels, which in turn can be used to build larger networks. GVPE provides a true multi-point network in wich any number of nodes (at least a few dozen in practise, the theoretical limit is 4095 nodes) can participate. == GVPE DESIGN GOALS == : SIMPLE DESIGN Cipher, HMAC algorithms and other key parameters must be selected at compile time - this makes it possible to only link in algorithms you actually need. It also makes the crypto part of the source very transparent and easy to inspect, and last not least this makes it possible to hardcode the layout of all packets into the binary. GVPE goes a step further and internally reserves blocks of the same length for all packets, which virtually removes all possibilities of buffer overflows, as there is only a single type of buffer and it's always of fixed length. : EASY TO SETUP A few lines of config (the config file is shared unmodified between all hosts) and a single run of ``gvpectrl'' to generate the keys suffices to make it work. : MAC-BASED SECURITY Since every host has it's own private key, other hosts cannot spoof traffic from this host. That makes it possible to filter packet by MAC address, e.g. to ensure that packets from a specific IP address come, in fact, from a specific host that is associated with that IP and not from another host. ==== PROGRAMS ==== Vpe comes with two programs: one daemon (``gvpe'') and one control program (``gvpectrl''). : gvpectrl Is used to generate the keys, check and give an overview of of the configuration and contorl the daemon (restarting etc.). : gvpe Is the daemon used to establish and maintain connections to the other network members. It should be run on the gateway machine. ==== COMPILETIME CONFIGURATION ==== Please have a look at the ``gvpe.osdep(5)'' manpage for platform-specific information. Here are a few recipes for compiling your gvpe, showing the extremes (fast, small, insecure OR slow, large, more secure), between you should choose: == AS LOW PACKET OVERHEAD AS POSSIBLE == ./configure --enable-hmac-length=4 --enable-rand-length=0 Minimize the header overhead of VPN packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a HMAC length of 4 makes collision attacks based on the birthday paradox easy, though. == MINIMIZE CPU TIME REQUIRED == ./configure --enable-cipher=bf --enable-digest=md4 Use the fastest cipher and digest algorithms currently available in gvpe. MD4 has been broken and is quite insecure, though. == MAXIMIZE SECURITY == ./configure --enable-hmac-length=16 --enable-rand-length=8 --enable-digest=sha1 This uses a 16 byte HMAC checksum to authenticate packets (I guess 8-12 would also be pretty secure ;) and will additionally prefix each packet with 8 bytes of random data. In the long run, people should move to SHA-224 and beyond, but support in openssl is missing as of writing this document. In general, remember that AES-128 seems to be more secure and faster than AES-192 or AES-256, more randomness helps against sniffing and a longer HMAC helps against spoofing. MD4 is a fast digest, SHA1 or RIPEMD160 are better, and Blowfish is a fast cipher (and also quite secure). ==== HOW TO SET UP A SIMPLE VPN ==== In this section I will describe how to get a simple VPN consisting of three hosts up and running. == STEP 1: configuration == First you have to create a daemon configuation file and put it into the configuration directory. This is usually ``/etc/gvpe'', depending on how you configured gvpe, and can be overwritten using the ``-c'' commandline switch. Put the following lines into ``/etc/gvpe/gvpe.conf'': udp-port = 50000 # the external port to listen on (configure your firewall) mtu = 1400 # minimum MTU of all outgoing interfaces on all hosts ifname = vpn0 # the local network device name node = first # just a nickname hostname = first.example.net # the DNS name or IP address of the host node = second hostname = 133.55.82.9 node = third hostname = third.example.net The only other file neccessary if the ``if-up'' script that initializes the local ethernet interface. Put the following lines into ``/etc/gvpe/if-up'' and make it execute (``chmod 755 /etc/gvpe/if-up''): #!/bin/sh ip link set $IFNAME address $MAC mtu $MTU up [ $NODENAME = first ] && ip addr add 10.0.1.1 dev $IFNAME [ $NODENAME = second ] && ip addr add 10.0.2.1 dev $IFNAME [ $NODENAME = third ] && ip addr add 10.0.3.1 dev $IFNAME ip route add 10.0.0.0/16 dev $IFNAME This script will give each node a different IP address in the ``10.0/16'' network. The internal network (e.g. the ``eth0'' interface) should then be set to a subset of that network, e.g. ``10.0.1.0/24'' on node ``first'', ``10.0.2.0/24'' on node ``second'', and so on. By enabling routing on the gateway host that runs ``gvpe'' all nodes will be able to reach the other nodes. You can, of course, also use proxy arp or other means of pseudo-bridging (or even real briding), or (best) full routing - the choice is yours. == STEP 2: create the RSA key pairs for all hosts == Run the following command to generate all key pairs (that might take a while): gvpectrl -c /etc/gvpe -g This command will put the public keys into ``/etc/gvpe/pubkeys/*nodename*'' and the private keys into ``/etc/gvpe/hostkeys/*nodename*''. == STEP 3: distribute the config files to all nodes == Now distribute the config files to the other nodes. This should be done in two steps, since the private keys should not be distributed. The example uses rsync-over-ssh First all the config files without the hostkeys should be distributed: rsync -avzessh /etc/gvpe first.example.net:/etc/. --exclude hostkeys rsync -avzessh /etc/gvpe 133.55.82.9:/etc/. --exclude hostkeys rsync -avzessh /etc/gvpe third.example.net:/etc/. --exclude hostkeys Then the hostkeys should be copied: rsync -avzessh /etc/gvpe/hostkeys/first first.example.net:/etc/hostkey rsync -avzessh /etc/gvpe/hostkeys/second 133.55.82.9:/etc/hostkey rsync -avzessh /etc/gvpe/hostkeys/third third.example.net:/etc/hostkey You should now check the configration by issuing the command ``gvpectrl -c /etc/gvpe -s'' on each node and verify it's output. == STEP 4: starting gvpe == You should then start gvpe on each node by issuing a command like: gvpe -D -linfo first # first is the nodename This will make the gvpe stay in foreground. You should then see "connection established" messages. If you don't see them check your firewall and routing (use tcpdump ;). If this works you should check your networking setup by pinging various endpoints. To make gvpe run more permanently you can either run it as a daemon (by starting it without the ``-D'' switch), or, much better, from your inittab. I use a line like this on my systems: t1:2345:respawn:/opt/gvpe/sbin/gvpe -D -L first >/dev/null 2>&1 == STEP 5: enjoy == ... and play around. Sending a -HUP (``gvpectrl -kHUP'') to the daemon will make it try to connect to all other nodes again. If you run it from inittab, as is recommended, ``gvpectrl -k'' (or simply ``killall gvpe'') will kill the daemon, start it again, making it read it's configuration files again. ==== SEE ALSO ==== gvpe.osdep(5) for OS-depedendent information, gvpe.conf(5), gvpectrl(8), and for a description of the transports, protocol, and routing algorithm, gvpe.protocol(7). The GVPE mailinglist, at , or ``gvpe@lists.schmorp.de''. ==== AUTHOR ==== Marc Lehmann ==== COPYRIGHTS AND LICENSES ==== GVPE itself is distributed under the GENERAL PUBLIC LICENSE (see the file COPYING that should be part of your distribution). In some configurations it uses modified versions of the tinc vpn suite, which is also available under the GENERAL PUBLIC LICENSE. gvpe-3.0/Makefile.in0000644000000000000000000004427713011103322011251 00000000000000# Makefile.in generated by automake 1.7.9 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # 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@ 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 = : host_triplet = @host@ 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@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_TUNTAP = @HAVE_TUNTAP@ IFSUBTYPE = @IFSUBTYPE@ IFTYPE = @IFTYPE@ INCLUDES = @INCLUDES@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DAEMON = @LDFLAGS_DAEMON@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LINUX_IF_TUN_H = @LINUX_IF_TUN_H@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ POSUB = @POSUB@ RANLIB = @RANLIB@ ROHC_FALSE = @ROHC_FALSE@ ROHC_TRUE = @ROHC_TRUE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ AUTOMAKE_OPTIONS = gnu SUBDIRS = m4 lib src doc po ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = config.rpath mkinstalldirs depcomp TODO \ libev/ev.c libev/ev.h libev/libev.m4 libev/ev++.h \ libev/ev_epoll.c libev/ev_kqueue.c libev/ev_poll.c libev/ev_select.c \ libev/ev_vars.h libev/ev_win32.c libev/ev_wrap.h CVS_CREATED = ABOUT-NLS configure aclocal.m4 config.h.in config.guess \ config.sub install-sh missing mkinstalldirs \ stamp-h.in m4/Makefile.am po/Makefile.in.in \ po/vpe.pot po/*.sed po/*.header po/*.sin po/Rules-quot \ src/.libs intl depcomp subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure \ ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL Makefile.am NEWS \ TODO aclocal.m4 config.guess config.h.in config.rpath \ config.sub configure configure.ac depcomp install-sh missing \ mkinstalldirs DIST_SUBDIRS = $(SUBDIRS) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.ac m4/aclocal-include.m4 m4/codeset.m4 m4/gettext.m4 m4/glibc21.m4 m4/iconv.m4 m4/intdiv0.m4 m4/inttypes-pri.m4 m4/inttypes.m4 m4/inttypes_h.m4 m4/isc-posix.m4 m4/lcmessage.m4 m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4 m4/openssl.m4 m4/progtest.m4 m4/stdint_h.m4 m4/tuntap.m4 m4/uintmax_t.m4 m4/ulonglong.m4 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: @MAINTAINER_MODE_TRUE@ $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOHEADER) touch $(srcdir)/config.h.in distclean-hdr: -rm -f config.h stamp-h1 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 ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS 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-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 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkinstalldirs) $(distdir)/libev $(distdir)/po @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"; \ $(mkinstalldirs) "$(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 -755 \ -exec chmod u+rwx,go+rx {} \; -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 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 $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod u+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 ../.. && $(mkinstalldirs) "$$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-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;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 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 mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: 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 -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: 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 check check-am clean \ clean-generic clean-recursive ctags ctags-recursive dist \ dist-all dist-gzip distcheck distclean distclean-generic \ distclean-hdr distclean-recursive distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am dvi-recursive info \ info-am info-recursive install install-am install-data \ install-data-am install-data-recursive install-exec \ install-exec-am install-exec-recursive install-info \ install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # 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: gvpe-3.0/configure0000744000000000000000000110314313011103322011076 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="src/gvpe.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 INCLUDES ROHC_FALSE ROHC_TRUE LDFLAGS_DAEMON HAVE_TUNTAP LINUX_IF_TUN_H ALLOCA CXXCPP IFSUBTYPE IFTYPE RANLIB LN_S EGREP GREP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP POSUB LTLIBINTL LIBINTL INTLLIBS LTLIBICONV LIBICONV USE_NLS 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 MSGMERGE XGETTEXT GMSGFMT MSGFMT MKINSTALLDIRS MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__leading_dot SET_MAKE AWK INSTALL_STRIP_PROGRAM STRIP install_sh AMTAR MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build 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 runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_dependency_tracking with_gnu_ld enable_rpath with_libiconv_prefix enable_nls with_libintl_prefix enable_iftype with_kernel with_openssl_include with_openssl_lib enable_threads enable_static_daemon enable_icmp enable_tcp enable_http_proxy enable_dns enable_rsa_length enable_hmac_length enable_max_mtu enable_compression enable_cipher enable_hmac_digest enable_auth_digest ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC 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' runstatedir='${localstatedir}/run' 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= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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 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 cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors --disable-rpath do not hardcode runtime library paths --disable-nls do not use Native Language Support --enable-iftype=TYPE/SUBTYPE Use kernel/net device interface TYPE/SUBTYPE. Working combinations are (see doc/gvpe.osdep.5.pod): "native/linux" "tincd/linux" "tincd/netbsd" "tincd/freebsd" "tincd/openbsd" "native/darwin" "tincd/darwin" "native/cygwin"; Untested combinations are: "tincd/bsd" "tincd/solaris" "tincd/mingw" "tincd/raw_socket" "tincd/uml_socket"; Broken combinations are: "tincd/cygwin"; The default is to autodetect. --enable-threads try to use threads for long-running asynchronous operations (default enabled). --enable-static-daemon enable statically linked daemon. --disable-icmp enable icmp protocol support (default enabled). --disable-tcp enable tcp protocol support (default enabled). --disable-http-proxy enable http proxy connect support (default enabled). --enable-dns enable dns tunnel protocol support (default disabled). --enable-rsa-length=BITS use BITS rsa keys (default 3072). Allowed values are 2048-10240. --enable-hmac-length=BYTES use a hmac of length BYTES bytes (default 12). Allowed values are 4, 8, 12, 16. --enable-max-mtu=BYTES enable mtu sizes upto BYTES bytes (default 1500). Use 9100 for jumbogram support. --disable-compression Disable compression support. --enable-cipher=CIPHER Select the symmetric cipher (default "aes-128"). Must be one of "aes-128" (rijndael), "aes-192", or "aes-256". --enable-hmac-digest=HMAC Select the HMAC digest algorithm to use (default "sha1"). Must be one of "sha512", "sha256", "sha1", "ripemd160", "whirlpool". --enable-auth-digest=DIGEST Select the hmac algorithm to use (default "sha512"). Must be one of "sha512", "sha256", "whirlpool". Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld default=no --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-libintl-prefix=DIR search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-kernel=dir give the directory with kernel sources (default: /usr/src/linux) --with-openssl-include=DIR OpenSSL headers directory (without trailing /openssl) --with-openssl-lib=DIR OpenSSL library directory Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags 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 the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" 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 $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" 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 $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_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_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; 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_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; 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:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; 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_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; 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:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; 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_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; 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}- am__api_version="1.7" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; 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 as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$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_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} 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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$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_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 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=gvpe VERSION=3.0 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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac 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" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGFMT" in /*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 $as_echo "$GMSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case "$XGETTEXT" in /*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f messages.po # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGMERGE" in /*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if $ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GMSGFMT" != ":"; then if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 $as_echo "found $GMSGFMT program is not GNU msgfmt; ignore it" >&6; } GMSGFMT=":" fi fi if test "$XGETTEXT" != ":"; then if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } XGETTEXT=":" fi rm -f messages.po fi ac_config_commands="$ac_config_commands default-1" if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" 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:${as_lineno-$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:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; 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:${as_lineno-$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 # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 $as_echo_n "checking for ld used by GCC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${acl_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break fi fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$acl_cv_path_LD" if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${acl_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then acl_cv_prog_gnu_ld=yes else acl_cv_prog_gnu_ld=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5 $as_echo "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 $as_echo_n "checking for shared library run path origin... " >&6; } if ${acl_cv_rpath+:} false; then : $as_echo_n "(cached) " >&6 else CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 $as_echo "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; : else enable_rpath=yes fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libiconv-prefix was given. if test "${with_libiconv_prefix+set}" = set; then : withval=$with_libiconv_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBICONV= LTLIBICONV= INCICONV= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='iconv ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" else LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" ;; esac done fi else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } LIBINTL= LTLIBINTL= POSUB= if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 $as_echo_n "checking for GNU gettext in libc... " >&6; } if ${gt_cv_func_gnugettext1_libc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libc=yes else gt_cv_func_gnugettext1_libc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libc" >&5 $as_echo "$gt_cv_func_gnugettext1_libc" >&6; } if test "$gt_cv_func_gnugettext1_libc" != "yes"; then am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 $as_echo_n "checking how to link with libiconv... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 $as_echo "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test "${with_libintl_prefix+set}" = set; then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBINTL= LTLIBINTL= INCINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 $as_echo_n "checking for GNU gettext in libintl... " >&6; } if ${gt_cv_func_gnugettext1_libintl+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (); int main () { bindtextdomain ("", ""); return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias (0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libintl=yes else gt_cv_func_gnugettext1_libintl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (); int main () { bindtextdomain ("", ""); return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias (0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext1_libintl=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libintl" >&5 $as_echo "$gt_cv_func_gnugettext1_libintl" >&6; } fi if test "$gt_cv_func_gnugettext1_libc" = "yes" \ || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ && test "$PACKAGE" != gettext; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then $as_echo "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 $as_echo_n "checking how to link with libintl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 $as_echo "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi INTLLIBS="$LIBINTL" # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions # in the latter don't make it into the configure-time tests. $as_echo "#define _GNU_SOURCE 1" >>confdefs.h # do NOT define POSIX_SOURCE, sicne this clashes with many BSDs ALL_LINGUAS="" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu 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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; 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_CXX_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_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 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" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else 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" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" 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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:${as_lineno-$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; 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:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Check whether --enable-iftype was given. if test "${enable_iftype+set}" = set; then : enableval=$enable_iftype; IFTYPE=`echo $enableval | sed s%/.*%%` IFSUBTYPE=`echo $enableval | sed s%.*/%%` fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kernel networking interface type" >&5 $as_echo_n "checking for kernel networking interface type... " >&6; } if test "x$IFTYPE" = "x"; then case $target_os in *linux*) IFTYPE=native IFSUBTYPE=linux $as_echo "#define HAVE_LINUX 1" >>confdefs.h ;; *freebsd*) IFTYPE=tincd IFSUBTYPE=freebsd $as_echo "#define HAVE_FREEBSD 1" >>confdefs.h ;; *darwin*) IFTYPE=native IFSUBTYPE=darwin $as_echo "#define HAVE_DARWIN 1" >>confdefs.h ;; *solaris*) IFTYPE=tincd IFSUBTYPE=solaris $as_echo "#define HAVE_SOLARIS 1" >>confdefs.h ;; *openbsd*) IFTYPE=tincd IFSUBTYPE=openbsd $as_echo "#define HAVE_OPENBSD 1" >>confdefs.h ;; *netbsd*) IFTYPE=tincd IFSUBTYPE=netbsd $as_echo "#define HAVE_NETBSD 1" >>confdefs.h ;; *cygwin*) IFTYPE=native IFSUBTYPE=cygwin $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h ;; *) as_fn_error $? "\"Unknown operating system.\"" "$LINENO" 5 ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IFTYPE/$IFSUBTYPE" >&5 $as_echo "$IFTYPE/$IFSUBTYPE" >&6; } IFTYPE=$IFTYPE IFSUBTYPE=$IFSUBTYPE cat >>confdefs.h <<_ACEOF #define IFTYPE "$IFTYPE" _ACEOF cat >>confdefs.h <<_ACEOF #define IFSUBTYPE "$IFSUBTYPE" _ACEOF cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache 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 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:${as_lineno-$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 ${ac_cv_prog_CXXCPP+:} false; 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i 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:${as_lineno-$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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi 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:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in tr1/unordered_map ext/hash_map clocale do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h inttypes.h limits.h malloc.h stdint.h strings.h syslog.h unistd.h \ sys/file.h sys/ioctl.h sys/param.h sys/time.h netinet/in_systm.h sys/cygwin.h \ sys/mman.h netinet/in.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in arpa/inet.h net/ethernet.h net/if.h netinet/ip.h netinet/tcp.h netinet/in_systm.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " #include #include #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_NETINET_IN_SYSTM_H # include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* 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 sort of thing. */ char tx; char *t = &tx; 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 sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 $as_echo_n "checking for socklen_t... " >&6; } if ${ac_cv_type_socklen_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { socklen_t len = 42; return len; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_type_socklen_t=yes else ac_cv_type_socklen_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_socklen_t" >&5 $as_echo "$ac_cv_type_socklen_t" >&6; } if test $ac_cv_type_socklen_t = yes; then $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5 $as_echo_n "checking for struct addrinfo... " >&6; } if ${ac_cv_struct_addrinfo+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct addrinfo ai; ai.ai_family = AF_INET; return ai.ai_family; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_struct_addrinfo=yes else ac_cv_struct_addrinfo=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_addrinfo" >&5 $as_echo "$ac_cv_struct_addrinfo" >&6; } if test $ac_cv_struct_addrinfo = yes; then $as_echo "#define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_func in asprintf daemon get_current_dir_name putenv select strerror strsignal strtol unsetenv mlockall do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_connect=yes else ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi for ac_header in sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF else if test $(uname) = Linux; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime syscall" >&5 $as_echo_n "checking for clock_gettime syscall... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_have_clock_syscall=1 $as_echo "#define HAVE_CLOCK_SYSCALL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi unset ac_cv_func_clock_gettime for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF fi done fi fi done for ac_func in nanosleep do : ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" if test "x$ac_cv_func_nanosleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NANOSLEEP 1 _ACEOF else if test -z "$LIBEV_M4_AVOID_LIBRT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 $as_echo_n "checking for nanosleep in -lrt... " >&6; } if ${ac_cv_lib_rt_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_nanosleep=yes else ac_cv_lib_rt_nanosleep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 $as_echo "$ac_cv_lib_rt_nanosleep" >&6; } if test "x$ac_cv_lib_rt_nanosleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi unset ac_cv_func_nanosleep for ac_func in nanosleep do : ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" if test "x$ac_cv_func_nanosleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NANOSLEEP 1 _ACEOF fi done fi fi done if test -z "$LIBEV_M4_AVOID_LIBM"; then LIBM=m fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing floor" >&5 $as_echo_n "checking for library containing floor... " >&6; } if ${ac_cv_search_floor+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char floor (); int main () { return floor (); ; return 0; } _ACEOF for ac_lib in '' $LIBM; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_floor=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_floor+:} false; then : break fi done if ${ac_cv_search_floor+:} false; then : else ac_cv_search_floor=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_floor" >&5 $as_echo "$ac_cv_search_floor" >&6; } ac_res=$ac_cv_search_floor if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_FLOOR 1" >>confdefs.h fi 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 cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache # Check whether --with-kernel was given. if test "${with_kernel+set}" = set; then : withval=$with_kernel; kerneldir="$withval" else kerneldir="/usr/src/linux" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linux/if_tun.h" >&5 $as_echo_n "checking for linux/if_tun.h... " >&6; } if ${tinc_cv_linux_if_tun_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "$kerneldir/include/linux/if_tun.h" int main () { int a = IFF_TAP; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : if_tun_h="\"$kerneldir/include/linux/if_tun.h\"" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int a = IFF_TAP; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : if_tun_h="default" else if_tun_h="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $if_tun_h = no; then tinc_cv_linux_if_tun_h=none else tinc_cv_linux_if_tun_h="$if_tun_h" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tinc_cv_linux_if_tun_h" >&5 $as_echo "$tinc_cv_linux_if_tun_h" >&6; } if test $tinc_cv_linux_if_tun_h != none; then $as_echo "#define HAVE_TUNTAP 1" >>confdefs.h if test $tinc_cv_linux_if_tun_h != default; then cat >>confdefs.h <<_ACEOF #define LINUX_IF_TUN_H $tinc_cv_linux_if_tun_h _ACEOF fi fi tinc_ac_save_CPPFLAGS="$CPPFLAGS" # Check whether --with-openssl-include was given. if test "${with_openssl_include+set}" = set; then : withval=$with_openssl_include; openssl_include="$withval" CFLAGS="$CFLAGS -I$withval" CPPFLAGS="$CPPFLAGS -I$withval" fi # Check whether --with-openssl-lib was given. if test "${with_openssl_lib+set}" = set; then : withval=$with_openssl_lib; openssl_lib="$withval" LIBS="$LIBS -L$withval" fi for ac_header in openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else as_fn_error $? "OpenSSL header files not found." "$LINENO" 5; break fi done CPPFLAGS="$tinc_ac_save_CPPFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA1_Init in -lcrypto" >&5 $as_echo_n "checking for SHA1_Init in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_SHA1_Init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SHA1_Init (); int main () { return SHA1_Init (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_crypto_SHA1_Init=yes else ac_cv_lib_crypto_SHA1_Init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA1_Init" >&5 $as_echo "$ac_cv_lib_crypto_SHA1_Init" >&6; } if test "x$ac_cv_lib_crypto_SHA1_Init" = xyes; then : LIBS="$LIBS -lcrypto" else as_fn_error $? "OpenSSL libraries not found." "$LINENO" 5 fi for ac_func in RAND_pseudo_bytes OPENSSL_add_all_algorithms_noconf OpenSSL_add_all_algorithms SSLeay_add_all_algorithms do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_cxx_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : LIBS="$LIBS -ldl" else as_fn_error $? "OpenSSL depends on libdl." "$LINENO" 5 fi fi ac_fn_cxx_check_func "$LINENO" "inflate" "ac_cv_func_inflate" if test "x$ac_cv_func_inflate" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5 $as_echo_n "checking for inflate in -lz... " >&6; } if ${ac_cv_lib_z_inflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflate (); int main () { return inflate (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_z_inflate=yes else ac_cv_lib_z_inflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5 $as_echo "$ac_cv_lib_z_inflate" >&6; } if test "x$ac_cv_lib_z_inflate" = xyes; then : LIBS="$LIBS -lz" else as_fn_error $? "OpenSSL depends on libz." "$LINENO" 5 fi fi if test "x$openssl_include" != x; then CXXFLAGS="$CXXFLAGS -I$openssl_include" fi # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; try_threads=$enableval else try_threads=yes fi if test "x$try_threads" = xyes; then ac_fn_cxx_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : LIBS="$LIBS -lpthread" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t id; pthread_create (&id, 0, 0, 0); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define ENABLE_PTHREADS 1 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi # Check whether --enable-static-daemon was given. if test "${enable_static_daemon+set}" = set; then : enableval=$enable_static_daemon; LDFLAGS_DAEMON=-static fi if test x$rohc = xtrue; then ROHC_TRUE= ROHC_FALSE='#' else ROHC_TRUE='#' ROHC_FALSE= fi ICMP=1 # Check whether --enable-icmp was given. if test "${enable_icmp+set}" = set; then : enableval=$enable_icmp; if test "x$enableval" = xno; then ICMP=0 fi fi if test "x$ICMP" = x1; then cat >>confdefs.h <<_ACEOF #define ENABLE_ICMP 1 _ACEOF fi TCP=1 # Check whether --enable-tcp was given. if test "${enable_tcp+set}" = set; then : enableval=$enable_tcp; if test "x$enableval" = xno; then TCP=0 fi fi if test "x$TCP" = x1; then cat >>confdefs.h <<_ACEOF #define ENABLE_TCP 1 _ACEOF fi HTTP=1 # Check whether --enable-http-proxy was given. if test "${enable_http_proxy+set}" = set; then : enableval=$enable_http_proxy; if test "x$enableval" = xno; then HTTP=0 fi fi if test "x$HTTP" = x1; then cat >>confdefs.h <<_ACEOF #define ENABLE_HTTP_PROXY 1 _ACEOF fi # Check whether --enable-dns was given. if test "${enable_dns+set}" = set; then : enableval=$enable_dns; ac_fn_cxx_check_header_mongrel "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" if test "x$ac_cv_header_gmp_h" = xyes; then : else as_fn_error $? "gmp.h not found, required for --enable-dns" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgmp" >&5 $as_echo_n "checking for main in -lgmp... " >&6; } if ${ac_cv_lib_gmp_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgmp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gmp_main=yes else ac_cv_lib_gmp_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp_main" >&5 $as_echo "$ac_cv_lib_gmp_main" >&6; } if test "x$ac_cv_lib_gmp_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGMP 1 _ACEOF LIBS="-lgmp $LIBS" else as_fn_error $? "libgmp not found, required for --enable-dns" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define ENABLE_DNS 1 _ACEOF fi RSA=3072 # Check whether --enable-rsa-length was given. if test "${enable_rsa_length+set}" = set; then : enableval=$enable_rsa_length; RSA=$enableval fi cat >>confdefs.h <<_ACEOF #define RSABITS $RSA _ACEOF HMACSIZE=12 # Check whether --enable-hmac-length was given. if test "${enable_hmac_length+set}" = set; then : enableval=$enable_hmac_length; HMACSIZE=$enableval fi cat >>confdefs.h <<_ACEOF #define HMACLENGTH $HMACSIZE _ACEOF MTU=1500 # Check whether --enable-max-mtu was given. if test "${enable_max_mtu+set}" = set; then : enableval=$enable_max_mtu; MTU=$enableval fi cat >>confdefs.h <<_ACEOF #define MAX_MTU ($MTU + 14) _ACEOF COMPRESS=1 # Check whether --enable-compression was given. if test "${enable_compression+set}" = set; then : enableval=$enable_compression; if test "x$enableval" = xno; then COMPRESS=0 fi fi cat >>confdefs.h <<_ACEOF #define ENABLE_COMPRESSION $COMPRESS _ACEOF CIPHER=aes_128_ctr # Check whether --enable-cipher was given. if test "${enable_cipher+set}" = set; then : enableval=$enable_cipher; #if test "x$enableval" = xbf ; then CIPHER=bf_ctr ; fi if test "x$enableval" = xaes-128 ; then CIPHER=aes_128_ctr ; fi if test "x$enableval" = xaes-192 ; then CIPHER=aes_192_ctr ; fi if test "x$enableval" = xaes-256 ; then CIPHER=aes_256_ctr ; fi #if test "x$enableval" = xcamellia-128; then CIPHER=camellia_128_ctr; fi #if test "x$enableval" = xcamellia-256; then CIPHER=camellia_256_ctr; fi fi cat >>confdefs.h <<_ACEOF #define ENABLE_CIPHER EVP_${CIPHER} _ACEOF HMAC=sha1 # Check whether --enable-hmac-digest was given. if test "${enable_hmac_digest+set}" = set; then : enableval=$enable_hmac_digest; if test "x$enableval" = xwhirlpool; then HMAC=whirlpool; fi if test "x$enableval" = xsha512 ; then HMAC=sha512 ; fi if test "x$enableval" = xsha256 ; then HMAC=sha256 ; fi if test "x$enableval" = xsha1 ; then HMAC=sha1 ; fi if test "x$enableval" = xripemd160; then HMAC=ripemd160; fi fi cat >>confdefs.h <<_ACEOF #define ENABLE_HMAC EVP_${HMAC} _ACEOF AUTH=sha512 # Check whether --enable-auth-digest was given. if test "${enable_auth_digest+set}" = set; then : enableval=$enable_auth_digest; if test "x$enableval" = xwhirlpool; then AUTH=whirlpool; fi if test "x$enableval" = xsha512 ; then AUTH=sha512 ; fi if test "x$enableval" = xsha256 ; then AUTH=sha256 ; fi fi cat >>confdefs.h <<_ACEOF #define ENABLE_AUTH EVP_${AUTH} _ACEOF if $CXX -v --help 2>&1 | grep -q fno-rtti; then CXXFLAGS="$CXXFLAGS -fno-rtti" fi #if $CXX -v --help 2>&1 | grep -q fexceptions; then # CXXFLAGS="$CXXFLAGS -fno-exceptions" #fi LIBS="$EXTRA_LIBS $LIBS" ac_config_files="$ac_config_files Makefile po/Makefile.in src/Makefile doc/Makefile lib/Makefile m4/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ROHC_TRUE}" && test -z "${ROHC_FALSE}"; then as_fn_error $? "conditional \"ROHC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 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:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. 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 and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' 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=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # # Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it # from automake. eval 'ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" 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" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers 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= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _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 < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || 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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :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_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in "$ac_file" | "$ac_file":* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for "$ac_file"" >`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "default-1":C) for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' fi case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= GMOFILES= UPDATEPOFILES= DUMMYPOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done ;; "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; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo echo "***" echo "*** Configuration Summary" echo "***" echo "*** Kernel Iface: $IFTYPE/$IFSUBTYPE" echo "*** RSA size: $RSA" echo "*** Cipher used: $CIPHER" echo "*** Digest used: $DIGEST" echo "*** Authdigest: $AUTH" echo "*** HMAC length: $HMAC" echo "*** Max. MTU: $MTU" echo "***" echo "*** Enable options:" grep ENABLE_ config.h | sed -e 's/^/*** /' if test "$HMACSIZE" -lt 12; then echo "***" echo "*** WARNING: The hmac length you have chosen ($HMACSIZE) is quite insecure" fi echo "***" echo gvpe-3.0/ABOUT-NLS0000644000000000000000000006015711046631516010447 00000000000000Notes on the Free Translation Project ************************************* Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work at translations should contact the appropriate team. When reporting bugs in the `intl/' directory or bugs which may be related to internationalization, you should tell about the version of `gettext' which is used. The information can be found in the `intl/VERSION' file, in internationalized packages. Quick configuration advice ========================== If you want to exploit the full power of internationalization, you should configure it using ./configure --with-included-gettext to force usage of internationalizing routines provided within this package, despite the existence of internationalizing capabilities in the operating system where this package is being installed. So far, only the `gettext' implementation in the GNU C library version 2 provides as many features (such as locale alias, message inheritance, automatic charset conversion or plural form handling) as the implementation here. It is also not possible to offer this additional functionality on top of a `catgets' implementation. Future versions of GNU `gettext' will very likely convey even more functionality. So it might be a good idea to change to GNU `gettext' as soon as possible. So you need _not_ provide this option if you are using GNU libc 2 or you have installed a recent copy of the GNU gettext package with the included `libintl'. INSTALL Matters =============== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU `gettext' functions. If not, the GNU `gettext' own library will be used. This library is wholly contained within this package, usually in the `intl/' subdirectory, so prior installation of the GNU `gettext' package is _not_ required. Installers may use special options at configuration time for changing the default behaviour. The commands: ./configure --with-included-gettext ./configure --disable-nls will respectively bypass any pre-existing `gettext' to use the internationalizing routines provided within this package, or else, _totally_ disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl.a' file and will decide to use this. This might be not what is desirable. You should use the more recent version of the GNU `gettext' library. I.e. if the file `intl/VERSION' shows that the library which comes with this package is more recent, you should use ./configure --with-included-gettext to prevent auto-detection. The configuration process will not test for the `catgets' function and therefore it will not be used. The reason is that even an emulation of `gettext' on top of `catgets' could not provide all the extensions of the GNU `gettext' library. Internationalized packages have usually many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. Using This Package ================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate `LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, and `CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute `setenv LANG de_DE' (in `csh'), `export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of `LL_CC', with `LL' denoting the language and `CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as `LL' or `LL_CC.ENCODING'. You can get the list of locales supported by your system for your country by running the command `locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called `LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' for the purpose of message handling, but you still need to have `LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. In the `LANGUAGE' environment variable, but not in the `LANG' environment variable, `LL_CC' combinations can be abbreviated as `LL' to denote the language's main dialect. For example, `de' is equivalent to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' (Portuguese as spoken in Portugal) in this context. Translating Teams ================= For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, `http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `translation@iro.umontreal.ca' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skill are praised more than programming skill, here. Available Packages ================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of August 2002. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files be bg ca cs da de el en eo es et fi fr +----------------------------------------+ a2ps | [] [] [] [] | ap-utils | | bash | [] [] [] [] | bfd | [] [] | binutils | [] [] | bison | [] [] [] [] | clisp | | clisp | [] [] [] [] | clisplow | | cpio | [] [] [] [] | darkstat | () | diffutils | [] [] [] [] [] [] | enscript | [] [] | error | [] [] [] | fetchmail | [] () [] [] [] () | fileutils | [] [] [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] [] [] | gas | [] [] | gawk | [] [] [] | gcal | [] [] | gcc | [] [] | gettext | [] [] [] [] [] | gnupg | [] [] [] [] [] [] [] | gprof | [] [] | gpsdrive | () () () () () | grep | [] [] [] [] [] [] [] [] | gretl | [] | gthumb | () () () | hello | [] [] [] [] [] [] [] [] [] | id-utils | [] [] [] | indent | [] [] [] [] [] | jpilot | () [] [] [] | jwhois | [] [] | kbd | [] [] [] | ld | [] [] | libc | [] [] [] [] [] [] [] [] | libiconv | [] [] [] [] | lifelines | () () | lilypond | [] [] | lingoteach | [] [] | lingoteach_lessons| () () | lynx | [] [] [] [] [] | m4 | [] [] [] [] [] | make | [] [] [] [] | man-db | [] () () [] () () | mysecretdiary | [] [] [] | nano | [] () [] [] [] [] | nano_1_0 | [] () [] [] [] [] | opcodes | [] [] [] | parted | [] [] [] [] [] | ptx | [] [] [] [] [] [] [] | python | | recode | [] [] [] [] [] [] | sed | [] [] [] [] [] [] [] [] [] [] | sh-utils | [] [] [] [] | sharutils | [] [] [] [] [] [] [] | sketch | () [] () | soundtracker | [] [] [] | sp | [] | tar | [] [] [] [] [] [] | texinfo | [] [] [] [] [] | textutils | [] [] [] [] [] | util-linux | [] [] [] [] [] [] | vorbis-tools | [] | wastesedge | | wdiff | [] [] [] [] [] [] | wget | [] [] [] [] [] [] [] [] [] [] | +----------------------------------------+ be bg ca cs da de el en eo es et fi fr 0 2 19 10 30 44 9 1 12 44 17 6 53 gl he hr hu id it ja ko lv nb nl nn +-------------------------------------+ a2ps | () () [] | ap-utils | | bash | [] | bfd | [] | binutils | [] | bison | [] [] [] [] | clisp | | clisp | [] | clisplow | | cpio | [] [] [] [] | darkstat | | diffutils | [] [] [] [] [] | enscript | [] [] | error | [] | fetchmail | [] | fileutils | [] [] [] | findutils | [] [] [] [] [] [] [] [] | flex | [] | gas | | gawk | [] | gcal | | gcc | [] | gettext | [] [] | gnupg | [] [] [] [] | gprof | [] | gpsdrive | [] () () | grep | [] [] [] [] [] [] [] | gretl | | gthumb | () () | hello | [] [] [] [] [] [] [] [] [] [] [] [] | id-utils | [] [] | indent | [] [] [] [] | jpilot | () () | jwhois | [] [] | kbd | | ld | | libc | [] [] [] [] | libiconv | [] [] [] | lifelines | | lilypond | [] | lingoteach | [] | lingoteach_lessons| | lynx | [] [] [] [] | m4 | [] [] [] [] | make | [] [] [] [] [] [] | man-db | () () | mysecretdiary | [] | nano | [] [] [] [] | nano_1_0 | [] [] [] [] [] | opcodes | [] [] | parted | [] [] [] | ptx | [] [] [] [] [] | python | | recode | [] [] [] | sed | [] [] [] [] [] [] [] [] | sh-utils | [] [] [] | sharutils | [] [] [] | sketch | () | soundtracker | [] [] | sp | | tar | [] [] [] [] [] [] | texinfo | [] [] [] | textutils | [] [] [] [] | util-linux | () [] | vorbis-tools | [] | wastesedge | | wdiff | [] [] [] | wget | [] [] [] [] [] [] | +-------------------------------------+ gl he hr hu id it ja ko lv nb nl nn 23 9 12 19 16 13 26 9 1 7 19 3 no pl pt pt_BR ru sk sl sv tr uk zh_CN zh_TW +----------------------------------------------+ a2ps | () () () [] [] [] [] [] | 10 ap-utils | () | 0 bash | [] | 6 bfd | [] [] | 5 binutils | [] [] | 5 bison | [] [] [] [] | 12 clisp | | 0 clisp | | 5 clisplow | | 0 cpio | [] [] [] [] | 12 darkstat | [] [] () () | 2 diffutils | [] [] [] [] [] [] | 17 enscript | [] [] [] [] | 8 error | [] [] [] | 7 fetchmail | () () [] | 6 fileutils | [] [] [] [] [] [] | 14 findutils | [] [] [] [] [] [] [] | 21 flex | [] [] [] | 9 gas | [] | 3 gawk | [] [] | 6 gcal | [] [] | 4 gcc | [] | 4 gettext | [] [] [] [] [] [] | 13 gnupg | [] [] [] | 14 gprof | [] [] | 5 gpsdrive | [] [] | 3 grep | [] [] [] [] [] | 20 gretl | | 1 gthumb | () () [] | 1 hello | [] [] [] [] [] [] [] | 28 id-utils | [] [] [] [] | 9 indent | [] [] [] [] [] | 14 jpilot | () () [] [] | 5 jwhois | [] () () [] [] | 7 kbd | [] [] | 5 ld | [] [] | 4 libc | [] [] [] [] [] [] | 18 libiconv | [] [] [] [] [] | 12 lifelines | [] | 1 lilypond | [] | 4 lingoteach | [] [] | 5 lingoteach_lessons| () | 0 lynx | [] [] [] [] | 13 m4 | [] [] [] [] | 13 make | [] [] [] [] [] | 15 man-db | | 3 mysecretdiary | [] [] [] | 7 nano | [] [] [] [] | 13 nano_1_0 | [] [] [] [] | 14 opcodes | [] [] [] | 8 parted | [] [] [] [] | 12 ptx | [] [] [] [] [] [] [] | 19 python | | 0 recode | [] [] [] [] [] [] | 15 sed | [] [] [] [] [] [] | 24 sh-utils | [] [] | 9 sharutils | [] [] [] [] | 14 sketch | [] () [] | 4 soundtracker | [] | 6 sp | | 1 tar | [] [] [] [] [] [] [] | 19 texinfo | [] [] | 10 textutils | [] [] [] [] [] | 14 util-linux | [] [] [] | 10 vorbis-tools | [] | 3 wastesedge | | 0 wdiff | [] [] [] [] [] | 14 wget | [] [] [] [] [] [] [] [] | 24 +----------------------------------------------+ 37 teams no pl pt pt_BR ru sk sl sv tr uk zh_CN zh_TW 68 domains 4 15 2 28 28 12 10 49 43 4 1 9 609 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If August 2002 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at `http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. Using `gettext' in new packages =============================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU `gettext' in your package. Of course you have to respect the GNU Library General Public License which covers the use of the GNU `gettext' library. This means in particular that even non-free programs can use `libintl' as a shared library, whereas only free software can use `libintl' as a static library or use modified versions of `libintl'. Once the sources are changed appropriately and the setup can handle to use of `gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact `translation@iro.umontreal.ca' to make the `.pot' files available to the translation teams. gvpe-3.0/AUTHORS0000644000000000000000000000035211046631706010260 00000000000000Gvpe Author: Marc Lehmann Although the actual gvpe code was completely rewritten, some configure macros and were taken from the tinc package, by Guus Sliepen and Ivo Timmermans . gvpe-3.0/COPYING0000644000000000000000000004311012011645431010233 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gvpe-3.0/ChangeLog0000644000000000000000000000014211046631516010756 00000000000000This file is unused, see the NEWS file for changes (and add documentation for any changes there). gvpe-3.0/INSTALL0000644000000000000000000002203012011645431010227 00000000000000Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. gvpe-3.0/Makefile.am0000644000000000000000000000116412170155330011237 00000000000000## Process this file with automake to get Makefile.in AUTOMAKE_OPTIONS = gnu SUBDIRS = m4 lib src doc po ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = config.rpath mkinstalldirs depcomp TODO \ libev/ev.c libev/ev.h libev/libev.m4 libev/ev++.h \ libev/ev_epoll.c libev/ev_kqueue.c libev/ev_poll.c libev/ev_select.c \ libev/ev_vars.h libev/ev_win32.c libev/ev_wrap.h CVS_CREATED = ABOUT-NLS configure aclocal.m4 config.h.in config.guess \ config.sub install-sh missing mkinstalldirs \ stamp-h.in m4/Makefile.am po/Makefile.in.in \ po/vpe.pot po/*.sed po/*.header po/*.sin po/Rules-quot \ src/.libs intl depcomp gvpe-3.0/NEWS0000644000000000000000000004035513011103305007675 00000000000000GVPE NEWS 3.0 Thu Nov 10 15:39:58 CET 2016 - INCOMPATIBLE CHANGE: core protocol version 1.0. - INCOMPATIBLE CHANGE: node sections are now introduced with "node nodename", not "node = nodename". - INCOMPATIBLE CHANGE: gvpectrl -g will now generate a single keypair, while -G will try to generate all keypairs as before. - openssl 1.0.2 is the latest supported openssl release, openssl 1.1.0 is not supported at the moment as the work to make it compatible to both versions is just too much. a switch to openssl 1.1 or another library will be done in a future release. - update examples to not generate keys centrally, but locally on each node. - add workaround for temporary/rare ENOBUFS condition. - while individual packets couldn't be replayed, a whole session could be replayed - this has been fixed by an extra key exchange. - fix a delete vs. delete [] mismatch in the central logging function. - in addition to rsa key exchange and authentication, the handshake now adds a diffie-hellman key exchange (using curve25119) for perfect forward secrecy. mac and cipher keys are derived using HKDF. - rsa key sizes are now configurable and larger (default is 3072). correspondingly, the minimum mtu is no longer 296 but 576. - fixed a potential (unverified) buffer overrun on rsa decryption. - new per-node low-power setting that tries to reduce cpu/network usage. - router reconnects could cause excessive rekeying on other connections. - gvpectrl no longer generates all missing public keys, but only missing private keys. private keys are also put into the configured location. - the pid-file now accepts %s as nodename as elsewhere. - switch to counter mode (only aes supported at the moment in openssl). this gets rid of the need to generate a random iv, is likely more secure (and, as a side effect, gets rid of slow randomness generation. counter mode is often faster then cbc mode as well, and packets are smaller). - no longer use RAND_bytes to generate session keys - you NEED a real source of entropy now (e.g. egd or /dev/random - see the openssl documentation). - multiple node statements for the same node are now supported and will be merged. - a new directive "global" switches back to the global section of the config file. - if-up scripts can now be specified with absolute paths. - new global option: serial, to detect configuration mismatches. - use HKDF as authentication proof, not HMAC or a plain hash (hint by Ilmari Karonen). - during rekeying or connection establishments, hmac authentication errors could occur and reset the connection. Transient hmac authentication errors are now being ignored for 3 seconds. - log the reason for a conneciton loss. - use a (hopefully) constant time memcmp to compare internal secrets. - fix a (harmless) errornous out of bounds stack read that would trigger gcc's -fsanitize=address. - bump old packet window size from 512 to 65536. - update for big changes in openssl 1.1 API, wrap primitives to make further changes easier. - correctly check return values for openssl 1.0.0 and later. - check for both public and private key file when deciding whether to skip generating a key to avoid accidental overwrites. 2.25 Sat Jul 13 06:42:33 CEST 2013 - INCOMPATIBLE CHANGE: no longer enable udp protocol if no other protocols are enabled - this is necessary when you have nodes with completely unknown protocols, to force mediated connection requests. - INCOMPATIBLE CHANGE: dns transport protocol bumped to version 2. - core protocol version 0.1, compatible with older releases. - switch to using RSA_generate_key_ex, which is the badly documented and needlessly more complicated replacement for the RSA_generate_key function which is now deprecated. - support additional hmac hashes: sha256 and sha512, usually truncated. - change public exponent for rsa keys from 65535 to 65537, for efficiency reasons - only affects new keys. - nodes would sometimes declare transport endpoints valid despite the protocol not being configured locally. - new global configuration options: chroot, chuser, chuid, chgid, to chroot to a specified or anonymous new root, and change user id. - new global configuration options seed_device and seed_interval, to configure another device than /dev/urandom for random seeds, and to configure a regular interval to reseed the rng. - prefer inet_aton over gethostbyname, as the latter is not guaranteed to "resolve" literal ip addresses. - configure didn't detect openssl 1.0 because SHA1_version became private (patch by TANIGUCHI Takaki). - fix a bug where nodes would tell the other side that it supports the same protocols as that other side, instead of its own. - add zlib when found, as openssl depends on it in newer versions. - work around append-bugs in uclibc by using an extra seek. - new "include" directive for the config file. - gvpectrl no longer evaluates any "on" directives. - icmp and rawip protocols weren't upgradable to each other. - major, but incremental, dns transport improvements: - do not simply abort in some error cases in the dns transport, but try to recover. - allow lowercase/uppercase aliases for base-n encodings that do not rely on case. - use base26 instead of base22 encoding for dns syn's, and base36 instead of base22 for headers (saves one byte/packet). - back off far quicker in dns tunnel when idling - increases latency on an idle link somewhat, but avoids hundreds of needless packets. - poll more aggressively when idling in dns (poll once per second as opposed to once per 5 seconds). - reduce dns send payload size to allow greater rate of ack messages (should help sack and ipv6). - allow for ip options in rawip/icmp transports, even though gvpe doesn't generate them. - upgrade to autoconf 2.69, automake 1.11. - upgrade to libev 4 API. - replace COPYING file by actual GPLv3 - files were relicensed to GPLv3 earlier but COPYING was forgotten. 2.24 Sat Feb 12 05:15:48 CET 2011 - protocol version 0.1, compatible with older releases. - due to a bug, when packets were lost, a connection could go into a state where a ping/connection request from another node would be ignored, leading to connections not being re-established. - due to a bug, compression was almost always enabled. - enable-max-mtu was actually enable-mtu, contrary to documentation. - add nfmark support. - add node-change script support. - new DESTSI variable for node-xxx scripts. - updated codingstyle a bit, declared truly static stuff as static. - clarify compression docs. 2.22 Sun Feb 1 17:25:28 CET 2009 - protocol version 0.1, compatible with older releases. - enabled icmp/tcp/http-proxy protocols by default. - updated copyright in program greetings. - fix some configure messages. - updated to libev 3.52. 2.21 Wed Sep 3 06:56:27 CEST 2008 - protocol version 0.1, compatible with older releases. - add missing ev++.h include header to tarball, which everybody who tested it apparently had in their include path :(. Caught by Karl Kleinpaste and Marcus Kong. 2.2 Mon Sep 1 06:28:09 CEST 2008 - protocol version 0.1, compatible with older releases. but upgrade is recommended to due changed ondemand behaviour. - new per-node options max-ttl and max-queue. - convert from iom.C to libev, a high-performance event loop (http://software.schmorp.de/pkg/libev). - tcp connections were leaking in some cases. - retry more aggressively (once/s) to establish a connection if new packets arrive for it. - save a lot of setsockopt calls when the tos doesn't change. - honor disabled even on initial connect attempt. - changed callback mechanism to be slightly less portable but more efficient mechanism (standards-compliant c++ compilers should work). - increased receive window positive size, to allow for massive packet loss due to occasional longer drop-outs. - send RST when a positive window size violation is detected, but not in other cases, to reconnect more quickly. - upgraded liblzf to version 3.4. - dropped -fno-exceptions due to ev++.h using it. - node-up/down scripts are now run in sequence. - new -q switch for gvpectrl, for when you run it often. - work around the horribly inconsistent, ad-hoc, ever-changing and broken texinfo syntax. YMMV. avoid texinfo. - keepalive is more aggressive now, sensding ping's every 3 seconds and killing the conenction after 15 seconds. - bugfixes. 2.01 Thu Mar 29 19:26:04 CEST 2007 - protocol version 0.1, compatible with older releases. - bugfix of callback.h, might have cause callback return values to be corrupted on architectures like sparc before. - dns transport retries more aggressively. - updated documentation, improved dns transport reliability and throughput. - added experimental support for sha256 and sha512 digests. 2.0 Mon Dec 5 13:59:26 CET 2005 - protocol version 0.1, compatible with older releases. - implement allow-direct, deny-direct node config statements. - implemented != for sockinfo. This fixes a bug where gvpe sent packets to the old ip address of another host even though it had received packets from it's new address. This only causes problems if you forget to -HUP your gvpe after your ip address changed, which is *required*. - sets close-on-exec flag on tcp connections. This fixes a bug where child processes kept tcp connections open and caused connections to fail when only one side can connect. - fixed a bug in receive sequence checking that made gvpe accept out-of-window packets in most cases. - tighter limit for the maximum sequence # to avoid overflow conditions + allow more headroom for packet reordering. - replace some asserts that trapped config mismatches by more useful log messages. - fix spurious extra newline in some log messages. 1.9 Tue Apr 19 06:21:50 CEST 2005 - protocol version 0.1, compatible with older releases. - WARNING: this version checks the return value of if-up etc. scripts and exits on failure. - IMPORTANT: run if-up/node-up etc. scripts via /bin/sh. - IMPORTANT: interface initialization (MAC, MTU) is now done automatically in most configurations. - options can now be specified on the gvpe command line, too. - make some DNS transport values configurable and document them. - improved OS specific information in gvpe.osdep(5). - new tap device type "native/darwin", that supports the tap driver available for darwin (thanks to matthew mead who tested it out with me in a long session). tincd/darwin is still available. - new device type "tincd/bsd", which is a newer version of the *bsd-drivers taken from tinc. - fixed a bug in relying on the order of global construction when tcp transport was enabled. The fix makes it use no cpu time unless it is in use, too. - information about other nodes is now available to if-up etc. scripts. - the value of the config variable if-up-data is passed to the if-up etc. scripts. - skip unparsable config lines with a warning instead of stopping parsing and continuing with a certainly unusable config. 1.8 Fri Mar 18 00:58:55 CET 2005 - protocol version 0.1, compatible with older releases. - enable-udp = yes is now default only when no other protocols are enabled. otherwise it is disabled unless explicitly enabled. - implemented dns tunneling (experimental now and in the future). - remove support for pre-release version protocol. - updated tincd drivers (rev 1433), added uml_socket driver, documented tincd drivers a bit better. - document icmp configuration values. - document transport protocols in gvpe.protocol(7). - remove unused ChangeLog file. - created a mailinglist at gvpe@lists.schmorp.de. - added an exemption to allow distribution of binaries linked against OpenSSL, as suggested by Guus Sliepen (author of tinc). No GNUTLS conversion in sight. - some portability fixes with respect to --disable-nls. 1.7 Tue Feb 22 23:58:59 CET 2005 - protocol version 0.1, compatible with older releases. - first gnu release. - documented the special value 1 for router-priority. - renamed vped => gvpe and vpectrl => gvpectrl, as well as vped.conf => gvpe.conf. - new per-node option "max-retry". - asymmetric rekeying behaviour, so hosts don't rekey simultaneously. - new configure option --enable-static-daemon. - fix configure --help output. - many documentation layout fixes. - synced iom.[Ch] from rxvt-unicode. - try to cope with some non-monotonic time changes. - revert to locale.h - a usual, clocale is nonfunctioning on macosx. - considerably improved pod2texi and the resulting texi doc. 1.6.1 Wed May 12 14:48:20 CEST 2004 - protocol version 0.1, compatible with older releases. - fix -c switch that has been broken due to a last-minute fix to option and config file parsing. 1.6 Mon May 10 20:55:10 CEST 2004 - protocol version 0.1, compatible with older releases. - do not RESET on out-of-sequence packets (good for wireless). - various non-security-related bugfixes. - c++ify (at least make it compile with g++-3.4, which should make it a little bit more standard c++). 1.5 Fri Jan 30 00:50:04 CET 2004 - protocol version 0.1, compatible with older releases. - vped will refuse to start when hostkey and public key do not match. - updated lzf code to version 1.2. - better error reporting for "unusual" conditions, like failing to allocate memory, that should not normally happen and will otherwise result in spurious other error messages. Also adds paranoid checks in case openssl's API changes in a bad way. - fix a bug where queued vpn packets were cleared to zero. while this doesn't affect security, it did cause warning messages and unnecessary connectivity delays. 1.4 Sat Jan 17 15:49:21 CET 2004 - protocol version 0.1, compatible with older releases. - better retry behaviour on key mismatch. - use select-based io_manager instead of poll-based one. - share io manager between rxvt-unicode and vpe. - sooo many *BSD workarounds because no BSD I could find is even remotely POSIX-compatible. 1.2 Fri Oct 17 03:44:44 CEST 2003 - protocol version 0.1. - tincd kernel interface code imported, more supported platforms (native/linux (2.4), tincd/linux (2.2 and 2.4), tincd/freebsd, native/cygwin). - added primitive ethernet emulation (ipv4 only), which allows the following platforms that only have tun drivers to work: /* none yet tested */ - portability workarounds, especially for unfriendly freebsd - very minor bugfixes - warnings when choosing insecure ciphers/hashes - reduced default hmac length to 8. - cvs now contains configure, Makefile.in and other generated files. - added doc/complex-example to the distribution. 1.0 distant past - protocol version 0.1. - tweaked various timeouts to help very slow (486) class machines or nets with many hosts. - tweaked rate-limiting to be more forgiving for hosts connecting through routers (not a fix). gvpe-3.0/TODO0000644000000000000000000000101313006270013007657 00000000000000TODO: bridge mode, finally? TODO: gcm mode? TODO: replace transport bits by transport endpoint structs? TODO: http://incog-izick.blogspot.de/2011/08/using-openssl-aes-gcm.html TODO: http://stackoverflow.com/questions/12153009/openssl-c-example-of-aes-gcm-using-evp-interfaces TODO: verify TODO: make sense of overhead calculation TODO: if-up &c should not be scripts? TODO: ipv6 TODO: gvpectrl should not use default privatekey,. or maybe document it better TODO: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=828336 gvpe-3.0/aclocal.m40000644000000000000000000032517613011103322011044 00000000000000# generated automatically by aclocal 1.7.9 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 # 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. # 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 10 AC_PREREQ([2.54]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # 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_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 # 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]) # Copyright 2002 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 # 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.7"]) # 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.7.9])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 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 1996, 1997, 2000, 2001 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)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 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_AUX_DIR_EXPAND # Copyright 2001 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. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 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)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 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])]) # -*- 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])]) # serial 5 -*- 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. # 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 builds --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 1999, 2000, 2001, 2002 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"]) ]) # 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 ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 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 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [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])]) # Add --enable-maintainer-mode option to configure. # From Jim Meyering # Copyright 1996, 1998, 2000, 2001, 2002 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 AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode is disabled by default AC_ARG_ENABLE(maintainer-mode, [ --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer], USE_MAINTAINER_MODE=$enableval, USE_MAINTAINER_MODE=no) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINT)dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # gettext.m4 serial 17 (gettext-0.11.5) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2002. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value `$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define(gt_included_intl, ifelse([$1], [external], [no], [yes])) define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. dnl Add a version number to the cache macros. define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, [AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings;], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no)]) if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], gt_cv_func_gnugettext_libintl, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], gt_cv_func_gnugettext_libintl=yes, gt_cv_func_gnugettext_libintl=no) dnl Now see whether libintl exists and depends on libiconv. if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext_libintl=yes ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if test "$gt_cv_func_gnugettext_libc" = "yes" \ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ && test "$PACKAGE" != gettext; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. INTLOBJS="\$(GETTOBJS)" BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE(HAVE_GETTEXT, 1, [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE(HAVE_DCGETTEXT, 1, [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST(BUILD_INCLUDED_LIBINTL) AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(CATOBJEXT) AC_SUBST(INTLOBJS) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST(DATADIRNAME) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST(INSTOBJEXT) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST(GENCAT) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST(INTLLIBS) dnl Make all documented variables known to autoconf. AC_SUBST(LIBINTL) AC_SUBST(LTLIBINTL) AC_SUBST(POSUB) ]) dnl Checks for all prerequisites of the po subdirectory, dnl except for USE_NLS. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.11 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_OUTPUT_COMMANDS([ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' fi case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= GMOFILES= UPDATEPOFILES= DUMMYPOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it # from automake. eval 'ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Checks for all prerequisites of the intl subdirectory, dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. AC_DEFUN([AM_INTL_SUBDIR], [ AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_ISC_POSIX])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_C_CONST])dnl AC_REQUIRE([AC_C_INLINE])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_REQUIRE([jm_GLIBC21])dnl AC_REQUIRE([gt_INTDIV0])dnl AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl AC_REQUIRE([gt_INTTYPES_PRI])dnl AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ stdlib.h string.h unistd.h sys/param.h]) AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) AM_ICONV AM_LANGINFO_CODESET if test $ac_cv_header_locale_h = yes; then AM_LC_MESSAGES fi dnl intl/plural.c is generated from intl/plural.y. It requires bison, dnl because plural.y uses bison specific features. It requires at least dnl bison-1.26 because earlier versions generate a plural.c that doesn't dnl compile. dnl bison is only needed for the maintainer (who touches plural.y). But in dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put dnl the rule in general Makefile. Now, some people carelessly touch the dnl files or have a broken "make" program, hence the plural.c rule will dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not dnl present or too old. AC_CHECK_PROGS([INTLBISON], [bison]) if test -z "$INTLBISON"; then ac_verc_fail=yes else dnl Found it, now check the version. AC_MSG_CHECKING([version of bison]) changequote(<<,>>)dnl ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) changequote([,])dnl ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac AC_MSG_RESULT([$ac_prog_version]) fi if test $ac_verc_fail = yes; then INTLBISON=: fi ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate is. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) # lib-prefix.m4 serial 1 (gettext-0.11) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) # lib-link.m4 serial 3 (gettext-0.11.3) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes undefine([Name]) undefine([NAME]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. If found, it dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" LIBS="$LIBS $LIB[]NAME" AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) undefine([Name]) undefine([NAME]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, dnl hardcode_direct, hardcode_minus_L, dnl sys_lib_search_path_spec, sys_lib_dlsearch_path_spec. AC_DEFUN([AC_LIB_RPATH], [ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE(rpath, [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH([lib$1-prefix], [ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib --without-lib$1-prefix don't search for lib$1 in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) # lib-ld.m4 serial 1 (gettext-0.11) dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl Subroutines of libtool.m4, dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision dnl with libtool.m4. dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then acl_cv_prog_gnu_ld=yes else acl_cv_prog_gnu_ld=no fi]) with_gnu_ld=$acl_cv_prog_gnu_ld ]) dnl From libtool-1.4. Sets the variable LD. AC_DEFUN([AC_LIB_PROG_LD], [AC_ARG_WITH(gnu-ld, [ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by GCC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]* | [A-Za-z]:[\\/]*)] [re_direlt='/[^/][^/]*/\.\./'] # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(acl_cv_path_LD, [if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break fi fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$acl_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) AC_LIB_PROG_LD_GNU ]) # iconv.m4 serial AM4 (gettext-0.11.3) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST(LIBICONV) AC_SUBST(LTLIBICONV) ]) AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi ]) # progtest.m4 serial 2 (gettext-0.10.40) dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) # isc-posix.m4 serial 2 (gettext-0.11.2) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # This file is not needed with autoconf-2.53 and newer. Remove it in 2005. # This test replaces the one in autoconf. # Currently this macro should have the same name as the autoconf macro # because gettext's gettext.m4 (distributed in the automake package) # still uses it. Otherwise, the use in gettext.m4 makes autoheader # give these diagnostics: # configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX # configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX undefine([AC_ISC_POSIX]) AC_DEFUN([AC_ISC_POSIX], [ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ] ) # glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # Test for the GNU C Library, version 2.1 or newer. # From Bruno Haible. AC_DEFUN([jm_GLIBC21], [ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, ac_cv_gnu_library_2_1, [AC_EGREP_CPP([Lucky GNU user], [ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif ], ac_cv_gnu_library_2_1=yes, ac_cv_gnu_library_2_1=no) ] ) AC_SUBST(GLIBC21) GLIBC21="$ac_cv_gnu_library_2_1" ] ) # intdiv0.m4 serial 1 (gettext-0.11.3) dnl Copyright (C) 2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([gt_INTDIV0], [ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], gt_cv_int_divbyzero_sigfpe, [ AC_TRY_RUN([ #include #include static void #ifdef __cplusplus sigfpe_handler (int sig) #else sigfpe_handler (sig) int sig; #endif { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (1); } ], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, [ # Guess based on the CPU. case "$host_cpu" in alpha* | i[34567]86 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac ]) ]) case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, [Define if integer division by zero raises signal SIGFPE.]) ]) # uintmax_t.m4 serial 6 (gettext-0.11) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_PREREQ(2.13) # Define uintmax_t to `unsigned long' or `unsigned long long' # if does not exist. AC_DEFUN([jm_AC_TYPE_UINTMAX_T], [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) AC_REQUIRE([jm_AC_HEADER_STDINT_H]) if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) test $ac_cv_type_unsigned_long_long = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, [Define to unsigned long or unsigned long long if and don't define.]) fi ]) # inttypes_h.m4 serial 4 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_inttypes_h=yes, jm_ac_cv_header_inttypes_h=no)]) if test $jm_ac_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) # stdint_h.m4 serial 2 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_STDINT_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_STDINT_H], [ AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_stdint_h=yes, jm_ac_cv_header_stdint_h=no)]) if test $jm_ac_cv_header_stdint_h = yes; then AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) # ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], [ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, [Define if you have the unsigned long long type.]) fi ]) # inttypes.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H if exists and doesn't clash with # . AC_DEFUN([gt_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, [ AC_TRY_COMPILE( [#include #include ], [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) ]) if test $gt_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, [Define if exists and doesn't clash with .]) fi ]) # inttypes-pri.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. # Define PRI_MACROS_BROKEN if exists and defines the PRI* # macros to non-string values. This is the case on AIX 4.3.3. AC_DEFUN([gt_INTTYPES_PRI], [ AC_REQUIRE([gt_HEADER_INTTYPES_H]) if test $gt_cv_header_inttypes_h = yes; then AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], gt_cv_inttypes_pri_broken, [ AC_TRY_COMPILE([#include #ifdef PRId32 char *p = PRId32; #endif ], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) ]) fi if test "$gt_cv_inttypes_pri_broken" = yes; then AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, [Define if exists and defines unusable PRI* macros.]) fi ]) # codeset.m4 serial AM1 (gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_LANGINFO_CODESET], [ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, [AC_TRY_LINK([#include ], [char* cs = nl_langinfo(CODESET);], am_cv_langinfo_codeset=yes, am_cv_langinfo_codeset=no) ]) if test $am_cv_langinfo_codeset = yes; then AC_DEFINE(HAVE_LANGINFO_CODESET, 1, [Define if you have and nl_langinfo(CODESET).]) fi ]) # lcmessage.m4 serial 3 (gettext-0.11.3) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995. # Check whether LC_MESSAGES is available in . AC_DEFUN([AM_LC_MESSAGES], [ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your file defines LC_MESSAGES.]) fi ]) dnl Check to find out whether the running kernel has support for TUN/TAP AC_DEFUN([tinc_TUNTAP], [ AC_ARG_WITH(kernel, [ --with-kernel=dir give the directory with kernel sources] [ (default: /usr/src/linux)], kerneldir="$withval", kerneldir="/usr/src/linux" ) AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h, [ AC_TRY_COMPILE([#include "$kerneldir/include/linux/if_tun.h"], [int a = IFF_TAP;], if_tun_h="\"$kerneldir/include/linux/if_tun.h\"", [AC_TRY_COMPILE([#include ], [int a = IFF_TAP;], if_tun_h="default", if_tun_h="no" )] ) if test $if_tun_h = no; then tinc_cv_linux_if_tun_h=none else tinc_cv_linux_if_tun_h="$if_tun_h" fi ]) if test $tinc_cv_linux_if_tun_h != none; then AC_DEFINE(HAVE_TUNTAP, 1, [Universal tun/tap driver present]) if test $tinc_cv_linux_if_tun_h != default; then AC_DEFINE_UNQUOTED(LINUX_IF_TUN_H, $tinc_cv_linux_if_tun_h, [Location of if_tun.h]) fi fi AC_SUBST(LINUX_IF_TUN_H) AC_SUBST(HAVE_TUNTAP) ]) dnl Check to find the OpenSSL headers/libraries AC_DEFUN([tinc_OPENSSL], [ tinc_ac_save_CPPFLAGS="$CPPFLAGS" AC_ARG_WITH(openssl-include, [ --with-openssl-include=DIR OpenSSL headers directory (without trailing /openssl)], [openssl_include="$withval" CFLAGS="$CFLAGS -I$withval" CPPFLAGS="$CPPFLAGS -I$withval"] ) AC_ARG_WITH(openssl-lib, [ --with-openssl-lib=DIR OpenSSL library directory], [openssl_lib="$withval" LIBS="$LIBS -L$withval"] ) AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h, [], [AC_MSG_ERROR([OpenSSL header files not found.]); break] ) CPPFLAGS="$tinc_ac_save_CPPFLAGS" AC_CHECK_LIB(crypto, SHA1_Init, [LIBS="$LIBS -lcrypto"], [AC_MSG_ERROR([OpenSSL libraries not found.])] ) AC_CHECK_FUNCS([RAND_pseudo_bytes OPENSSL_add_all_algorithms_noconf OpenSSL_add_all_algorithms SSLeay_add_all_algorithms]) AC_CHECK_FUNC(dlopen, [], [AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"], [AC_MSG_ERROR([OpenSSL depends on libdl.])] )] ) AC_CHECK_FUNC(inflate, [], [AC_CHECK_LIB(z, inflate, [LIBS="$LIBS -lz"], [AC_MSG_ERROR([OpenSSL depends on libz.])] )] ) ]) gvpe-3.0/config.guess0000755000000000000000000012355012404676534011545 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-03-23' # 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 3 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, see . # # 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. 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 1992-2014 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 "$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 case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # 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 tuples: *-*-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 ;; sh5el) machine=sh5le-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 -q __ELF__ 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 ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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 ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-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'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; 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 ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; 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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-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:*:[4567]) 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 -q __LP64__ 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:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-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-${LIBC}`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/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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 -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #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-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${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-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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.[02]*:*) 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 i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-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; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' 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; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; 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.[02]*:*) 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 ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku 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 ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-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 eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi 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 ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} 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 ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac 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: gvpe-3.0/config.h.in0000644000000000000000000002403012735173704011237 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ #ifndef CONFIG_H__ #define CONFIG_H__ #ifdef __cplusplus using namespace std; #endif /* 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 /* Select the auth digest algorithm to use. */ #undef ENABLE_AUTH /* Select the symmetric cipher to use. */ #undef ENABLE_CIPHER /* Enable compression support. */ #undef ENABLE_COMPRESSION /* DNS tunnel protocol support. */ #undef ENABLE_DNS /* Select the HMAC digest algorithm to use. */ #undef ENABLE_HMAC /* http proxy connect support. */ #undef ENABLE_HTTP_PROXY /* ICMP protocol support. */ #undef ENABLE_ICMP /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* POSIX thread support. */ #undef ENABLE_PTHREADS /* TCP protocol support. */ #undef ENABLE_TCP /* 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_ARPA_INET_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_CLOCALE /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 to use the syscall interface for clock_gettime */ #undef HAVE_CLOCK_SYSCALL /* Cygwin */ #undef HAVE_CYGWIN /* Define to 1 if you have the `daemon' function. */ #undef HAVE_DAEMON /* Darwin (MacOS/X) */ #undef HAVE_DARWIN /* Define if the GNU dcgettext() function is already present or preinstalled. */ #undef HAVE_DCGETTEXT /* Define to 1 if you have the `epoll_ctl' function. */ #undef HAVE_EPOLL_CTL /* Define to 1 if you have the `eventfd' function. */ #undef HAVE_EVENTFD /* Define to 1 if you have the header file. */ #undef HAVE_EXT_HASH_MAP /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if the floor function is available */ #undef HAVE_FLOOR /* FreeBSD */ #undef HAVE_FREEBSD /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT /* Define to 1 if you have the `get_current_dir_name' function. */ #undef HAVE_GET_CURRENT_DIR_NAME /* Define if you have the iconv() function. */ #undef HAVE_ICONV /* Define to 1 if you have the `inotify_init' function. */ #undef HAVE_INOTIFY_INIT /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `kqueue' function. */ #undef HAVE_KQUEUE /* Define to 1 if you have the `gmp' library (-lgmp). */ #undef HAVE_LIBGMP /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Linux */ #undef HAVE_LINUX /* 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 `mlockall' function. */ #undef HAVE_MLOCKALL /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* NetBSD */ #undef HAVE_NETBSD /* 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 /* OpenBSD */ #undef HAVE_OPENBSD /* Define to 1 if you have the `OpenSSL_add_all_algorithms' function. */ #undef HAVE_OPENSSL_ADD_ALL_ALGORITHMS /* Define to 1 if you have the `OPENSSL_add_all_algorithms_noconf' function. */ #undef HAVE_OPENSSL_ADD_ALL_ALGORITHMS_NOCONF /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ERR_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_EVP_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_PEM_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RAND_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RSA_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SHA_H /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H /* Define to 1 if you have the `port_create' function. */ #undef HAVE_PORT_CREATE /* Define to 1 if you have the header file. */ #undef HAVE_PORT_H /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the `RAND_pseudo_bytes' function. */ #undef HAVE_RAND_PSEUDO_BYTES /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `signalfd' function. */ #undef HAVE_SIGNALFD /* socklen_t available */ #undef HAVE_SOCKLEN_T /* Solaris/SunOS */ #undef HAVE_SOLARIS /* Define to 1 if you have the `SSLeay_add_all_algorithms' function. */ #undef HAVE_SSLEAY_ADD_ALL_ALGORITHMS /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* struct addrinfo available */ #undef HAVE_STRUCT_ADDRINFO /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CYGWIN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EVENTFD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EVENT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_INOTIFY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SIGNALFD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TR1_UNORDERED_MAP /* Universal tun/tap driver present */ #undef HAVE_TUNTAP /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Size of HMAC in each packet in bytes. */ #undef HMACLENGTH /* kernel interface subtype */ #undef IFSUBTYPE /* kernel interface type */ #undef IFTYPE /* Location of if_tun.h */ #undef LINUX_IF_TUN_H /* Maximum MTU supported. */ #undef MAX_MTU /* 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 home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Size of RSA keys. */ #undef RSABITS /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Version number of package */ #undef VERSION /* Enable GNU extensions */ #undef _GNU_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t typedef unsigned char u8; typedef signed char s8; #if __CYGWIN__ typedef unsigned short u16; typedef unsigned int u32; typedef signed short s16; typedef signed int s32; #else #include /* old modula-2 habits */ typedef uint16_t u16; typedef uint32_t u32; typedef int16_t s16; typedef int32_t s32; #endif #endif #if HAVE_CLOCALE # define CLOCALE #else # define CLOCALE #endif gvpe-3.0/config.rpath0000744000000000000000000003345511046631516011527 00000000000000#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2002 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is part of GVPE. # # GVPE 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 gvpe; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, 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. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # All known linkers require a `.a' archive for static linking (except M$VC, # which needs '.lib'). libext=a shlibext= host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix3* | aix4* | aix5*) wl='-Wl,' ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6*) wl='-Wl,' ;; linux*) echo '__INTEL_COMPILER' > conftest.$ac_ext if $CC -E conftest.$ac_ext >/dev/null | grep __INTEL_COMPILER >/dev/null then : else # Intel icc wl='-Qoption,ld,' fi ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; solaris*) wl='-Wl,' ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) if test "x$host_vendor" = xsni; then wl='-LD' else wl='-Wl,' fi ;; esac fi hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then case "$host_os" in aix3* | aix4* | aix5*) # On AIX, the GNU linker is very broken ld_shlibs=no ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' ;; solaris* | sysv5*) if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi esac fi if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' fi fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=yes ;; freebsd1*) ld_shlibs=no ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9* | hpux10* | hpux11*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_minus_L=yes # Not in the search PATH, but as the default # location of the library. ;; irix5* | irix6*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; openbsd*) hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; sco3.2v5*) ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) if test "x$host_vendor" = xsno; then hardcode_direct=yes # is this really true??? else hardcode_direct=no # Motorola manual says yes, but my tests say they lie fi ;; sysv4.3*) ;; sysv5*) hardcode_libdir_flag_spec= ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4.2uw2*) hardcode_direct=yes hardcode_minus_L=no ;; sysv5uw7* | unixware7*) ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics libname_spec='lib$name' sys_lib_dlsearch_path_spec="/lib /usr/lib" sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" case "$host_os" in aix3*) shlibext=so ;; aix4* | aix5*) shlibext=so ;; amigaos*) shlibext=ixlibrary ;; beos*) shlibext=so ;; bsdi4*) shlibext=so sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ;; cygwin* | mingw* | pw32*) case $GCC,$host_os in yes,cygwin*) shlibext=dll.a ;; yes,mingw*) shlibext=dll sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` ;; yes,pw32*) shlibext=dll ;; *) shlibext=dll ;; esac ;; darwin* | rhapsody*) shlibext=dylib ;; freebsd1*) ;; freebsd*) shlibext=so ;; gnu*) shlibext=so ;; hpux9* | hpux10* | hpux11*) shlibext=sl ;; irix5* | irix6*) shlibext=so case "$host_os" in irix5*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 ") libsuff= shlibsuff= ;; *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ;; linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) ;; linux-gnu*) shlibext=so ;; netbsd*) shlibext=so ;; newsos6) shlibext=so ;; openbsd*) shlibext=so ;; os2*) libname_spec='$name' shlibext=dll ;; osf3* | osf4* | osf5*) shlibext=so sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; sco3.2v5*) shlibext=so ;; solaris*) shlibext=so ;; sunos4*) shlibext=so ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) shlibext=so case "$host_vendor" in motorola) sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; uts4*) shlibext=so ;; dgux*) shlibext=so ;; sysv4*MP*) if test -d /usr/nec; then shlibext=so fi ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_sys_lib_search_path_spec=`echo "X$sys_lib_search_path_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_sys_lib_dlsearch_path_spec=`echo "X$sys_lib_dlsearch_path_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. # # 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # 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. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # 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 1992-2014 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-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) 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 | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -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 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -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/'` ;; -sco5v6*) # 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*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -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 \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # 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-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # 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 ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; 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 ;; cr16 | cr16-*) basic_machine=cr16-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 ;; dicos) basic_machine=i686-pc os=-dicos ;; 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*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 ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; 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 ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; 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 ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; 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 ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; 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 | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) 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 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; 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 ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; 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 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; 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 ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; 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 ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-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[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) 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. -auroraux) os=-auroraux ;; -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* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -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* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -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* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # 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 ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -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 score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) 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 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; 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 ;; -cnk*|-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: gvpe-3.0/configure.ac0000644000000000000000000003005513006310054011465 00000000000000dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.69) AC_INIT AC_CONFIG_SRCDIR([src/gvpe.C]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(gvpe, 3.0) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE AH_TOP([ #ifndef CONFIG_H__ #define CONFIG_H__ #ifdef __cplusplus using namespace std; #endif ]) AH_BOTTOM([ typedef unsigned char u8; typedef signed char s8; #if __CYGWIN__ typedef unsigned short u16; typedef unsigned int u32; typedef signed short s16; typedef signed int s32; #else #include /* old modula-2 habits */ typedef uint16_t u16; typedef uint32_t u32; typedef int16_t s16; typedef int32_t s32; #endif #endif #if HAVE_CLOCALE # define CLOCALE #else # define CLOCALE #endif ]) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION(0.11.5) # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions # in the latter don't make it into the configure-time tests. AC_DEFINE([_GNU_SOURCE], 1, [Enable GNU extensions]) # do NOT define POSIX_SOURCE, sicne this clashes with many BSDs dnl AC_DEFINE([_POSIX_SOURCE], 1, [Enable POSIX 1003.1 extensions]) dnl AC_DEFINE([_XOPEN_SOURCE], 500, [Enable XOPEN extensions]) ALL_LINGUAS="" dnl Checks for programs. AC_PROG_CPP AC_PROG_CXX AC_PROG_GCC_TRADITIONAL AC_PROG_AWK AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_RANLIB AC_ARG_ENABLE(iftype, [AS_HELP_STRING(--enable-iftype=TYPE/SUBTYPE, Use kernel/net device interface TYPE/SUBTYPE. Working combinations are (see doc/gvpe.osdep.5.pod): "native/linux" "tincd/linux" "tincd/netbsd" "tincd/freebsd" "tincd/openbsd" "native/darwin" "tincd/darwin" "native/cygwin"; Untested combinations are: "tincd/bsd" "tincd/solaris" "tincd/mingw" "tincd/raw_socket" "tincd/uml_socket"; Broken combinations are: "tincd/cygwin"; The default is to autodetect. )], [ IFTYPE=`echo $enableval | sed s%/.*%%` IFSUBTYPE=`echo $enableval | sed s%.*/%%` ] ) dnl Check and set OS AC_MSG_CHECKING(for kernel networking interface type) if test "x$IFTYPE" = "x"; then case $target_os in *linux*) IFTYPE=native IFSUBTYPE=linux AC_DEFINE(HAVE_LINUX, 1, [Linux]) ;; *freebsd*) IFTYPE=tincd IFSUBTYPE=freebsd AC_DEFINE(HAVE_FREEBSD, 1, [FreeBSD]) ;; *darwin*) IFTYPE=native IFSUBTYPE=darwin AC_DEFINE(HAVE_DARWIN, 1, [Darwin (MacOS/X)]) ;; *solaris*) IFTYPE=tincd IFSUBTYPE=solaris AC_DEFINE(HAVE_SOLARIS, 1, [Solaris/SunOS]) ;; *openbsd*) IFTYPE=tincd IFSUBTYPE=openbsd AC_DEFINE(HAVE_OPENBSD, 1, [OpenBSD]) ;; *netbsd*) IFTYPE=tincd IFSUBTYPE=netbsd AC_DEFINE(HAVE_NETBSD, 1, [NetBSD]) ;; *cygwin*) IFTYPE=native IFSUBTYPE=cygwin AC_DEFINE(HAVE_CYGWIN, 1, [Cygwin]) ;; *) AC_MSG_ERROR("Unknown operating system.") ;; esac fi AC_MSG_RESULT($IFTYPE/$IFSUBTYPE) AC_SUBST(IFTYPE,$IFTYPE) AC_SUBST(IFSUBTYPE,$IFSUBTYPE) AC_DEFINE_UNQUOTED(IFTYPE,"$IFTYPE",[kernel interface type]) AC_DEFINE_UNQUOTED(IFSUBTYPE,"$IFSUBTYPE",[kernel interface subtype]) AC_CACHE_SAVE dnl Checks for libraries. AC_LANG(C++) AC_CHECK_HEADERS(tr1/unordered_map ext/hash_map clocale) dnl Checks for header files. AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h malloc.h stdint.h strings.h syslog.h unistd.h \ sys/file.h sys/ioctl.h sys/param.h sys/time.h netinet/in_systm.h sys/cygwin.h \ sys/mman.h netinet/in.h]) AC_CHECK_HEADERS([arpa/inet.h net/ethernet.h net/if.h netinet/ip.h netinet/tcp.h netinet/in_systm.h], [], [], [ #include #include #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_NETINET_IN_SYSTM_H # include #endif ]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[socklen_t len = 42; return len;]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no]) ]) if test $ac_cv_type_socklen_t = yes; then AC_DEFINE(HAVE_SOCKLEN_T, 1, [socklen_t available]) fi AC_CACHE_CHECK([for struct addrinfo], ac_cv_struct_addrinfo, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include #include ]], [[struct addrinfo ai; ai.ai_family = AF_INET; return ai.ai_family;]])],[ac_cv_struct_addrinfo=yes],[ac_cv_struct_addrinfo=no]) ]) if test $ac_cv_struct_addrinfo = yes; then AC_DEFINE(HAVE_STRUCT_ADDRINFO, 1, [struct addrinfo available]) fi dnl Checks for library functions. AC_TYPE_SIGNAL AC_LANG_PUSH(C) AC_HEADER_STDC dnl argl, could somebody catapult darwin into the 21st century??? AC_CHECK_FUNCS(asprintf daemon get_current_dir_name putenv select strerror strsignal strtol unsetenv mlockall) AC_FUNC_ALLOCA dnl Support for SunOS AC_CHECK_FUNC(socket, [], [ AC_CHECK_LIB(socket, connect) ]) AC_CHECK_FUNC(gethostbyname, [], [ AC_CHECK_LIB(nsl, gethostbyname) ]) dnl libev support m4_include([libev/libev.m4]) AC_LANG_POP dnl AC_CHECK_FUNCS([freeaddrinfo gai_strerror getaddrinfo getnameinfo]) AC_CACHE_SAVE dnl These are defined in files in m4/ tinc_TUNTAP tinc_OPENSSL if test "x$openssl_include" != x; then CXXFLAGS="$CXXFLAGS -I$openssl_include" fi dnl tinc_ZLIB AC_ARG_ENABLE(threads, [AS_HELP_STRING(--enable-threads,try to use threads for long-running asynchronous operations (default enabled).)], [try_threads=$enableval], [try_threads=yes] ) if test "x$try_threads" = xyes; then AC_CHECK_HEADER(pthread.h,[ LIBS="$LIBS -lpthread" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([#include ], [pthread_t id; pthread_create (&id, 0, 0, 0);])], [AC_DEFINE_UNQUOTED(ENABLE_PTHREADS, 1, [POSIX thread support.])] ) ]) fi AC_ARG_ENABLE(static-daemon, [AS_HELP_STRING(--enable-static-daemon,enable statically linked daemon.)], [LDFLAGS_DAEMON=-static] ) AC_SUBST(LDFLAGS_DAEMON) dnl AC_ARG_ENABLE(rohc, dnl [AS_HELP_STRING(--enable-rohc,enable robust header compression (rfc3095).)], dnl [ dnl echo dnl echo "**********************************************************************" dnl echo "**********************************************************************" dnl echo "**** --enable-rohc is highly experimental, do not use ****************" dnl echo "**********************************************************************" dnl echo "**********************************************************************" dnl echo dnl rohc=true dnl AC_DEFINE_UNQUOTED(ENABLE_ROHC, 1, [ROHC support]) dnl ] dnl ) AM_CONDITIONAL(ROHC, test x$rohc = xtrue) dnl AC_ARG_ENABLE(bridging, dnl [AS_HELP_STRING(--enable-bridging,enable bridging support (default disabled).)], dnl AC_DEFINE_UNQUOTED(ENABLE_BRIDGING, 1, [bridging support.]) dnl ) ICMP=1 AC_ARG_ENABLE(icmp, [AS_HELP_STRING(--disable-icmp,enable icmp protocol support (default enabled).)], if test "x$enableval" = xno; then ICMP=0 fi ) if test "x$ICMP" = x1; then AC_DEFINE_UNQUOTED(ENABLE_ICMP, 1, [ICMP protocol support.]) fi TCP=1 AC_ARG_ENABLE(tcp, [AS_HELP_STRING(--disable-tcp,enable tcp protocol support (default enabled).)], if test "x$enableval" = xno; then TCP=0 fi ) if test "x$TCP" = x1; then AC_DEFINE_UNQUOTED(ENABLE_TCP, 1, [TCP protocol support.]) fi HTTP=1 AC_ARG_ENABLE(http-proxy, [AS_HELP_STRING(--disable-http-proxy,enable http proxy connect support (default enabled).)], if test "x$enableval" = xno; then HTTP=0 fi ) if test "x$HTTP" = x1; then AC_DEFINE_UNQUOTED(ENABLE_HTTP_PROXY, 1, [http proxy connect support.]) fi AC_ARG_ENABLE(dns, [AS_HELP_STRING(--enable-dns,enable dns tunnel protocol support (default disabled).)], [ AC_CHECK_HEADER(gmp.h,,[AC_MSG_ERROR([gmp.h not found, required for --enable-dns])]) AC_CHECK_LIB(gmp,main,,[AC_MSG_ERROR([libgmp not found, required for --enable-dns])]) AC_DEFINE_UNQUOTED(ENABLE_DNS, 1, [DNS tunnel protocol support.]) ] ) RSA=3072 AC_ARG_ENABLE(rsa-length, [AS_HELP_STRING(--enable-rsa-length=BITS,[ use BITS rsa keys (default 3072). Allowed values are 2048-10240.])], RSA=$enableval ) AC_DEFINE_UNQUOTED(RSABITS, $RSA, [Size of RSA keys.]) HMACSIZE=12 AC_ARG_ENABLE(hmac-length, [AS_HELP_STRING(--enable-hmac-length=BYTES,[ use a hmac of length BYTES bytes (default 12). Allowed values are 4, 8, 12, 16.])], HMACSIZE=$enableval ) AC_DEFINE_UNQUOTED(HMACLENGTH, $HMACSIZE, [Size of HMAC in each packet in bytes.]) MTU=1500 AC_ARG_ENABLE(max-mtu, [AS_HELP_STRING(--enable-max-mtu=BYTES,enable mtu sizes upto BYTES bytes (default 1500). Use 9100 for jumbogram support.)], MTU=$enableval ) AC_DEFINE_UNQUOTED(MAX_MTU, ($MTU + 14), [Maximum MTU supported.]) COMPRESS=1 AC_ARG_ENABLE(compression, [AS_HELP_STRING(--disable-compression,Disable compression support.)], if test "x$enableval" = xno; then COMPRESS=0 fi ) AC_DEFINE_UNQUOTED(ENABLE_COMPRESSION, $COMPRESS, [Enable compression support.]) CIPHER=aes_128_ctr AC_ARG_ENABLE(cipher, [AS_HELP_STRING(--enable-cipher=CIPHER,[ Select the symmetric cipher (default "aes-128"). Must be one of "aes-128" (rijndael), "aes-192", or "aes-256".])], #if test "x$enableval" = xbf ; then CIPHER=bf_ctr ; fi if test "x$enableval" = xaes-128 ; then CIPHER=aes_128_ctr ; fi if test "x$enableval" = xaes-192 ; then CIPHER=aes_192_ctr ; fi if test "x$enableval" = xaes-256 ; then CIPHER=aes_256_ctr ; fi #if test "x$enableval" = xcamellia-128; then CIPHER=camellia_128_ctr; fi #if test "x$enableval" = xcamellia-256; then CIPHER=camellia_256_ctr; fi ) AC_DEFINE_UNQUOTED(ENABLE_CIPHER, EVP_${CIPHER}, [Select the symmetric cipher to use.]) HMAC=sha1 AC_ARG_ENABLE(hmac-digest, [AS_HELP_STRING(--enable-hmac-digest=HMAC,[ Select the HMAC digest algorithm to use (default "sha1"). Must be one of "sha512", "sha256", "sha1", "ripemd160", "whirlpool".])], if test "x$enableval" = xwhirlpool; then HMAC=whirlpool; fi if test "x$enableval" = xsha512 ; then HMAC=sha512 ; fi if test "x$enableval" = xsha256 ; then HMAC=sha256 ; fi if test "x$enableval" = xsha1 ; then HMAC=sha1 ; fi if test "x$enableval" = xripemd160; then HMAC=ripemd160; fi ) AC_DEFINE_UNQUOTED(ENABLE_HMAC, EVP_${HMAC}, [Select the HMAC digest algorithm to use.]) AUTH=sha512 AC_ARG_ENABLE(auth-digest, [AS_HELP_STRING(--enable-auth-digest=DIGEST,[ Select the hmac algorithm to use (default "sha512"). Must be one of "sha512", "sha256", "whirlpool".])], if test "x$enableval" = xwhirlpool; then AUTH=whirlpool; fi if test "x$enableval" = xsha512 ; then AUTH=sha512 ; fi if test "x$enableval" = xsha256 ; then AUTH=sha256 ; fi ) AC_DEFINE_UNQUOTED(ENABLE_AUTH, EVP_${AUTH}, [Select the auth digest algorithm to use.]) if $CXX -v --help 2>&1 | grep -q fno-rtti; then CXXFLAGS="$CXXFLAGS -fno-rtti" fi #if $CXX -v --help 2>&1 | grep -q fexceptions; then # CXXFLAGS="$CXXFLAGS -fno-exceptions" #fi LIBS="$EXTRA_LIBS $LIBS" dnl if $CXX -v --help 2>&1 | grep -q ffunction-sections; then dnl CXXFLAGS="$CXXFLAGS -ffunction-sections" dnl fi dnl dnl if $LD -v --help 2>&1 | grep -q gc-sections; then dnl LDFLAGS="$LDFLAGS -Wl,--gc-sections" dnl fi AC_SUBST(INCLUDES) AC_CONFIG_FILES([Makefile po/Makefile.in src/Makefile doc/Makefile lib/Makefile m4/Makefile ]) AC_OUTPUT echo echo "***" echo "*** Configuration Summary" echo "***" echo "*** Kernel Iface: $IFTYPE/$IFSUBTYPE" echo "*** RSA size: $RSA" echo "*** Cipher used: $CIPHER" echo "*** Digest used: $DIGEST" echo "*** Authdigest: $AUTH" echo "*** HMAC length: $HMAC" echo "*** Max. MTU: $MTU" echo "***" echo "*** Enable options:" grep ENABLE_ config.h | sed -e 's/^/*** /' if test "$HMACSIZE" -lt 12; then echo "***" echo "*** WARNING: The hmac length you have chosen ($HMACSIZE) is quite insecure" fi echo "***" echo gvpe-3.0/depcomp0000755000000000000000000003305212011645431010561 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 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 . 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 gvpe-3.0/install-sh0000755000000000000000000001572212011645431011214 00000000000000#!/bin/sh # # install - install a program, script, or datafile # # 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="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -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 [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up 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. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # 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 [ -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 && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } gvpe-3.0/missing0000755000000000000000000002403212011645431010601 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # 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 case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; 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]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - 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 missing on your system. 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 missing on your system. 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 missing on your system. 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 missing on your system. 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, and you do not seem to have it handy on your system. 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' is missing on your system. 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 missing on your system. 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 missing on your system. 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 missing on your system. 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 you do not seem to have it handy on your system. 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 gvpe-3.0/mkinstalldirs0000755000000000000000000000370412011645431012013 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # 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 -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" 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 # End: # mkinstalldirs ends here gvpe-3.0/m4/0000755000000000000000000000000013011103357007576 500000000000000gvpe-3.0/m4/README0000644000000000000000000000063411046631517010413 00000000000000These files are used by a program called aclocal (part of the GNU automake package). aclocal uses these files to create aclocal.m4 which is in turn used by autoconf to create the configure script at the the top level in this distribution. The Makefile.am file in this directory is automatically generated from the template file, Makefile.am.in. The generation will fail if you don't have all the right tools. gvpe-3.0/m4/Makefile.in0000644000000000000000000002050613011103322011556 00000000000000# Makefile.in generated by automake 1.7.9 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # 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@ 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 = : host_triplet = @host@ 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@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_TUNTAP = @HAVE_TUNTAP@ IFSUBTYPE = @IFSUBTYPE@ IFTYPE = @IFTYPE@ INCLUDES = @INCLUDES@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DAEMON = @LDFLAGS_DAEMON@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LINUX_IF_TUN_H = @LINUX_IF_TUN_H@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ POSUB = @POSUB@ RANLIB = @RANLIB@ ROHC_FALSE = @ROHC_FALSE@ ROHC_TRUE = @ROHC_TRUE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ EXTRA_DIST = README Makefile.am.in aclocal-include.m4 codeset.m4 \ gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes-pri.m4 inttypes.m4 \ inttypes_h.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 \ lib-prefix.m4 openssl.m4 progtest.m4 stdint_h.m4 tuntap.m4 uintmax_t.m4 \ ulonglong.m4 subdir = m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = README $(srcdir)/Makefile.in ChangeLog Makefile.am all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu m4/Makefile Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) 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"; \ $(mkinstalldirs) "$(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 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: 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 mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-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 -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-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-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am Makefile.am: Makefile.am.in rm -f $@ $@t sed -n '1,/^##m4-files-begin/p' $< > $@t ( echo EXTRA_DIST = README Makefile.am.in; \ find . -type f -name '*.m4' -print |sed 's,^\./,,' |sort ) \ |fmt | (tr '\012' @; echo) \ |sed 's/@$$/%/;s/@/ \\@/g' |tr @% '\012\012' \ >> $@t sed -n '/^##m4-files-end/,$$p' $< >> $@t chmod a-w $@t mv $@t $@ # 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: gvpe-3.0/m4/ChangeLog0000644000000000000000000000057311046631517011307 000000000000002003-02-20 gettextize * iconv.m4: New file, from gettext-0.11.5. * intdiv0.m4: New file, from gettext-0.11.5. * isc-posix.m4: New file, from gettext-0.11.5. * lib-ld.m4: New file, from gettext-0.11.5. * lib-link.m4: New file, from gettext-0.11.5. * lib-prefix.m4: New file, from gettext-0.11.5. * Makefile.am (EXTRA_DIST): Add the new files. gvpe-3.0/m4/Makefile.am0000444000000000000000000000137411046631517011567 00000000000000## Process this file with automake to produce Makefile.in -*-Makefile-*- ##m4-files-begin EXTRA_DIST = README Makefile.am.in aclocal-include.m4 codeset.m4 \ gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes-pri.m4 inttypes.m4 \ inttypes_h.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 \ lib-prefix.m4 openssl.m4 progtest.m4 stdint_h.m4 tuntap.m4 uintmax_t.m4 \ ulonglong.m4 ##m4-files-end Makefile.am: Makefile.am.in rm -f $@ $@t sed -n '1,/^##m4-files-begin/p' $< > $@t ( echo EXTRA_DIST = README Makefile.am.in; \ find . -type f -name '*.m4' -print |sed 's,^\./,,' |sort ) \ |fmt | (tr '\012' @; echo) \ |sed 's/@$$/%/;s/@/ \\@/g' |tr @% '\012\012' \ >> $@t sed -n '/^##m4-files-end/,$$p' $< >> $@t chmod a-w $@t mv $@t $@ gvpe-3.0/m4/Makefile.am.in0000644000000000000000000000073111046631517012172 00000000000000## Process this file with automake to produce Makefile.in -*-Makefile-*- ##m4-files-begin ##m4-files-end Makefile.am: Makefile.am.in rm -f $@ $@t sed -n '1,/^##m4-files-begin/p' $< > $@t ( echo EXTRA_DIST = README Makefile.am.in; \ find . -type f -name '*.m4' -print |sed 's,^\./,,' |sort ) \ |fmt | (tr '\012' @; echo) \ |sed 's/@$$/%/;s/@/ \\@/g' |tr @% '\012\012' \ >> $@t sed -n '/^##m4-files-end/,$$p' $< >> $@t chmod a-w $@t mv $@t $@ gvpe-3.0/m4/aclocal-include.m40000644000000000000000000000050211046631517013006 00000000000000# aclocal-include.m4 # # This macro adds the name macrodir to the set of directories # that `aclocal' searches for macros. # serial 1 dnl AM_ACLOCAL_INCLUDE(macrodir) AC_DEFUN([AM_ACLOCAL_INCLUDE], [ test -n "$ACLOCAL_FLAGS" && ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS" for k in $1 ; do ACLOCAL="$ACLOCAL -I $k" ; done ]) gvpe-3.0/m4/codeset.m40000644000000000000000000000157611046631517011431 00000000000000# codeset.m4 serial AM1 (gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_LANGINFO_CODESET], [ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, [AC_TRY_LINK([#include ], [char* cs = nl_langinfo(CODESET);], am_cv_langinfo_codeset=yes, am_cv_langinfo_codeset=no) ]) if test $am_cv_langinfo_codeset = yes; then AC_DEFINE(HAVE_LANGINFO_CODESET, 1, [Define if you have and nl_langinfo(CODESET).]) fi ]) gvpe-3.0/m4/gettext.m40000644000000000000000000005730111046631517011464 00000000000000# gettext.m4 serial 17 (gettext-0.11.5) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2002. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value `$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define(gt_included_intl, ifelse([$1], [external], [no], [yes])) define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. dnl Add a version number to the cache macros. define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, [AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings;], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no)]) if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], gt_cv_func_gnugettext_libintl, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], gt_cv_func_gnugettext_libintl=yes, gt_cv_func_gnugettext_libintl=no) dnl Now see whether libintl exists and depends on libiconv. if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext_libintl=yes ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if test "$gt_cv_func_gnugettext_libc" = "yes" \ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ && test "$PACKAGE" != gettext; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. INTLOBJS="\$(GETTOBJS)" BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE(HAVE_GETTEXT, 1, [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE(HAVE_DCGETTEXT, 1, [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST(BUILD_INCLUDED_LIBINTL) AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(CATOBJEXT) AC_SUBST(INTLOBJS) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST(DATADIRNAME) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST(INSTOBJEXT) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST(GENCAT) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST(INTLLIBS) dnl Make all documented variables known to autoconf. AC_SUBST(LIBINTL) AC_SUBST(LTLIBINTL) AC_SUBST(POSUB) ]) dnl Checks for all prerequisites of the po subdirectory, dnl except for USE_NLS. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.11 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_OUTPUT_COMMANDS([ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' fi case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= GMOFILES= UPDATEPOFILES= DUMMYPOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it # from automake. eval 'ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Checks for all prerequisites of the intl subdirectory, dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. AC_DEFUN([AM_INTL_SUBDIR], [ AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_ISC_POSIX])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_C_CONST])dnl AC_REQUIRE([AC_C_INLINE])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_REQUIRE([jm_GLIBC21])dnl AC_REQUIRE([gt_INTDIV0])dnl AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl AC_REQUIRE([gt_INTTYPES_PRI])dnl AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ stdlib.h string.h unistd.h sys/param.h]) AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) AM_ICONV AM_LANGINFO_CODESET if test $ac_cv_header_locale_h = yes; then AM_LC_MESSAGES fi dnl intl/plural.c is generated from intl/plural.y. It requires bison, dnl because plural.y uses bison specific features. It requires at least dnl bison-1.26 because earlier versions generate a plural.c that doesn't dnl compile. dnl bison is only needed for the maintainer (who touches plural.y). But in dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put dnl the rule in general Makefile. Now, some people carelessly touch the dnl files or have a broken "make" program, hence the plural.c rule will dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not dnl present or too old. AC_CHECK_PROGS([INTLBISON], [bison]) if test -z "$INTLBISON"; then ac_verc_fail=yes else dnl Found it, now check the version. AC_MSG_CHECKING([version of bison]) changequote(<<,>>)dnl ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) changequote([,])dnl ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac AC_MSG_RESULT([$ac_prog_version]) fi if test $ac_verc_fail = yes; then INTLBISON=: fi ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate is. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) gvpe-3.0/m4/glibc21.m40000644000000000000000000000172711046631517011224 00000000000000# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # Test for the GNU C Library, version 2.1 or newer. # From Bruno Haible. AC_DEFUN([jm_GLIBC21], [ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, ac_cv_gnu_library_2_1, [AC_EGREP_CPP([Lucky GNU user], [ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif ], ac_cv_gnu_library_2_1=yes, ac_cv_gnu_library_2_1=no) ] ) AC_SUBST(GLIBC21) GLIBC21="$ac_cv_gnu_library_2_1" ] ) gvpe-3.0/m4/iconv.m40000644000000000000000000000665311046631517011122 00000000000000# iconv.m4 serial AM4 (gettext-0.11.3) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST(LIBICONV) AC_SUBST(LTLIBICONV) ]) AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi ]) gvpe-3.0/m4/intdiv0.m40000644000000000000000000000356511046631517011360 00000000000000# intdiv0.m4 serial 1 (gettext-0.11.3) dnl Copyright (C) 2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([gt_INTDIV0], [ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], gt_cv_int_divbyzero_sigfpe, [ AC_TRY_RUN([ #include #include static void #ifdef __cplusplus sigfpe_handler (int sig) #else sigfpe_handler (sig) int sig; #endif { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (1); } ], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, [ # Guess based on the CPU. case "$host_cpu" in alpha* | i[34567]86 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac ]) ]) case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, [Define if integer division by zero raises signal SIGFPE.]) ]) gvpe-3.0/m4/inttypes-pri.m40000644000000000000000000000222711046631517012444 00000000000000# inttypes-pri.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. # Define PRI_MACROS_BROKEN if exists and defines the PRI* # macros to non-string values. This is the case on AIX 4.3.3. AC_DEFUN([gt_INTTYPES_PRI], [ AC_REQUIRE([gt_HEADER_INTTYPES_H]) if test $gt_cv_header_inttypes_h = yes; then AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], gt_cv_inttypes_pri_broken, [ AC_TRY_COMPILE([#include #ifdef PRId32 char *p = PRId32; #endif ], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) ]) fi if test "$gt_cv_inttypes_pri_broken" = yes; then AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, [Define if exists and defines unusable PRI* macros.]) fi ]) gvpe-3.0/m4/inttypes.m40000644000000000000000000000171711046631517011657 00000000000000# inttypes.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H if exists and doesn't clash with # . AC_DEFUN([gt_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, [ AC_TRY_COMPILE( [#include #include ], [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) ]) if test $gt_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, [Define if exists and doesn't clash with .]) fi ]) gvpe-3.0/m4/inttypes_h.m40000644000000000000000000000207311046631517012162 00000000000000# inttypes_h.m4 serial 4 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_inttypes_h=yes, jm_ac_cv_header_inttypes_h=no)]) if test $jm_ac_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) gvpe-3.0/m4/isc-posix.m40000644000000000000000000000213311046631517011707 00000000000000# isc-posix.m4 serial 2 (gettext-0.11.2) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # This file is not needed with autoconf-2.53 and newer. Remove it in 2005. # This test replaces the one in autoconf. # Currently this macro should have the same name as the autoconf macro # because gettext's gettext.m4 (distributed in the automake package) # still uses it. Otherwise, the use in gettext.m4 makes autoheader # give these diagnostics: # configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX # configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX undefine([AC_ISC_POSIX]) AC_DEFUN([AC_ISC_POSIX], [ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ] ) gvpe-3.0/m4/lcmessage.m40000644000000000000000000000261611046631517011742 00000000000000# lcmessage.m4 serial 3 (gettext-0.11.3) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995. # Check whether LC_MESSAGES is available in . AC_DEFUN([AM_LC_MESSAGES], [ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your file defines LC_MESSAGES.]) fi ]) gvpe-3.0/m4/lib-ld.m40000644000000000000000000000626011046631517011141 00000000000000# lib-ld.m4 serial 1 (gettext-0.11) dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl Subroutines of libtool.m4, dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision dnl with libtool.m4. dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then acl_cv_prog_gnu_ld=yes else acl_cv_prog_gnu_ld=no fi]) with_gnu_ld=$acl_cv_prog_gnu_ld ]) dnl From libtool-1.4. Sets the variable LD. AC_DEFUN([AC_LIB_PROG_LD], [AC_ARG_WITH(gnu-ld, [ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by GCC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]* | [A-Za-z]:[\\/]*)] [re_direlt='/[^/][^/]*/\.\./'] # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(acl_cv_path_LD, [if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break fi fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$acl_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) AC_LIB_PROG_LD_GNU ]) gvpe-3.0/m4/lib-link.m40000644000000000000000000005563311046631517011507 00000000000000# lib-link.m4 serial 3 (gettext-0.11.3) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes undefine([Name]) undefine([NAME]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. If found, it dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" LIBS="$LIBS $LIB[]NAME" AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) undefine([Name]) undefine([NAME]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, dnl hardcode_direct, hardcode_minus_L, dnl sys_lib_search_path_spec, sys_lib_dlsearch_path_spec. AC_DEFUN([AC_LIB_RPATH], [ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE(rpath, [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH([lib$1-prefix], [ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib --without-lib$1-prefix don't search for lib$1 in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) gvpe-3.0/m4/lib-prefix.m40000644000000000000000000001175511046631517012044 00000000000000# lib-prefix.m4 serial 1 (gettext-0.11) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) gvpe-3.0/m4/openssl.m40000644000000000000000000000235012167124064011454 00000000000000dnl Check to find the OpenSSL headers/libraries AC_DEFUN([tinc_OPENSSL], [ tinc_ac_save_CPPFLAGS="$CPPFLAGS" AC_ARG_WITH(openssl-include, [ --with-openssl-include=DIR OpenSSL headers directory (without trailing /openssl)], [openssl_include="$withval" CFLAGS="$CFLAGS -I$withval" CPPFLAGS="$CPPFLAGS -I$withval"] ) AC_ARG_WITH(openssl-lib, [ --with-openssl-lib=DIR OpenSSL library directory], [openssl_lib="$withval" LIBS="$LIBS -L$withval"] ) AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h, [], [AC_MSG_ERROR([OpenSSL header files not found.]); break] ) CPPFLAGS="$tinc_ac_save_CPPFLAGS" AC_CHECK_LIB(crypto, SHA1_Init, [LIBS="$LIBS -lcrypto"], [AC_MSG_ERROR([OpenSSL libraries not found.])] ) AC_CHECK_FUNCS([RAND_pseudo_bytes OPENSSL_add_all_algorithms_noconf OpenSSL_add_all_algorithms SSLeay_add_all_algorithms]) AC_CHECK_FUNC(dlopen, [], [AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"], [AC_MSG_ERROR([OpenSSL depends on libdl.])] )] ) AC_CHECK_FUNC(inflate, [], [AC_CHECK_LIB(z, inflate, [LIBS="$LIBS -lz"], [AC_MSG_ERROR([OpenSSL depends on libz.])] )] ) ]) gvpe-3.0/m4/progtest.m40000644000000000000000000000407411046631517011646 00000000000000# progtest.m4 serial 2 (gettext-0.10.40) dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) gvpe-3.0/m4/stdint_h.m40000644000000000000000000000204311046631517011605 00000000000000# stdint_h.m4 serial 2 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_STDINT_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_STDINT_H], [ AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_stdint_h=yes, jm_ac_cv_header_stdint_h=no)]) if test $jm_ac_cv_header_stdint_h = yes; then AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) gvpe-3.0/m4/tuntap.m40000644000000000000000000000205012167124053011277 00000000000000dnl Check to find out whether the running kernel has support for TUN/TAP AC_DEFUN([tinc_TUNTAP], [ AC_ARG_WITH(kernel, [ --with-kernel=dir give the directory with kernel sources] [ (default: /usr/src/linux)], kerneldir="$withval", kerneldir="/usr/src/linux" ) AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h, [ AC_TRY_COMPILE([#include "$kerneldir/include/linux/if_tun.h"], [int a = IFF_TAP;], if_tun_h="\"$kerneldir/include/linux/if_tun.h\"", [AC_TRY_COMPILE([#include ], [int a = IFF_TAP;], if_tun_h="default", if_tun_h="no" )] ) if test $if_tun_h = no; then tinc_cv_linux_if_tun_h=none else tinc_cv_linux_if_tun_h="$if_tun_h" fi ]) if test $tinc_cv_linux_if_tun_h != none; then AC_DEFINE(HAVE_TUNTAP, 1, [Universal tun/tap driver present]) if test $tinc_cv_linux_if_tun_h != default; then AC_DEFINE_UNQUOTED(LINUX_IF_TUN_H, $tinc_cv_linux_if_tun_h, [Location of if_tun.h]) fi fi AC_SUBST(LINUX_IF_TUN_H) AC_SUBST(HAVE_TUNTAP) ]) gvpe-3.0/m4/uintmax_t.m40000644000000000000000000000211411046631517012000 00000000000000# uintmax_t.m4 serial 6 (gettext-0.11) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_PREREQ(2.13) # Define uintmax_t to `unsigned long' or `unsigned long long' # if does not exist. AC_DEFUN([jm_AC_TYPE_UINTMAX_T], [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) AC_REQUIRE([jm_AC_HEADER_STDINT_H]) if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) test $ac_cv_type_unsigned_long_long = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, [Define to unsigned long or unsigned long long if and don't define.]) fi ]) gvpe-3.0/m4/ulonglong.m40000644000000000000000000000200011046631517011766 00000000000000# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], [ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, [Define if you have the unsigned long long type.]) fi ]) gvpe-3.0/lib/0000755000000000000000000000000013011103357010024 500000000000000gvpe-3.0/lib/pidfile.h0000644000000000000000000000321212167136742011546 00000000000000/* pidfile.h - interact with pidfiles Copyright (c) 1995 Martin Schulze This file is part of the sysklogd package, a kernel and system log daemon. This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #if __cplusplus extern "C" { #endif /* read_pid * * Reads the specified pidfile and returns the read pid. * 0 is returned if either there's no pidfile, it's empty * or no pid can be read. */ int read_pid (char *pidfile); /* check_pid * * Reads the pid using read_pid and looks up the pid in the process * table (using /proc) to determine if the process already exists. If * so 1 is returned, otherwise 0. */ int check_pid (char *pidfile); /* write_pid * * Writes the pid to the specified file. If that fails 0 is * returned, otherwise the pid. */ int write_pid (char *pidfile); /* remove_pid * * Remove the the specified file. The result from unlink(2) * is returned */ int remove_pid (char *pidfile); #if __cplusplus } #endif gvpe-3.0/lib/getopt.h0000644000000000000000000001066412167136742011445 00000000000000/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ gvpe-3.0/lib/dropin.h0000644000000000000000000000237012167136742011431 00000000000000/* dropin.h -- header file for dropin.c Copyright (C) 2000,2001 Ivo Timmermans , 2000,2001 Guus Sliepen This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DROPIN_H__ #define __DROPIN_H__ #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_DAEMON extern int daemon(int, int); #endif #ifndef HAVE_GET_CURRENT_DIR_NAME extern char *get_current_dir_name(void); #endif #ifndef HAVE_ASPRINTF extern int asprintf(char **, const char *, ...); #endif #ifdef __cplusplus } #endif #endif /* __DROPIN_H__ */ gvpe-3.0/lib/gettext.h0000644000000000000000000000635212167136742011626 00000000000000/* Convenience header for conditional use of GNU . Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. This file is part of GVPE. GVPE is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 #if __cplusplus # include CLOCALE #else # include #endif /* NLS can be disabled through the configure --disable-nls option. */ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include /* Shorthand notation */ # define _(Text) gettext (Text) #else /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # define gettext(Msgid) ((const char *) (Msgid)) # define dgettext(Domainname, Msgid) ((const char *) (Msgid)) # define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define textdomain(Domainname) ((const char *) (Domainname)) # define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) # define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) # define _(Text) Text //# define setlocale(Category, Locale) ((const char *) (Locale)) #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #define gettext_noop(String) String #define N_(Text) Text #endif /* _LIBGETTEXT_H */ gvpe-3.0/lib/Makefile.in0000644000000000000000000003074213011103322012007 00000000000000# Makefile.in generated by automake 1.7.9 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # 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@ 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 = : host_triplet = @host@ 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@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_TUNTAP = @HAVE_TUNTAP@ IFSUBTYPE = @IFSUBTYPE@ IFTYPE = @IFTYPE@ INCLUDES = @INCLUDES@ -I. -I$(top_builddir) INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DAEMON = @LDFLAGS_DAEMON@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LINUX_IF_TUN_H = @LINUX_IF_TUN_H@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ POSUB = @POSUB@ RANLIB = @RANLIB@ ROHC_FALSE = @ROHC_FALSE@ ROHC_TRUE = @ROHC_TRUE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ noinst_LIBRARIES = libgvpe.a libgvpe_a_SOURCES = pidfile.c getopt.c getopt1.c dropin.c libgvpe_a_LIBADD = @LIBOBJS@ @ALLOCA@ libgvpe_a_DEPENDENCIES = $(libgvpe_a_LIBADD) noinst_HEADERS = pidfile.h getopt.h dropin.h gettext.h subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libgvpe_a_AR = $(AR) cru am_libgvpe_a_OBJECTS = pidfile.$(OBJEXT) getopt.$(OBJEXT) \ getopt1.$(OBJEXT) dropin.$(OBJEXT) libgvpe_a_OBJECTS = $(am_libgvpe_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = $(DEPDIR)/alloca.Po ./$(DEPDIR)/dropin.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/getopt.Po ./$(DEPDIR)/getopt1.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/pidfile.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libgvpe_a_SOURCES) HEADERS = $(noinst_HEADERS) DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am \ alloca.c SOURCES = $(libgvpe_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) AR = ar clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgvpe.a: $(libgvpe_a_OBJECTS) $(libgvpe_a_DEPENDENCIES) -rm -f libgvpe.a $(libgvpe_a_AR) libgvpe.a $(libgvpe_a_OBJECTS) $(libgvpe_a_LIBADD) $(RANLIB) libgvpe.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidfile.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ 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 `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ 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 `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS 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: $(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 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) 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"; \ $(mkinstalldirs) "$(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 $(LIBRARIES) $(HEADERS) 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: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-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) ./$(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-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-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 # 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: gvpe-3.0/lib/Makefile.am0000644000000000000000000000042211046631516012007 00000000000000noinst_LIBRARIES = libgvpe.a INCLUDES = @INCLUDES@ -I. -I$(top_builddir) libgvpe_a_SOURCES = pidfile.c getopt.c getopt1.c dropin.c libgvpe_a_LIBADD = @LIBOBJS@ @ALLOCA@ libgvpe_a_DEPENDENCIES = $(libgvpe_a_LIBADD) noinst_HEADERS = pidfile.h getopt.h dropin.h gettext.h gvpe-3.0/lib/alloca.c0000644000000000000000000003366011524347421011364 00000000000000/* alloca.c -- allocate automatically reclaimed memory (Mostly) portable public-domain implementation -- D A Gwyn This implementation of the PWB library alloca function, which is used to allocate space off the run-time stack so that it is automatically reclaimed upon procedure exit, was inspired by discussions with J. Q. Johnson of Cornell. J.Otto Tennant contributed the Cray support. There are some preprocessor constants that can be defined when compiling for your specific system, for improved efficiency; however, the defaults should be okay. The general concept of this implementation is to keep track of all alloca-allocated blocks, and reclaim any that are found to be deeper in the stack than the current invocation. This heuristic does not reclaim storage as soon as it becomes invalid, but it will do so eventually. As a special case, alloca(0) reclaims storage without allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef emacs # include "blockinput.h" #endif /* If compiling with GCC 2, this file's not needed. */ #if !defined (__GNUC__) || __GNUC__ < 2 /* If someone has defined alloca as a macro, there must be some other way alloca is supposed to work. */ # ifndef alloca # ifdef emacs # ifdef static /* actually, only want this if static is defined as "" -- this is for usg, in which emacs must undefine static in order to make unexec workable */ # ifndef STACK_DIRECTION you lose -- must know STACK_DIRECTION at compile-time # endif /* STACK_DIRECTION undefined */ # endif /* static */ # endif /* emacs */ /* If your stack is a linked list of frames, you have to provide an "address metric" ADDRESS_FUNCTION macro. */ # if defined (CRAY) && defined (CRAY_STACKSEG_END) long i00afunc (); # define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) # else # define ADDRESS_FUNCTION(arg) &(arg) # endif # if __STDC__ typedef void *pointer; # else typedef char *pointer; # endif # ifndef NULL # define NULL 0 # endif /* Different portions of Emacs need to call different versions of malloc. The Emacs executable needs alloca to call xmalloc, because ordinary malloc isn't protected from input signals. On the other hand, the utilities in lib-src need alloca to call malloc; some of them are very simple, and don't have an xmalloc routine. Non-Emacs programs expect this to call xmalloc. Callers below should use malloc. */ # ifndef emacs # define malloc xmalloc # endif extern pointer malloc (); /* Define STACK_DIRECTION 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 */ # ifndef STACK_DIRECTION # define STACK_DIRECTION 0 /* Direction unknown. */ # endif # if STACK_DIRECTION != 0 # define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ # else /* STACK_DIRECTION == 0; need run-time code. */ static int stack_dir; /* 1 or -1 once known. */ # define STACK_DIR stack_dir static void find_stack_direction () { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ if (addr == NULL) { /* Initial entry. */ addr = ADDRESS_FUNCTION (dummy); find_stack_direction (); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION (dummy) > addr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } } # endif /* STACK_DIRECTION == 0 */ /* An "alloca header" is used to: (a) chain together all alloca'ed blocks; (b) keep track of stack depth. It is very important that sizeof(header) agree with malloc alignment chunk size. The following default should work okay. */ # ifndef ALIGN_SIZE # define ALIGN_SIZE sizeof(double) # endif typedef union hdr { char align[ALIGN_SIZE]; /* To force sizeof(header). */ struct { union hdr *next; /* For chaining headers. */ char *deep; /* For stack depth measure. */ } h; } header; static header *last_alloca_header = NULL; /* -> last alloca header. */ /* Return a pointer to at least SIZE bytes of storage, which will be automatically reclaimed upon exit from the procedure that called alloca. Originally, this space was supposed to be taken from the current stack frame of the caller, but that method cannot be made to work for some implementations of C, for example under Gould's UTX/32. */ pointer alloca (size) unsigned size; { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); # if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* Unknown growth direction. */ find_stack_direction (); # endif /* Reclaim garbage, defined as all alloca'd storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* Traverses linked list. */ # ifdef emacs BLOCK_INPUT; # endif for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((pointer) hp); /* Collect garbage. */ hp = np; /* -> next header. */ } else break; /* Rest are not deeper. */ last_alloca_header = hp; /* -> last valid storage. */ # ifdef emacs UNBLOCK_INPUT; # endif } if (size == 0) return NULL; /* No allocation required. */ /* Allocate combined header + user data storage. */ { register pointer new = malloc (sizeof (header) + size); /* Address of header. */ ((header *) new)->h.next = last_alloca_header; ((header *) new)->h.deep = depth; last_alloca_header = (header *) new; /* User storage begins just after header. */ return (pointer) ((char *) new + sizeof (header)); } } # if defined (CRAY) && defined (CRAY_STACKSEG_END) # ifdef DEBUG_I00AFUNC # include # endif # ifndef CRAY_STACK # define CRAY_STACK # ifndef CRAY2 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ struct stack_control_header { long shgrow:32; /* Number of times stack has grown. */ long shaseg:32; /* Size of increments to stack. */ long shhwm:32; /* High water mark of stack. */ long shsize:32; /* Current size of stack (all segments). */ }; /* The stack segment linkage control information occurs at the high-address end of a stack segment. (The stack grows from low addresses to high addresses.) The initial part of the stack segment linkage control information is 0200 (octal) words. This provides for register storage for the routine which overflows the stack. */ struct stack_segment_linkage { long ss[0200]; /* 0200 overflow words. */ long sssize:32; /* Number of words in this segment. */ long ssbase:32; /* Offset to stack base. */ long:32; long sspseg:32; /* Offset to linkage control of previous segment of stack. */ long:32; long sstcpt:32; /* Pointer to task common address block. */ long sscsnm; /* Private control structure number for microtasking. */ long ssusr1; /* Reserved for user. */ long ssusr2; /* Reserved for user. */ long sstpid; /* Process ID for pid based multi-tasking. */ long ssgvup; /* Pointer to multitasking thread giveup. */ long sscray[7]; /* Reserved for Cray Research. */ long ssa0; long ssa1; long ssa2; long ssa3; long ssa4; long ssa5; long ssa6; long ssa7; long sss0; long sss1; long sss2; long sss3; long sss4; long sss5; long sss6; long sss7; }; # else /* CRAY2 */ /* The following structure defines the vector of words returned by the STKSTAT library routine. */ struct stk_stat { long now; /* Current total stack size. */ long maxc; /* Amount of contiguous space which would be required to satisfy the maximum stack demand to date. */ long high_water; /* Stack high-water mark. */ long overflows; /* Number of stack overflow ($STKOFEN) calls. */ long hits; /* Number of internal buffer hits. */ long extends; /* Number of block extensions. */ long stko_mallocs; /* Block allocations by $STKOFEN. */ long underflows; /* Number of stack underflow calls ($STKRETN). */ long stko_free; /* Number of deallocations by $STKRETN. */ long stkm_free; /* Number of deallocations by $STKMRET. */ long segments; /* Current number of stack segments. */ long maxs; /* Maximum number of stack segments so far. */ long pad_size; /* Stack pad size. */ long current_address; /* Current stack segment address. */ long current_size; /* Current stack segment size. This number is actually corrupted by STKSTAT to include the fifteen word trailer area. */ long initial_address; /* Address of initial segment. */ long initial_size; /* Size of initial segment. */ }; /* The following structure describes the data structure which trails any stack segment. I think that the description in 'asdef' is out of date. I only describe the parts that I am sure about. */ struct stk_trailer { long this_address; /* Address of this block. */ long this_size; /* Size of this block (does not include this trailer). */ long unknown2; long unknown3; long link; /* Address of trailer block of previous segment. */ long unknown5; long unknown6; long unknown7; long unknown8; long unknown9; long unknown10; long unknown11; long unknown12; long unknown13; long unknown14; }; # endif /* CRAY2 */ # endif /* not CRAY_STACK */ # ifdef CRAY2 /* Determine a "stack measure" for an arbitrary ADDRESS. I doubt that "lint" will like this much. */ static long i00afunc (long *address) { struct stk_stat status; struct stk_trailer *trailer; long *block, size; long result = 0; /* We want to iterate through all of the segments. The first step is to get the stack status structure. We could do this more quickly and more directly, perhaps, by referencing the $LM00 common block, but I know that this works. */ STKSTAT (&status); /* Set up the iteration. */ trailer = (struct stk_trailer *) (status.current_address + status.current_size - 15); /* There must be at least one stack segment. Therefore it is a fatal error if "trailer" is null. */ if (trailer == 0) abort (); /* Discard segments that do not contain our argument address. */ while (trailer != 0) { block = (long *) trailer->this_address; size = trailer->this_size; if (block == 0 || size == 0) abort (); trailer = (struct stk_trailer *) trailer->link; if ((block <= address) && (address < (block + size))) break; } /* Set the result to the offset in this segment and add the sizes of all predecessor segments. */ result = address - block; if (trailer == 0) { return result; } do { if (trailer->this_size <= 0) abort (); result += trailer->this_size; trailer = (struct stk_trailer *) trailer->link; } while (trailer != 0); /* We are done. Note that if you present a bogus address (one not in any segment), you will get a different number back, formed from subtracting the address of the first block. This is probably not what you want. */ return (result); } # else /* not CRAY2 */ /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. Determine the number of the cell within the stack, given the address of the cell. The purpose of this routine is to linearize, in some sense, stack addresses for alloca. */ static long i00afunc (long address) { long stkl = 0; long size, pseg, this_segment, stack; long result = 0; struct stack_segment_linkage *ssptr; /* Register B67 contains the address of the end of the current stack segment. If you (as a subprogram) store your registers on the stack and find that you are past the contents of B67, you have overflowed the segment. B67 also points to the stack segment linkage control area, which is what we are really interested in. */ stkl = CRAY_STACKSEG_END (); ssptr = (struct stack_segment_linkage *) stkl; /* If one subtracts 'size' from the end of the segment, one has the address of the first word of the segment. If this is not the first segment, 'pseg' will be nonzero. */ pseg = ssptr->sspseg; size = ssptr->sssize; this_segment = stkl - size; /* It is possible that calling this routine itself caused a stack overflow. Discard stack segments which do not contain the target address. */ while (!(this_segment <= address && address <= stkl)) { # ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); # endif if (pseg == 0) break; stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; this_segment = stkl - size; } result = address - this_segment; /* If you subtract pseg from the current end of the stack, you get the address of the previous stack segment's end. This seems a little convoluted to me, but I'll bet you save a cycle somewhere. */ while (pseg != 0) { # ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o\n", pseg, size); # endif stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; result += size; } return (result); } # endif /* not CRAY2 */ # endif /* CRAY */ # endif /* no alloca */ #endif /* not GCC version 2 */ gvpe-3.0/lib/pidfile.c0000644000000000000000000000636311524347421011545 00000000000000/* pidfile.c - interact with pidfiles Copyright (c) 1995 Martin Schulze This file is part of the sysklogd package, a kernel and system log daemon. This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA */ /* * Sat Aug 19 13:24:33 MET DST 1995: Martin Schulze * First version (v0.2) released */ #include #include #include #include #include #include #include #include #include #include /* read_pid * * Reads the specified pidfile and returns the read pid. * 0 is returned if either there's no pidfile, it's empty * or no pid can be read. */ int read_pid (char *pidfile) { FILE *f; int pid; if (!(f=fopen(pidfile,"r"))) return 0; fscanf(f,"%d", &pid); fclose(f); return pid; } /* check_pid * * Reads the pid using read_pid and looks up the pid in the process * table (using /proc) to determine if the process already exists. If * so 1 is returned, otherwise 0. */ int check_pid (char *pidfile) { int pid = read_pid(pidfile); /* Amazing ! _I_ am already holding the pid file... */ if ((!pid) || (pid == getpid ())) return 0; /* * The 'standard' method of doing this is to try and do a 'fake' kill * of the process. If an ESRCH error is returned the process cannot * be found -- GW */ /* But... errno is usually changed only on error.. */ errno = 0; if (kill(pid, 0) && errno == ESRCH) return(0); return pid; } /* write_pid * * Writes the pid to the specified file. If that fails 0 is * returned, otherwise the pid. */ int write_pid (char *pidfile) { FILE *f; int fd; int pid; if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1) || ((f = fdopen(fd, "r+")) == NULL) ) { fprintf(stderr, "Can't open or create %s.\n", pidfile ? pidfile : "(null)"); return 0; } #ifdef HAVE_FLOCK if (flock(fd, LOCK_EX|LOCK_NB) == -1) { fscanf(f, "%d", &pid); fclose(f); printf("Can't lock, lock is held by pid %d.\n", pid); return 0; } #endif pid = getpid(); if (!fprintf(f,"%d\n", pid)) { printf("Can't write pid , %s.\n", strerror(errno)); close(fd); return 0; } fflush(f); #ifdef HAVE_FLOCK if (flock(fd, LOCK_UN) == -1) { printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno)); close(fd); return 0; } #endif close(fd); return pid; } /* remove_pid * * Remove the the specified file. The result from unlink(2) * is returned */ int remove_pid (char *pidfile) { return unlink (pidfile); } gvpe-3.0/lib/getopt.c0000644000000000000000000007234211524347421011433 00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #ifdef HAVE_CONFIG_H #include #endif #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include #endif /* GNU C library. */ #ifdef VMS #include #if HAVE_STRING_H - 0 #include #endif #endif #if defined (WIN32) && !defined (__CYGWIN32__) /* It's not Unix, really. See? Capital letters. */ #include #define getpid() GetCurrentProcessId() #endif #include "gettext.h" /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* 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. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; extern pid_t __libc_pid; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } text_set_element (__libc_subinit, store_args_and_env); # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* 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,optind), 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. */ #if defined (__STDC__) && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; 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. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); memset (&new_str[nonoption_flags_max_len], '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif 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; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* 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; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else { memcpy (__getopt_nonoption_flags, orig_str, len); memset (&__getopt_nonoption_flags[len], '\0', nonoption_flags_max_len - len); } } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. 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. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ gvpe-3.0/lib/getopt1.c0000644000000000000000000001067011524347421011510 00000000000000/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #endif #include "getopt.h" #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ gvpe-3.0/lib/dropin.c0000644000000000000000000000704711524347421011424 00000000000000/* dropin.c -- a set of drop-in replacements for libc functions Copyright (C) 2000,2001 Ivo Timmermans , 2000,2001 Guus Sliepen 2003 Marc Lehmann This file is part of GVPE. GVPE 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 gvpe; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include #include #include #ifndef HAVE_DAEMON /* Replacement for the daemon() function. The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. Unless the argument nochdir is non-zero, daemon() changes the current working directory to the root (``/''). Unless the argument noclose is non-zero, daemon() will redirect standard input, standard output and standard error to /dev/null. */ int daemon(int nochdir, int noclose) { pid_t pid; int fd; pid = fork(); /* Check if forking failed */ if(pid < 0) { perror("fork"); exit(-1); } /* If we are the parent, terminate */ if(pid) exit(0); /* Detach by becoming the new process group leader */ if(setsid() < 0) { perror("setsid"); return -1; } /* Change working directory to the root (to avoid keeping mount points busy) */ if(!nochdir) { chdir("/"); } /* Redirect stdin/out/err to /dev/null */ if(!noclose) { fd = open("/dev/null", O_RDWR); if(fd < 0) { perror("opening /dev/null"); return -1; } else { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); } } return 0; } #endif #ifndef HAVE_GET_CURRENT_DIR_NAME /* Replacement for the GNU get_current_dir_name function: get_current_dir_name will malloc(3) an array big enough to hold the current directory name. If the environment variable PWD is set, and its value is correct, then that value will be returned. */ char *get_current_dir_name(void) { size_t size; char *buf; char *r; /* Start with 100 bytes. If this turns out to be insufficient to contain the working directory, double the size. */ size = 100; buf = malloc(size); errno = 0; /* Success */ r = getcwd(buf, size); /* getcwd returns NULL and sets errno to ERANGE if the bufferspace is insufficient to contain the entire working directory. */ while(r == NULL && errno == ERANGE) { free(buf); size <<= 1; /* double the size */ buf = malloc(size); r = getcwd(buf, size); } return buf; } #endif #ifndef HAVE_ASPRINTF int asprintf(char **buf, const char *fmt, ...) { int status; va_list ap; int len; len = 4096; *buf = malloc(len); va_start(ap, fmt); status = vsnprintf(*buf, len, fmt, ap); va_end(ap); if(status >= 0) *buf = realloc(*buf, status); if(status > len - 1) { len = status; va_start(ap, fmt); status = vsnprintf(*buf, len, fmt, ap); va_end(ap); } return status; } #endif gvpe-3.0/src/0000755000000000000000000000000013011103357010045 500000000000000gvpe-3.0/src/lzf/0000755000000000000000000000000013011103357010640 500000000000000gvpe-3.0/src/lzf/lzf.h0000644000000000000000000001035511524347500011537 00000000000000/* * Copyright (c) 2000-2007 Marc Alexander Lehmann * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef LZF_H #define LZF_H /*********************************************************************** ** ** lzf -- an extremely fast/free compression/decompression-method ** http://liblzf.plan9.de/ ** ** This algorithm is believed to be patent-free. ** ***********************************************************************/ #define LZF_VERSION 0x0105 /* 1.5 */ /* * Compress in_len bytes stored at the memory block starting at * in_data and write the result to out_data, up to a maximum length * of out_len bytes. * * If the output buffer is not large enough or any error occurs * return 0, otherwise return the number of bytes used (which might * be considerably larger than in_len, so it makes sense to always * use out_len == in_len - 1), to ensure _some_ compression, and store * the data uncompressed otherwise. * * lzf_compress might use different algorithms on different systems and * even different runs, thus might result in different compressed strings * depending on the phase of the moon or similar factors. However, all * these strings are architecture-independent and will result in the * original data when decompressed using lzf_decompress. * * The buffers must not be overlapping. * * If the option LZF_STATE_ARG is enabled, an extra argument must be * supplied which is not reflected in this header file. Refer to lzfP.h * and lzf_c.c. * */ unsigned int lzf_compress (const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len); /* * Decompress data compressed with some version of the lzf_compress * function and stored at location in_data and length in_len. The result * will be stored at out_data up to a maximum of out_len characters. * * If the output buffer is not large enough to hold the decompressed * data, a 0 is returned and errno is set to E2BIG. Otherwise the number * of decompressed bytes (i.e. the original length of the data) is * returned. * * If an error in the compressed data is detected, a zero is returned and * errno is set to EINVAL. * * This function is very fast, about as fast as a copying loop. */ unsigned int lzf_decompress (const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len); #endif gvpe-3.0/src/lzf/lzfP.h0000644000000000000000000001204011524347500011650 00000000000000/* * Copyright (c) 2000-2007 Marc Alexander Lehmann * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #ifndef LZFP_h #define LZFP_h #define STANDALONE 1 /* at the moment, this is ok. */ #ifndef STANDALONE # include "lzf.h" #endif /* * Size of hashtable is (1 << HLOG) * sizeof (char *) * decompression is independent of the hash table size * the difference between 15 and 14 is very small * for small blocks (and 14 is usually a bit faster). * For a low-memory/faster configuration, use HLOG == 13; * For best compression, use 15 or 16 (or more, up to 23). */ #ifndef HLOG # define HLOG 16 #endif /* * Sacrifice very little compression quality in favour of compression speed. * This gives almost the same compression as the default code, and is * (very roughly) 15% faster. This is the preferred mode of operation. */ #ifndef VERY_FAST # define VERY_FAST 1 #endif /* * Sacrifice some more compression quality in favour of compression speed. * (roughly 1-2% worse compression for large blocks and * 9-10% for small, redundant, blocks and >>20% better speed in both cases) * In short: when in need for speed, enable this for binary data, * possibly disable this for text data. */ #ifndef ULTRA_FAST # define ULTRA_FAST 0 #endif /* * Unconditionally aligning does not cost very much, so do it if unsure */ #ifndef STRICT_ALIGN # define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) #endif /* * You may choose to pre-set the hash table (might be faster on some * modern cpus and large (>>64k) blocks, and also makes compression * deterministic/repeatable when the configuration otherwise is the same). */ #ifndef INIT_HTAB # define INIT_HTAB 0 #endif /* * Avoid assigning values to errno variable? for some embedding purposes * (linux kernel for example), this is neccessary. NOTE: this breaks * the documentation in lzf.h. */ #ifndef AVOID_ERRNO # define AVOID_ERRNO 0 #endif /* * Wether to pass the LZF_STATE variable as argument, or allocate it * on the stack. For small-stack environments, define this to 1. * NOTE: this breaks the prototype in lzf.h. */ #ifndef LZF_STATE_ARG # define LZF_STATE_ARG 0 #endif /* * Wether to add extra checks for input validity in lzf_decompress * and return EINVAL if the input stream has been corrupted. This * only shields against overflowing the input buffer and will not * detect most corrupted streams. * This check is not normally noticable on modern hardware * (<1% slowdown), but might slow down older cpus considerably. */ #ifndef CHECK_INPUT # define CHECK_INPUT 1 #endif /*****************************************************************************/ /* nothing should be changed below */ typedef unsigned char u8; typedef const u8 *LZF_STATE[1 << (HLOG)]; #if !STRICT_ALIGN /* for unaligned accesses we need a 16 bit datatype. */ # include # if USHRT_MAX == 65535 typedef unsigned short u16; # elif UINT_MAX == 65535 typedef unsigned int u16; # else # undef STRICT_ALIGN # define STRICT_ALIGN 1 # endif #endif #if ULTRA_FAST # if defined(VERY_FAST) # undef VERY_FAST # endif #endif #if INIT_HTAB # ifdef __cplusplus # include # else # include # endif #endif #endif gvpe-3.0/src/lzf/lzf_c.c0000644000000000000000000002123211524347500012030 00000000000000/* * Copyright (c) 2000-2008 Marc Alexander Lehmann * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #include "lzfP.h" #define HSIZE (1 << (HLOG)) /* * don't play with this unless you benchmark! * decompression is not dependent on the hash function * the hashing function might seem strange, just believe me * it works ;) */ #ifndef FRST # define FRST(p) (((p[0]) << 8) | p[1]) # define NEXT(v,p) (((v) << 8) | p[2]) # if ULTRA_FAST # define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) # elif VERY_FAST # define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) # else # define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) # endif #endif /* * IDX works because it is very similar to a multiplicative hash, e.g. * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) * the latter is also quite fast on newer CPUs, and compresses similarly. * * the next one is also quite good, albeit slow ;) * (int)(cos(h & 0xffffff) * 1e6) */ #if 0 /* original lzv-like hash function, much worse and thus slower */ # define FRST(p) (p[0] << 5) ^ p[1] # define NEXT(v,p) ((v) << 5) ^ p[2] # define IDX(h) ((h) & (HSIZE - 1)) #endif #define MAX_LIT (1 << 5) #define MAX_OFF (1 << 13) #define MAX_REF ((1 << 8) + (1 << 3)) #if __GNUC__ >= 3 # define expect(expr,value) __builtin_expect ((expr),(value)) # define inline inline #else # define expect(expr,value) (expr) # define inline static #endif #define expect_false(expr) expect ((expr) != 0, 0) #define expect_true(expr) expect ((expr) != 0, 1) /* * compressed format * * 000LLLLL ; literal * LLLooooo oooooooo ; backref L * 111ooooo LLLLLLLL oooooooo ; backref L+7 * */ unsigned int lzf_compress (const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len #if LZF_STATE_ARG , LZF_STATE htab #endif ) { #if !LZF_STATE_ARG LZF_STATE htab; #endif const u8 **hslot; const u8 *ip = (const u8 *)in_data; u8 *op = (u8 *)out_data; const u8 *in_end = ip + in_len; u8 *out_end = op + out_len; const u8 *ref; /* off requires a type wide enough to hold a general pointer difference. * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only * works for differences within a single object). We also assume that no * no bit pattern traps. Since the only platform that is both non-POSIX * and fails to support both assumptions is windows 64 bit, we make a * special workaround for it. */ #if defined (WIN32) && defined (_M_X64) unsigned _int64 off; /* workaround for missing POSIX compliance */ #else unsigned long off; #endif unsigned int hval; int lit; if (!in_len || !out_len) return 0; #if INIT_HTAB memset (htab, 0, sizeof (htab)); # if 0 for (hslot = htab; hslot < htab + HSIZE; hslot++) *hslot++ = ip; # endif #endif lit = 0; op++; /* start run */ hval = FRST (ip); while (ip < in_end - 2) { hval = NEXT (hval, ip); hslot = htab + IDX (hval); ref = *hslot; *hslot = ip; if (1 #if INIT_HTAB && ref < ip /* the next test will actually take care of this, but this is faster */ #endif && (off = ip - ref - 1) < MAX_OFF && ip + 4 < in_end && ref > (u8 *)in_data #if STRICT_ALIGN && ref[0] == ip[0] && ref[1] == ip[1] && ref[2] == ip[2] #else && *(u16 *)ref == *(u16 *)ip && ref[2] == ip[2] #endif ) { /* match found at *ref++ */ unsigned int len = 2; unsigned int maxlen = in_end - ip - len; maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; op [- lit - 1] = lit - 1; /* stop run */ op -= !lit; /* undo run if length is zero */ if (expect_false (op + 3 + 1 >= out_end)) return 0; for (;;) { if (expect_true (maxlen > 16)) { len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; len++; if (ref [len] != ip [len]) break; } do len++; while (len < maxlen && ref[len] == ip[len]); break; } len -= 2; /* len is now #octets - 1 */ ip++; if (len < 7) { *op++ = (off >> 8) + (len << 5); } else { *op++ = (off >> 8) + ( 7 << 5); *op++ = len - 7; } *op++ = off; lit = 0; op++; /* start run */ ip += len + 1; if (expect_false (ip > in_end - 2)) break; #if ULTRA_FAST || VERY_FAST --ip; # if VERY_FAST && !ULTRA_FAST --ip; # endif hval = FRST (ip); hval = NEXT (hval, ip); htab[IDX (hval)] = ip; ip++; # if VERY_FAST && !ULTRA_FAST hval = NEXT (hval, ip); htab[IDX (hval)] = ip; ip++; # endif #else ip -= len + 1; do { hval = NEXT (hval, ip); htab[IDX (hval)] = ip; ip++; } while (len--); #endif } else { /* one more literal byte we must copy */ if (expect_false (op >= out_end)) return 0; lit++; *op++ = *ip++; if (expect_false (lit == MAX_LIT)) { op [- lit - 1] = lit - 1; /* stop run */ lit = 0; op++; /* start run */ } } } if (op + 3 > out_end) /* at most 3 bytes can be missing here */ return 0; while (ip < in_end) { lit++; *op++ = *ip++; if (expect_false (lit == MAX_LIT)) { op [- lit - 1] = lit - 1; /* stop run */ lit = 0; op++; /* start run */ } } op [- lit - 1] = lit - 1; /* end run */ op -= !lit; /* undo run if length is zero */ return op - (u8 *)out_data; } gvpe-3.0/src/lzf/lzf_d.c0000644000000000000000000001031211524347500012026 00000000000000/* * Copyright (c) 2000-2007 Marc Alexander Lehmann * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License ("GPL") version 2 or any later version, * in which case the provisions of the GPL are applicable instead of * the above. If you wish to allow the use of your version of this file * only under the terms of the GPL and not to allow others to use your * version of this file under the BSD license, indicate your decision * by deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete the * provisions above, a recipient may use your version of this file under * either the BSD or the GPL. */ #include "lzfP.h" #if AVOID_ERRNO # define SET_ERRNO(n) #else # include # define SET_ERRNO(n) errno = (n) #endif #if (__i386 || __amd64) && __GNUC__ >= 3 # define lzf_movsb(dst, src, len) \ asm ("rep movsb" \ : "=D" (dst), "=S" (src), "=c" (len) \ : "0" (dst), "1" (src), "2" (len)); #endif unsigned int lzf_decompress (const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len) { u8 const *ip = (const u8 *)in_data; u8 *op = (u8 *)out_data; u8 const *const in_end = ip + in_len; u8 *const out_end = op + out_len; do { unsigned int ctrl = *ip++; if (ctrl < (1 << 5)) /* literal run */ { ctrl++; if (op + ctrl > out_end) { SET_ERRNO (E2BIG); return 0; } #if CHECK_INPUT if (ip + ctrl > in_end) { SET_ERRNO (EINVAL); return 0; } #endif #ifdef lzf_movsb lzf_movsb (op, ip, ctrl); #else do *op++ = *ip++; while (--ctrl); #endif } else /* back reference */ { unsigned int len = ctrl >> 5; u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; #if CHECK_INPUT if (ip >= in_end) { SET_ERRNO (EINVAL); return 0; } #endif if (len == 7) { len += *ip++; #if CHECK_INPUT if (ip >= in_end) { SET_ERRNO (EINVAL); return 0; } #endif } ref -= *ip++; if (op + len + 2 > out_end) { SET_ERRNO (E2BIG); return 0; } if (ref < (u8 *)out_data) { SET_ERRNO (EINVAL); return 0; } #ifdef lzf_movsb len += 2; lzf_movsb (op, ref, len); #else *op++ = *ref++; *op++ = *ref++; do *op++ = *ref++; while (--len); #endif } } while (ip < in_end); return op - (u8 *)out_data; } gvpe-3.0/src/tincd/0000755000000000000000000000000013011103357011146 500000000000000gvpe-3.0/src/tincd/bsd/0000755000000000000000000000000013011103357011716 500000000000000gvpe-3.0/src/tincd/bsd/device.c0000644000000000000000000001617111524347501013257 00000000000000/* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2004 Ivo Timmermans , 2001-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2005-03-25 16:05:22 pcg Exp $ */ #define DEFAULT_DEVICE "/dev/tun0" typedef enum device_type { DEVICE_TYPE_TUN, DEVICE_TYPE_TUNIFHEAD, DEVICE_TYPE_TAP, } device_type_t; int device_fd = -1; char *device; char *iface; char *device_info; static int device_total_in = 0; static int device_total_out = 0; #ifdef HAVE_OPENBSD static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; #else static device_type_t device_type = DEVICE_TYPE_TUN; #endif bool setup_device(void) { char *type; cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; else if(!strcasecmp(type, "tunnohead")) device_type = DEVICE_TYPE_TUN; else if(!strcasecmp(type, "tunifhead")) device_type = DEVICE_TYPE_TUNIFHEAD; else if(!strcasecmp(type, "tap")) device_type = DEVICE_TYPE_TAP; else { logger(LOG_ERR, _("Unknown device type %s!"), type); return false; } } else { if(strstr(device, "tap")) device_type = DEVICE_TYPE_TAP; } switch(device_type) { default: device_type = DEVICE_TYPE_TUN; case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD { const int zero = 0; if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { logger(LOG_ERR, _("System call `%s' failed: %s"), "ioctl", strerror(errno)); return false; } } #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { const int mode = IFF_BROADCAST | IFF_MULTICAST; ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); } #endif device_info = _("Generic BSD tun device"); break; case DEVICE_TYPE_TUNIFHEAD: #ifdef TUNSIFHEAD { const int one = 1; if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { logger(LOG_ERR, _("System call `%s' failed: %s"), "ioctl", strerror(errno)); return false; } } #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { const int mode = IFF_BROADCAST | IFF_MULTICAST; ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); } #endif device_info = _("Generic BSD tun device"); break; case DEVICE_TYPE_TAP: if(routing_mode == RMODE_ROUTER) overwrite_mac = true; device_info = _("Generic BSD tap device"); break; } logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); switch(device_type) { case DEVICE_TYPE_TUN: if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } switch(packet->data[14] >> 4) { case 4: packet->data[12] = 0x08; packet->data[13] = 0x00; break; case 6: packet->data[12] = 0x86; packet->data[13] = 0xDD; break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _ ("Unknown IP version %d while reading packet from %s %s"), packet->data[14] >> 4, device_info, device); return false; } packet->len = lenin + 14; break; case DEVICE_TYPE_TUNIFHEAD: { u_int32_t type; struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, MTU - 14}}; if((lenin = readv(device_fd, vector, 2)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } switch (ntohl(type)) { case AF_INET: packet->data[12] = 0x08; packet->data[13] = 0x00; break; case AF_INET6: packet->data[12] = 0x86; packet->data[13] = 0xDD; break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _ ("Unknown address family %x while reading packet from %s %s"), ntohl(type), device_info, device); return false; } packet->len = lenin + 10; break; } case DEVICE_TYPE_TAP: if((lenin = read(device_fd, packet->data, MTU)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; break; default: return false; } device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TUNIFHEAD: { u_int32_t type; struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, MTU - 14}}; int af; af = (packet->data[12] << 8) + packet->data[13]; switch (af) { case 0x0800: type = htonl(AF_INET); break; case 0x86DD: type = htonl(AF_INET6); break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _("Unknown address family %x while writing packet to %s %s"), af, device_info, device); return false; } if(writev(device_fd, vector, 2) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; } case DEVICE_TYPE_TAP: if(write(device_fd, packet->data, packet->len) < 0) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; default: return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/cygwin/0000755000000000000000000000000013011103357012446 500000000000000gvpe-3.0/src/tincd/cygwin/device.c0000644000000000000000000001516411524347501014010 00000000000000/* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2004 Ivo Timmermans , 2002-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.2 2005-03-17 23:59:37 pcg Exp $ */ #include #include #include "mingw/common.h" int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; char *device = NULL; char *iface = NULL; char *device_info = NULL; static int device_total_in = 0; static int device_total_out = 0; static pid_t reader_pid; static int sp[2]; bool setup_device(void) { HKEY key, key2; int i, err; char regpath[1024]; char adapterid[1024]; char adaptername[1024]; char tapname[1024]; char gelukt = 0; long len; bool found = false; cp(); get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { logger(LOG_ERR, _("Unable to read registry: %s"), winerror(GetLastError())); return false; } for (i = 0; ; i++) { len = sizeof(adapterid); if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) break; /* Find out more about this adapter */ snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); if(err) continue; if(device) { if(!strcmp(device, adapterid)) { found = true; break; } else continue; } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; } else continue; } snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle != INVALID_HANDLE_VALUE) { CloseHandle(device_handle); found = true; break; } } RegCloseKey(key); if(!found) { logger(LOG_ERR, _("No Windows tap device found!")); return false; } if(!device) device = xstrdup(adapterid); if(!iface) iface = xstrdup(adaptername); snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); /* Now we are going to open this device twice: once for reading and once for writing. We do this because apparently it isn't possible to check for activity in the select() loop. Furthermore I don't really know how to do it the "Windows" way. */ if(socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, sp)) { logger(LOG_DEBUG, _("System call `%s' failed: %s"), "socketpair", strerror(errno)); return false; } /* The parent opens the tap device for writing. */ device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); if(device_handle == INVALID_HANDLE_VALUE) { logger(LOG_ERR, _("Could not open Windows tap device %s (%s) for writing: %s"), device, iface, winerror(GetLastError())); return false; } device_fd = sp[0]; /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { logger(LOG_ERR, _("Could not get MAC address from Windows tap device %s (%s): %s"), device, iface, winerror(GetLastError())); return false; } if(routing_mode == RMODE_ROUTER) { overwrite_mac = 1; } /* Now we start the child */ reader_pid = fork(); if(reader_pid == -1) { logger(LOG_DEBUG, _("System call `%s' failed: %s"), "fork", strerror(errno)); return false; } if(!reader_pid) { /* The child opens the tap device for reading, blocking. It passes everything it reads to the socket. */ char buf[MTU]; long lenin; CloseHandle(device_handle); device_handle = CreateFile(tapname, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { logger(LOG_ERR, _("Could not open Windows tap device %s (%s) for reading: %s"), device, iface, winerror(GetLastError())); buf[0] = 0; write(sp[1], buf, 1); exit(1); } logger(LOG_DEBUG, _("Tap reader forked and running.")); /* Notify success */ buf[0] = 1; write(sp[1], buf, 1); /* Pass packets */ for(;;) { ReadFile(device_handle, buf, MTU, &lenin, NULL); write(sp[1], buf, lenin); } } read(device_fd, &gelukt, 1); if(gelukt != 1) { logger(LOG_DEBUG, _("Tap reader failed!")); return false; } device_info = _("Windows tap device"); logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info); return true; } void close_device(void) { cp(); close(sp[0]); close(sp[1]); CloseHandle(device_handle); kill(reader_pid, SIGKILL); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(sp[0], packet->data, MTU)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { long lenout; cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(!WriteFile (device_handle, packet->data, packet->len, &lenout, NULL)) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, winerror(GetLastError())); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/darwin/0000755000000000000000000000000013011103357012432 500000000000000gvpe-3.0/src/tincd/darwin/device.c0000644000000000000000000000541111524347501013766 00000000000000/* device.c -- Interaction with MacOS/X tun device Copyright (C) 2001-2003 Ivo Timmermans , 2001-2003 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2003-10-14 03:22:09 pcg Exp $ */ #define DEFAULT_DEVICE "/dev/tun0" int device_fd = -1; char *device; char *iface; char *device_info; int device_total_in = 0; int device_total_out = 0; bool setup_device(void) { cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } device_info = _("MacOS/X tun device"); logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->data[12] = 0x08; packet->data[13] = 0x00; packet->len = lenin + 14; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/freebsd/0000755000000000000000000000000013011103357012560 500000000000000gvpe-3.0/src/tincd/freebsd/device.c0000644000000000000000000000527311524347501014122 00000000000000/* device.c -- Interaction with FreeBSD tap device Copyright (C) 2001-2003 Ivo Timmermans , 2001-2003 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2003-10-14 03:22:09 pcg Exp $ */ #define DEFAULT_DEVICE "/dev/tap0" int device_fd = -1; char *device; char *iface; char *device_info; int device_total_in = 0; int device_total_out = 0; bool setup_device(void) { cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } device_info = _("FreeBSD tap device"); logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(device_fd, packet->data, MTU)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(device_fd, packet->data, packet->len) < 0) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/linux/0000755000000000000000000000000013011103357012305 500000000000000gvpe-3.0/src/tincd/linux/device.c0000644000000000000000000001237411524347501013647 00000000000000/* device.c -- Interaction with Linux ethertap and tun/tap device Copyright (C) 2001-2004 Ivo Timmermans , 2001-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.2 2005-03-17 23:59:38 pcg Exp $ */ #ifdef HAVE_TUNTAP #ifdef LINUX_IF_TUN_H #include LINUX_IF_TUN_H #else #include #endif #define DEFAULT_DEVICE "/dev/net/tun" #else #define DEFAULT_DEVICE "/dev/tap0" #endif typedef enum device_type_t { DEVICE_TYPE_ETHERTAP, DEVICE_TYPE_TUN, DEVICE_TYPE_TAP, } device_type_t; int device_fd = -1; static device_type_t device_type; char *device; char *iface; char ifrname[IFNAMSIZ]; char *device_info; static int device_total_in = 0; static int device_total_out = 0; bool setup_device(void) { struct ifreq ifr; cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) #ifdef HAVE_TUNTAP iface = netname; #else iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; #endif device_fd = open(device, O_RDWR | O_NONBLOCK); if(device_fd < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } #ifdef HAVE_TUNTAP /* Ok now check if this is an old ethertap or a new tun/tap thingie */ memset(&ifr, 0, sizeof(ifr)); if(routing_mode == RMODE_ROUTER) { ifr.ifr_flags = IFF_TUN; device_type = DEVICE_TYPE_TUN; device_info = _("Linux tun/tap device (tun mode)"); } else { ifr.ifr_flags = IFF_TAP | IFF_NO_PI; device_type = DEVICE_TYPE_TAP; device_info = _("Linux tun/tap device (tap mode)"); } if(iface) strncpy(ifr.ifr_name, iface, IFNAMSIZ); if(!ioctl(device_fd, TUNSETIFF, &ifr)) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); iface = ifrname; } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) { logger(LOG_WARNING, _("Old ioctl() request was needed for %s"), device); strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); iface = ifrname; } else #endif { if(routing_mode == RMODE_ROUTER) overwrite_mac = true; device_info = _("Linux ethertap device"); device_type = DEVICE_TYPE_ETHERTAP; iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; } logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); switch(device_type) { case DEVICE_TYPE_TUN: lenin = read(device_fd, packet->data + 10, MTU - 10); if(lenin <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin + 10; break; case DEVICE_TYPE_TAP: lenin = read(device_fd, packet->data, MTU); if(lenin <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; break; case DEVICE_TYPE_ETHERTAP: lenin = read(device_fd, packet->data - 2, MTU + 2); if(lenin <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin - 2; break; } device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: packet->data[10] = packet->data[11] = 0; if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: if(write(device_fd, packet->data, packet->len) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_ETHERTAP: *(short int *)(packet->data - 2) = packet->len; if(write(device_fd, packet->data - 2, packet->len + 2) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } break; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/mingw/0000755000000000000000000000000013011103357012267 500000000000000gvpe-3.0/src/tincd/mingw/common.h0000644000000000000000000000624711524347501013671 00000000000000/* * TAP-Win32 -- A kernel driver to provide virtual tap device functionality * on Windows. Originally derived from the CIPE-Win32 * project by Damion K. Wilson, with extensive modifications by * James Yonan. * * All source code which derives from the CIPE-Win32 project is * Copyright (C) Damion K. Wilson, 2003, and is released under the * GPL version 2 (see below). * * All other source code is Copyright (C) James Yonan, 2003-2004, * and is released under the GPL version 2 (see below). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //=============================================== // This file is included both by OpenVPN and // the TAP-Win32 driver and contains definitions // common to both. //=============================================== //============= // TAP IOCTLs //============= #define TAP_CONTROL_CODE(request,method) \ CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) #define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) #define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) #define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) //================= // Registry keys //================= #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" #define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" //====================== // Filesystem prefixes //====================== #define USERMODEDEVICEDIR "\\\\.\\Global\\" #define SYSDEVICEDIR "\\Device\\" #define USERDEVICEDIR "\\DosDevices\\Global\\" #define TAPSUFFIX ".tap" //========================================================= // TAP_COMPONENT_ID -- This string defines the TAP driver // type -- different component IDs can reside in the system // simultaneously. //========================================================= #define TAP_COMPONENT_ID "tap0801" gvpe-3.0/src/tincd/mingw/device.c0000644000000000000000000002021511524347501013622 00000000000000/* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2004 Ivo Timmermans , 2002-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.2 2005-03-17 23:59:38 pcg Exp $ */ #include "system.h" #include #include #include "tincd/mingw/common.h" int device_fd = 0; static HANDLE device_handle = INVALID_HANDLE_VALUE; char *device = NULL; char *iface = NULL; char *device_info = NULL; static int device_total_in = 0; static int device_total_out = 0; extern char *myport; DWORD WINAPI tapreader(void *bla) { int sock, err, status; struct addrinfo *ai; struct addrinfo hint = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = 0, }; char buf[MTU]; long len; OVERLAPPED overlapped; /* Open a socket to the parent process */ err = getaddrinfo(NULL, myport, &hint, &ai); if(err || !ai) { logger(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo", gai_strerror(errno)); return -1; } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); freeaddrinfo(ai); if(sock < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "socket", strerror(errno)); return -1; } if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { logger(LOG_ERR, _("System call `%s' failed: %s"), "connect", strerror(errno)); return -1; } logger(LOG_DEBUG, _("Tap reader running")); /* Read from tap device and send to parent */ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); for(;;) { overlapped.Offset = 0; overlapped.OffsetHigh = 0; ResetEvent(overlapped.hEvent); status = ReadFile(device_handle, buf, sizeof(buf), &len, &overlapped); if(!status) { if(GetLastError() == ERROR_IO_PENDING) { WaitForSingleObject(overlapped.hEvent, INFINITE); if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE)) continue; } else { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return -1; } } if(send(sock, buf, len, 0) <= 0) return -1; } } bool setup_device(void) { HKEY key, key2; int i; char regpath[1024]; char adapterid[1024]; char adaptername[1024]; char tapname[1024]; long len; unsigned long status; bool found = false; int sock, err; HANDLE thread; struct addrinfo *ai; struct addrinfo hint = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = 0, }; cp(); get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { logger(LOG_ERR, _("Unable to read registry: %s"), winerror(GetLastError())); return false; } for (i = 0; ; i++) { len = sizeof(adapterid); if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) break; /* Find out more about this adapter */ snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); if(err) continue; if(device) { if(!strcmp(device, adapterid)) { found = true; break; } else continue; } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; } else continue; } snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); if(device_handle != INVALID_HANDLE_VALUE) { found = true; break; } } RegCloseKey(key); if(!found) { logger(LOG_ERR, _("No Windows tap device found!")); return false; } if(!device) device = xstrdup(adapterid); if(!iface) iface = xstrdup(adaptername); /* Try to open the corresponding tap device */ if(device_handle == INVALID_HANDLE_VALUE) { snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); } if(device_handle == INVALID_HANDLE_VALUE) { logger(LOG_ERR, _("%s (%s) is not a usable Windows tap device: %s"), device, iface, winerror(GetLastError())); return false; } /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { logger(LOG_ERR, _("Could not get MAC address from Windows tap device %s (%s): %s"), device, iface, winerror(GetLastError())); return false; } if(routing_mode == RMODE_ROUTER) { overwrite_mac = 1; } /* Create a listening socket */ err = getaddrinfo(NULL, myport, &hint, &ai); if(err || !ai) { logger(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo", gai_strerror(errno)); return false; } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(sock < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "socket", strerror(errno)); return false; } if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { logger(LOG_ERR, _("System call `%s' failed: %s"), "bind", strerror(errno)); return false; } freeaddrinfo(ai); if(listen(sock, 1)) { logger(LOG_ERR, _("System call `%s' failed: %s"), "listen", strerror(errno)); return false; } /* Start the tap reader */ thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); if(!thread) { logger(LOG_ERR, _("System call `%s' failed: %s"), "CreateThread", winerror(GetLastError())); return false; } /* Wait for the tap reader to connect back to us */ if((device_fd = accept(sock, NULL, 0)) == -1) { logger(LOG_ERR, _("System call `%s' failed: %s"), "accept", strerror(errno)); return false; } closesocket(sock); /* Set media status for newer TAP-Win32 devices */ status = true; DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); device_info = _("Windows tap device"); logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info); return true; } void close_device(void) { cp(); CloseHandle(device_handle); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { long lenout; OVERLAPPED overlapped = {0}; cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(!WriteFile(device_handle, packet->data, packet->len, &lenout, &overlapped)) { logger(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, winerror(GetLastError())); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/netbsd/0000755000000000000000000000000013011103357012425 500000000000000gvpe-3.0/src/tincd/netbsd/device.c0000644000000000000000000000547411524347501013772 00000000000000/* device.c -- Interaction with NetBSD tun device Copyright (C) 2001-2003 Ivo Timmermans , 2001-2003 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2003-10-14 03:22:09 pcg Exp $ */ #define DEFAULT_DEVICE "/dev/tun0" #define DEVICE_TYPE_ETHERTAP 0 #define DEVICE_TYPE_TUNTAP 1 int device_fd = -1; char *device; char *iface; char *device_info; int device_total_in = 0; int device_total_out = 0; bool setup_device(void) { cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } device_info = _("NetBSD tun device"); logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->data[12] = 0x08; packet->data[13] = 0x00; packet->len = lenin + 14; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/openbsd/0000755000000000000000000000000013011103357012600 500000000000000gvpe-3.0/src/tincd/openbsd/device.c0000644000000000000000000000745611524347501014147 00000000000000/* device.c -- Interaction with OpenBSD tun device Copyright (C) 2001-2003 Ivo Timmermans , 2001-2003 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2003-10-14 03:22:09 pcg Exp $ */ #include #define DEFAULT_DEVICE "/dev/tun0" #define DEVICE_TYPE_ETHERTAP 0 #define DEVICE_TYPE_TUNTAP 1 int device_fd = -1; char *device; char *iface; char *device_info; int device_total_in = 0; int device_total_out = 0; bool setup_device(void) { cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = rindex(device, '/') ? rindex(device, '/') + 1 : device; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } device_info = _("OpenBSD tun device"); logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; u_int32_t type; struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, MTU - 14}}; cp(); if((lenin = readv(device_fd, vector, 2)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } switch (ntohl(type)) { case AF_INET: packet->data[12] = 0x8; packet->data[13] = 0x0; break; case AF_INET6: packet->data[12] = 0x86; packet->data[13] = 0xDD; break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _ ("Unknown address family %d while reading packet from %s %s"), ntohl(type), device_info, device); return false; } packet->len = lenin + 10; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { u_int32_t type; struct iovec vector[2]; int af; cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); af = (packet->data[12] << 8) + packet->data[13]; switch (af) { case 0x800: type = htonl(AF_INET); break; case 0x86DD: type = htonl(AF_INET6); break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _("Unknown address family %d while writing packet to %s %s"), af, device_info, device); return false; } vector[0].iov_base = &type; vector[0].iov_len = sizeof(type); vector[1].iov_base = packet->data + 14; vector[1].iov_len = packet->len - 14; if(writev(device_fd, vector, 2) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/raw_socket/0000755000000000000000000000000013011103357013307 500000000000000gvpe-3.0/src/tincd/raw_socket/device.c0000644000000000000000000000641611524347501014651 00000000000000/* device.c -- raw socket Copyright (C) 2002-2004 Ivo Timmermans , 2002-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.2 2005-03-17 23:59:38 pcg Exp $ */ #include #include int device_fd = -1; char *device; char *iface; char ifrname[IFNAMSIZ]; char *device_info; static int device_total_in = 0; static int device_total_out = 0; bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; cp(); if(!get_config_string (lookup_config(config_tree, "Interface"), &iface)) iface = "eth0"; if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = iface; device_info = _("raw socket"); if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device_info, strerror(errno)); return false; } memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); logger(LOG_ERR, _("Can't find interface %s: %s"), iface, strerror(errno)); return false; } memset(&sa, '0', sizeof(sa)); sa.sll_family = AF_PACKET; sa.sll_protocol = htons(ETH_P_ALL); sa.sll_ifindex = ifr.ifr_ifindex; if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof(sa))) { logger(LOG_ERR, _("Could not bind %s to %s: %s"), device, iface, strerror(errno)); return false; } logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(device_fd, packet->data, MTU)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } packet->len = lenin; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(device_fd, packet->data, packet->len) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/solaris/0000755000000000000000000000000013011103357012622 500000000000000gvpe-3.0/src/tincd/solaris/device.c0000644000000000000000000001035211524347501014156 00000000000000/* device.c -- Interaction with Solaris tun device Copyright (C) 2001-2004 Ivo Timmermans , 2001-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.2 2005-03-17 23:59:38 pcg Exp $ */ #include "system.h" #include #include #include #define DEFAULT_DEVICE "/dev/tun" int device_fd = -1; char *device = NULL; char *iface = NULL; char *device_info = NULL; static int device_total_in = 0; static int device_total_out = 0; bool setup_device(void) { int ip_fd = -1, if_fd = -1; int ppa; char *ptr; cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = DEFAULT_DEVICE; if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); return false; } ppa = 0; ptr = device; while(*ptr && !isdigit((int) *ptr)) ptr++; ppa = atoi(ptr); if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { logger(LOG_ERR, _("Could not open /dev/ip: %s"), strerror(errno)); return false; } /* Assign a new PPA and get its unit number. */ if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) { logger(LOG_ERR, _("Can't assign new interface: %s"), strerror(errno)); return false; } if((if_fd = open(device, O_RDWR, 0)) < 0) { logger(LOG_ERR, _("Could not open %s twice: %s"), device, strerror(errno)); return false; } if(ioctl(if_fd, I_PUSH, "ip") < 0) { logger(LOG_ERR, _("Can't push IP module: %s"), strerror(errno)); return false; } /* Assign ppa according to the unit number returned by tun device */ if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) { logger(LOG_ERR, _("Can't set PPA %d: %s"), ppa, strerror(errno)); return false; } if(ioctl(ip_fd, I_LINK, if_fd) < 0) { logger(LOG_ERR, _("Can't link TUN device to IP: %s"), strerror(errno)); return false; } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) asprintf(&iface, "tun%d", ppa); device_info = _("Solaris tun device"); logger(LOG_INFO, _("%s is a %s"), device, device_info); return true; } void close_device(void) { cp(); close(device_fd); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); return false; } switch(packet->data[14] >> 4) { case 4: packet->data[12] = 0x08; packet->data[13] = 0x00; break; case 6: packet->data[12] = 0x86; packet->data[13] = 0xDD; break; default: ifdebug(TRAFFIC) logger(LOG_ERR, _ ("Unknown IP version %d while reading packet from %s %s"), packet->data[14] >> 4, device_info, device); return false; } packet->len = lenin + 14; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } bool write_packet(vpn_packet_t *packet) { cp(); ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/uml_socket/0000755000000000000000000000000013011103357013313 500000000000000gvpe-3.0/src/tincd/uml_socket/device.c0000644000000000000000000001564411524347501014660 00000000000000/* device.c -- UML network socket Copyright (C) 2002-2004 Ivo Timmermans , 2002-2004 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: device.c,v 1.1 2005-03-17 23:59:38 pcg Exp $ */ #include #include #include int device_fd = -1; static int listen_fd = -1; static int request_fd = -1; static int data_fd = -1; static int write_fd = -1; static int state = 0; char *device; char *iface = NULL; char *device_info; bool running; static int device_total_in = 0; static int device_total_out = 0; enum request_type { REQ_NEW_CONTROL }; static struct request { uint32_t magic; uint32_t version; enum request_type type; struct sockaddr_un sock; } request; static struct sockaddr_un data_sun; bool setup_device(void) { struct sockaddr_un listen_sun; static const int one = 1; struct { char zero; int pid; int usecs; } name; struct timeval tv; cp(); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) return false; get_config_string(lookup_config(config_tree, "Interface"), &iface); device_info = _("UML network socket"); if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(LOG_ERR, _("Could not open write %s: %s"), device_info, strerror(errno)); running = false; return false; } setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); running = false; return false; } if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(LOG_ERR, _("Could not open data %s: %s"), device_info, strerror(errno)); running = false; return false; } setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); running = false; return false; } name.zero = 0; name.pid = getpid(); gettimeofday(&tv, NULL); name.usecs = tv.tv_usec; data_sun.sun_family = AF_UNIX; memcpy(&data_sun.sun_path, &name, sizeof name); if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { logger(LOG_ERR, _("Could not bind data %s: %s"), device_info, strerror(errno)); running = false; return false; } if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { logger(LOG_ERR, _("Could not open %s: %s"), device_info, strerror(errno)); return false; } setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); return false; } listen_sun.sun_family = AF_UNIX; strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path); if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) { logger(LOG_ERR, _("Could not bind %s to %s: %s"), device_info, device, strerror(errno)); return false; } if(listen(listen_fd, 1) < 0) { logger(LOG_ERR, _("Could not listen on %s %s: %s"), device_info, device, strerror(errno)); return false; } device_fd = listen_fd; state = 0; logger(LOG_INFO, _("%s is a %s"), device, device_info); if(routing_mode == RMODE_ROUTER) overwrite_mac = true; return true; } void close_device(void) { cp(); if(listen_fd >= 0) close(listen_fd); if(request_fd >= 0) close(request_fd); if(data_fd >= 0) close(data_fd); if(write_fd >= 0) close(write_fd); unlink(device); } bool read_packet(vpn_packet_t *packet) { int lenin; cp(); switch(state) { case 0: { struct sockaddr sa; socklen_t salen = sizeof sa; request_fd = accept(listen_fd, &sa, &salen); if(request_fd < 0) { logger(LOG_ERR, _("Could not accept connection to %s %s: %s"), device_info, device, strerror(errno)); return false; } if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); running = false; return false; } close(listen_fd); listen_fd = -1; device_fd = request_fd; state = 1; return false; } case 1: { if((lenin = read(request_fd, &request, sizeof request)) != sizeof request) { logger(LOG_ERR, _("Error while reading request from %s %s: %s"), device_info, device, strerror(errno)); running = false; return false; } if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { logger(LOG_ERR, _("Unknown magic %x, version %d, request type %d from %s %s"), request.magic, request.version, request.type, device_info, device); running = false; return false; } if(connect(write_fd, (sockaddr *)&request.sock, sizeof request.sock) < 0) { logger(LOG_ERR, _("Could not bind write %s: %s"), device_info, strerror(errno)); running = false; return false; } write(request_fd, &data_sun, sizeof data_sun); device_fd = data_fd; logger(LOG_INFO, _("Connection with UML established")); state = 2; return false; } case 2: { if((lenin = read(data_fd, packet->data, MTU)) <= 0) { logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); running = false; return false; } packet->len = lenin; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); return true; } } } bool write_packet(vpn_packet_t *packet) { cp(); if(state != 2) { ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Dropping packet of %d bytes to %s: not connected to UML yet"), packet->len, device_info); return false; } ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"), packet->len, device_info); if(write(write_fd, packet->data, packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); running = false; } return false; } device_total_out += packet->len; return true; } void dump_device_stats(void) { cp(); logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device); logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); } gvpe-3.0/src/tincd/apply0000754000000000000000000000004610002074751012142 00000000000000#!/bin/sh perl -i ./fixit */device.c gvpe-3.0/src/tincd/fixit0000754000000000000000000000020510002074751012135 00000000000000#!/usr/bin/perl while (<>) { if (/^#include \"(.*)"/) { warn "skipping local include $1"; } else { print; } } gvpe-3.0/src/Makefile.in0000644000000000000000000004406213011103322012030 00000000000000# Makefile.in generated by automake 1.7.9 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # 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@ #SUBDIRS = rohc 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 = : host_triplet = @host@ 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@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_TUNTAP = @HAVE_TUNTAP@ IFSUBTYPE = @IFSUBTYPE@ IFTYPE = @IFTYPE@ INCLUDES = -I$(top_builddir) -I$(top_srcdir)/lib -I$(top_srcdir)/libev @INCLUDES@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DAEMON = @LDFLAGS_DAEMON@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ @LIBINTL@ LINUX_IF_TUN_H = @LINUX_IF_TUN_H@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ POSUB = @POSUB@ RANLIB = @RANLIB@ ROHC_FALSE = @ROHC_FALSE@ ROHC_TRUE = @ROHC_TRUE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = $(datadir)/locale localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ sbin_PROGRAMS = gvpe bin_PROGRAMS = gvpectrl EXTRA_DIST = device-linux.C device-cygwin.C device-tincd.C device-darwin.C callback.pl \ tincd/apply tincd/fixit \ tincd/cygwin/device.c tincd/darwin/device.c tincd/freebsd/device.c \ tincd/linux/device.c tincd/mingw/common.h tincd/mingw/device.c tincd/netbsd/device.c \ tincd/openbsd/device.c tincd/raw_socket/device.c tincd/solaris/device.c \ tincd/uml_socket/device.c tincd/bsd/device.c \ ether_emu.C lzf/lzf_c.c lzf/lzf_d.c \ curve25519-donna.c curve25519-donna-c64.c @ROHC_FALSE@ROHCLIB = @ROHC_TRUE@ROHCLIB = rohc/librohc.a COMMON = global.h conf.h conf.C util.h util.C slog.h slog.C netcompat.h \ ev_cpp.h ev_cpp.C crypto.h crypto.C gvpe_SOURCES = gvpe.C vpn.h vpn.C vpn_tcp.C vpn_dns.C \ sockinfo.h sockinfo.C \ curve25519.h curve25519.C \ iv_gen.h iv_gen.C \ hkdf.h hkdf.C \ lzf/lzf.h lzf/lzfP.h \ connection.h connection.C callback.h device.h device.C \ $(COMMON) gvpe_LDADD = $(top_builddir)/lib/libgvpe.a $(ROHCLIB) gvpe_LDFLAGS = @LDFLAGS_DAEMON@ gvpectrl_SOURCES = gvpectrl.C $(COMMON) gvpectrl_LDADD = $(top_builddir)/lib/libgvpe.a DEFINES = -DPKGLIBDIR=$(pkglibdir) -DCONFDIR=\"$(sysconfdir)\" \ -DLOCALEDIR=\"$(localedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" \ -DIFTYPE_@IFTYPE@=1 -DIF_@IFSUBTYPE@=1 AM_CFLAGS = $(DEFINES) AM_CXXFLAGS = $(DEFINES) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = bin_PROGRAMS = gvpectrl$(EXEEXT) sbin_PROGRAMS = gvpe$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) am__objects_1 = conf.$(OBJEXT) util.$(OBJEXT) slog.$(OBJEXT) \ ev_cpp.$(OBJEXT) crypto.$(OBJEXT) am_gvpe_OBJECTS = gvpe.$(OBJEXT) vpn.$(OBJEXT) vpn_tcp.$(OBJEXT) \ vpn_dns.$(OBJEXT) sockinfo.$(OBJEXT) curve25519.$(OBJEXT) \ iv_gen.$(OBJEXT) hkdf.$(OBJEXT) connection.$(OBJEXT) \ device.$(OBJEXT) $(am__objects_1) gvpe_OBJECTS = $(am_gvpe_OBJECTS) @ROHC_TRUE@gvpe_DEPENDENCIES = $(top_builddir)/lib/libgvpe.a \ @ROHC_TRUE@ rohc/librohc.a @ROHC_FALSE@gvpe_DEPENDENCIES = $(top_builddir)/lib/libgvpe.a am_gvpectrl_OBJECTS = gvpectrl.$(OBJEXT) $(am__objects_1) gvpectrl_OBJECTS = $(am_gvpectrl_OBJECTS) gvpectrl_DEPENDENCIES = $(top_builddir)/lib/libgvpe.a gvpectrl_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/conf.Po ./$(DEPDIR)/connection.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/crypto.Po ./$(DEPDIR)/curve25519.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/device.Po ./$(DEPDIR)/ev_cpp.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/gvpe.Po ./$(DEPDIR)/gvpectrl.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/hkdf.Po ./$(DEPDIR)/iv_gen.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/slog.Po ./$(DEPDIR)/sockinfo.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/vpn.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/vpn_dns.Po ./$(DEPDIR)/vpn_tcp.Po CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(gvpe_SOURCES) $(gvpectrl_SOURCES) DIST_COMMON = $(srcdir)/Makefile.in Makefile.am SOURCES = $(gvpe_SOURCES) $(gvpectrl_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .C .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ rm -f $(DESTDIR)$(bindir)/$$f; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(sbindir) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \ else :; fi; \ done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ rm -f $(DESTDIR)$(sbindir)/$$f; \ done clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) gvpe$(EXEEXT): $(gvpe_OBJECTS) $(gvpe_DEPENDENCIES) @rm -f gvpe$(EXEEXT) $(CXXLINK) $(gvpe_LDFLAGS) $(gvpe_OBJECTS) $(gvpe_LDADD) $(LIBS) gvpectrl$(EXEEXT): $(gvpectrl_OBJECTS) $(gvpectrl_DEPENDENCIES) @rm -f gvpectrl$(EXEEXT) $(CXXLINK) $(gvpectrl_LDFLAGS) $(gvpectrl_OBJECTS) $(gvpectrl_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curve25519.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev_cpp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvpe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvpectrl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hkdf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iv_gen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpn_dns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpn_tcp.Po@am__quote@ .C.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCXX_TRUE@ fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< .C.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCXX_TRUE@ fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS 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: $(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 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/lzf $(distdir)/tincd $(distdir)/tincd/bsd $(distdir)/tincd/cygwin $(distdir)/tincd/darwin $(distdir)/tincd/freebsd $(distdir)/tincd/linux $(distdir)/tincd/mingw $(distdir)/tincd/netbsd $(distdir)/tincd/openbsd $(distdir)/tincd/raw_socket $(distdir)/tincd/solaris $(distdir)/tincd/uml_socket @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"; \ $(mkinstalldirs) "$(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 $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) 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: 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-binPROGRAMS clean-generic clean-sbinPROGRAMS \ 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: info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS install-sbinPROGRAMS 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-binPROGRAMS uninstall-info-am \ uninstall-sbinPROGRAMS .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-sbinPROGRAMS ctags distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-exec install-exec-am \ install-info install-info-am install-man install-sbinPROGRAMS \ 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-binPROGRAMS \ uninstall-info-am uninstall-sbinPROGRAMS dist-hook: rm -f `find . -type l` # 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: gvpe-3.0/src/Makefile.am0000644000000000000000000000325712735177540012051 00000000000000## Produce this file with automake to get Makefile.in #SUBDIRS = rohc sbin_PROGRAMS = gvpe bin_PROGRAMS = gvpectrl EXTRA_DIST = device-linux.C device-cygwin.C device-tincd.C device-darwin.C callback.pl \ tincd/apply tincd/fixit \ tincd/cygwin/device.c tincd/darwin/device.c tincd/freebsd/device.c \ tincd/linux/device.c tincd/mingw/common.h tincd/mingw/device.c tincd/netbsd/device.c \ tincd/openbsd/device.c tincd/raw_socket/device.c tincd/solaris/device.c \ tincd/uml_socket/device.c tincd/bsd/device.c \ ether_emu.C lzf/lzf_c.c lzf/lzf_d.c \ curve25519-donna.c curve25519-donna-c64.c INCLUDES = -I$(top_builddir) -I$(top_srcdir)/lib -I$(top_srcdir)/libev @INCLUDES@ LIBS = @LIBS@ @LIBINTL@ if ROHC ROHCLIB = rohc/librohc.a else ROHCLIB = endif COMMON = global.h conf.h conf.C util.h util.C slog.h slog.C netcompat.h \ ev_cpp.h ev_cpp.C crypto.h crypto.C gvpe_SOURCES = gvpe.C vpn.h vpn.C vpn_tcp.C vpn_dns.C \ sockinfo.h sockinfo.C \ curve25519.h curve25519.C \ iv_gen.h iv_gen.C \ hkdf.h hkdf.C \ lzf/lzf.h lzf/lzfP.h \ connection.h connection.C callback.h device.h device.C \ $(COMMON) gvpe_LDADD = $(top_builddir)/lib/libgvpe.a $(ROHCLIB) gvpe_LDFLAGS = @LDFLAGS_DAEMON@ gvpectrl_SOURCES = gvpectrl.C $(COMMON) gvpectrl_LDADD = $(top_builddir)/lib/libgvpe.a localedir = $(datadir)/locale DEFINES = -DPKGLIBDIR=$(pkglibdir) -DCONFDIR=\"$(sysconfdir)\" \ -DLOCALEDIR=\"$(localedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" \ -DIFTYPE_@IFTYPE@=1 -DIF_@IFSUBTYPE@=1 AM_CFLAGS = $(DEFINES) AM_CXXFLAGS = $(DEFINES) dist-hook: rm -f `find . -type l` gvpe-3.0/src/gvpe.C0000644000000000000000000002206712615056110011044 00000000000000/* gvpe.C -- the main file for gvpe Copyright (C) 1998-2002 Ivo Timmermans 2000-2002 Guus Sliepen 2003-2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_SYS_MMAN_H # include #endif #include #include #include "gettext.h" #include "pidfile.h" #include "conf.h" #include "slog.h" #include "util.h" #include "vpn.h" #include "ev_cpp.h" #include "hkdf.h" static loglevel llevel = L_NONE; /* If nonzero, display usage information and exit. */ static int show_help; /* If nonzero, print the version on standard output and exit. */ static int show_version; /* If nonzero, disable swapping for this process. */ static int do_mlock = 0; /* If zero, don't detach from the terminal. */ static int do_detach = 1; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, {"help", no_argument, &show_help, 1}, {"version", no_argument, &show_version, 1}, {"no-detach", no_argument, &do_detach, 0}, {"log-level", required_argument, NULL, 'l'}, {"mlock", no_argument, &do_mlock, 1}, {NULL, 0, NULL, 0} }; static void usage (int status) { if (status != 0) fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ()); else { printf (_("Usage: %s [option]... NODENAME\n\n"), get_identity ()); printf (_ (" -c, --config=DIR Read configuration options from DIR.\n" " -D, --no-detach Don't fork and detach.\n" " -l, --log-level=LEVEL Set logging level (info, notice, warn are common).\n" " -L, --mlock Lock gvpe into main memory.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n\n")); printf (_("Report bugs to .\n")); } exit (status); } static void parse_options (int argc, char **argv, char **envp) { int r; int option_index = 0; while ((r = getopt_long (argc, argv, "c:DLl:", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; case 'c': /* config file */ confbase = strdup (optarg); break; case 'D': /* no detach */ do_detach = 0; break; case 'L': /* lock into memory */ do_mlock = 1; break; case 'l': /* inc debug level */ { llevel = string_to_loglevel (optarg); if (llevel == L_NONE) slog (L_WARN, "'%s': %s", optarg, UNKNOWN_LOGLEVEL); } break; case '?': usage (1); default: break; } } } // close network connections, and terminate neatly static void cleanup_and_exit (int c) { network.shutdown_all (); if (conf.pidfilename) remove_pid (conf.pidfilename); slog (L_INFO, _("terminating with exit code %d"), c); exit (c); } // signal handlers static RETSIGTYPE sigterm_handler (int a) { network.events |= vpn::EVENT_SHUTDOWN; network.event.start (); } static RETSIGTYPE sighup_handler (int a) { network.events |= vpn::EVENT_RECONNECT; network.event.start (); } static RETSIGTYPE sigusr1_handler (int a) { network.dump_status (); } static RETSIGTYPE sigusr2_handler (int a) { } static void setup_signals (void) { struct sigaction act; sigfillset (&act.sa_mask); act.sa_flags = 0; act.sa_handler = sighup_handler; sigaction (SIGHUP , &act, NULL); act.sa_handler = sigusr1_handler; sigaction (SIGUSR1, &act, NULL); act.sa_handler = sigusr2_handler; sigaction (SIGUSR2, &act, NULL); act.sa_handler = SIG_IGN; sigaction (SIGPIPE, &act, NULL); act.sa_flags = SA_RESETHAND; act.sa_handler = sigterm_handler; sigaction (SIGINT , &act, NULL); act.sa_handler = sigterm_handler; sigaction (SIGTERM, &act, NULL); } static int rand_fd; // antique C++ requires external linkage :/ void reseed_rng (ev::timer &w, int revents) { char buf [SEED_SIZE]; int n = read (rand_fd, buf, sizeof (buf)); if (n > 0) RAND_seed (buf, n); } static void setup_rng (void) { if (!*conf.seed_dev) return; #ifndef O_BINARY # define O_BINARY 0 #endif #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif rand_fd = open (conf.seed_dev, O_RDONLY | O_NONBLOCK | O_BINARY); if (rand_fd < 0) { slog (L_ERR, _("unable to open seed device '%s': %s, exiting."), conf.seed_dev, strerror (errno)); exit (EXIT_FAILURE); } static ev::timer reseed_timer; if (conf.reseed) { reseed_timer.set (); reseed_timer.set (conf.reseed, conf.reseed); reseed_timer.start (EV_DEFAULT); } reseed_rng (reseed_timer, 0); } int main (int argc, char **argv, char **envp) { ERR_load_crypto_strings (); // we have the RAM // m,ake sure openssl agrees with us on the important bits require (EVP_MD_size (MAC_DIGEST ()) == HASH_SIZE (MAC_DIGEST )); require (EVP_MD_size (AUTH_DIGEST ()) == HASH_SIZE (AUTH_DIGEST)); require (EVP_CIPHER_key_length (CIPHER ()) == KEY_SIZE (CIPHER )); require (EVP_CIPHER_block_size (CIPHER ()) == BLOCK_SIZE (CIPHER )); require (EVP_CIPHER_iv_length (CIPHER ()) == IV_SIZE (CIPHER )); require (EVP_CIPHER_mode (CIPHER ()) == EVP_CIPH_CTR_MODE); curve25519_verify (); hkdf::verify (); set_loglevel (L_INFO); set_identity (argv[0]); log_to (LOGTO_SYSLOG | LOGTO_STDERR); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); parse_options (argc, argv, envp); argc -= optind; argv += optind; if (show_version) { printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (), VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); printf (_ ("Copyright (C) 2003-2011 Marc Lehmann and others.\n" "See the AUTHORS file for a complete list.\n\n" "GVPE comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" "see the file COPYING for details.\n")); return 0; } if (show_help) usage (0); log_to (LOGTO_SYSLOG | LOGTO_STDERR); /* Lock all pages into memory if requested */ #if HAVE_MLOCKALL && HAVE_SYS_MMAN_H && _POSIX_MEMLOCK if (do_mlock) if (mlockall (MCL_CURRENT | MCL_FUTURE)) slog (L_ERR, _("system call `%s' failed: %s"), "mlockall", strerror (errno)); #endif if (argc >= 1) { thisnode = *argv++; argc--; } if (!ev_default_loop (0)) { slog (L_ERR, _("unable to initialise the event loop (bad $LIBEV_METHODS?)")); exit (EXIT_FAILURE); } { configuration_parser (conf, true, argc, argv); } set_loglevel (llevel != L_NONE ? llevel : conf.llevel); setup_rng (); if (!THISNODE) { slog (L_ERR, _("current node not set, or node '%s' not found in configfile, specify the nodename when starting gvpe."), thisnode ? thisnode : ""); exit (EXIT_FAILURE); } if (detach (do_detach)) exit (EXIT_SUCCESS); setup_signals (); if (!network.setup ()) if (network.drop_privileges ()) { ev_run (EV_DEFAULT_ 0); cleanup_and_exit (EXIT_FAILURE); } slog (L_CRIT, _("unrecoverable error while setting up network, exiting.")); cleanup_and_exit (EXIT_FAILURE); } gvpe-3.0/src/vpn.h0000644000000000000000000000715712615056110010756 00000000000000/* vpn.h -- header for vpn.C Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_VPN_H__ #define GVPE_VPN_H__ #include "global.h" #include "conf.h" #include "device.h" #include "connection.h" struct vpn { int udpv4_fd , tcpv4_fd, ipv4_fd , icmpv4_fd , dnsv4_fd; int udpv4_tos, ipv4_tos, icmpv4_tos, dnsv4_tos; int events; enum { EVENT_RECONNECT = 1, EVENT_SHUTDOWN = 2, }; void event_cb (ev::timer &w, int revents); ev::timer event; tap_device *tap; typedef vector conns_vector; conns_vector conns; // called when any conenction has been established void connection_established (connection *c); // return true if src can connect directly to dst bool can_direct (conf_node *src, conf_node *dst) const; connection *find_router_for (const connection *dst); void reconnect_all (); void shutdown_all (); void tap_ev (ev::io &w, int revents); ev::io tap_ev_watcher; void inject_data_packet (tap_packet *pkt, int dst); void send_connect_request (connection *c); void recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi); bool send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos = 0); #if ENABLE_TCP void tcpv4_ev (ev::io &w, int revents); ev::io tcpv4_ev_watcher; bool send_tcpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos); #endif #if ENABLE_ICMP void icmpv4_ev (ev::io &w, int revents); ev::io icmpv4_ev_watcher; bool send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos); #endif #if ENABLE_DNS vector dns_sndpq; sockinfo dns_forwarder; void dnsv4_ev (ev::io &w, int revents); ev::io dnsv4_ev_watcher; void dnsv4_server (struct dns_packet &pkt); void dnsv4_client (struct dns_packet &pkt); bool send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos); #endif void udpv4_ev (ev::io &w, int revents); ev::io udpv4_ev_watcher; bool send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos); void ipv4_ev (ev::io &w, int revents); ev::io ipv4_ev_watcher; bool send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos); vpn (); ~vpn (); int setup_socket (u8 prot, int family, int type, int proto); int setup (); bool drop_privileges (); void dump_status (); void script_init_env (); const char *script_if_init (); const char *script_if_up (); }; extern vpn network; // THE vpn #endif gvpe-3.0/src/vpn.C0000644000000000000000000006041412615056110010704 00000000000000/* vpn.C -- handle the protocol, encryption, handshaking etc. Copyright (C) 2003-2008,2010,2011,2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netcompat.h" #include "pidfile.h" #include "connection.h" #include "util.h" #include "vpn.h" using namespace std; vpn network; // THE vpn (bad design...) ///////////////////////////////////////////////////////////////////////////// // hopefully temporary workaround for rare buffer full conditions // if it happens, usually instantly retrying or retrying ~5ms later // is good enough with current network technologies/kernels static ssize_t xsendto (int fd, const void *buf, size_t len, int flags, const struct sockaddr *sa, socklen_t salen) { ssize_t res; for (int retry = 0; retry <= 13; ++retry) // ~100ms { res = sendto (fd, buf, len, flags, sa, salen); if (res >= 0 || errno != ENOBUFS) break; struct timespec ts = { 0, 1000 * retry }; nanosleep (&ts, 0); } return res; } ///////////////////////////////////////////////////////////////////////////// static void inline set_tos (int fd, int &tos_prev, int tos) { #if defined(SOL_IP) && defined(IP_TOS) if (tos_prev == tos) return; tos_prev = tos; setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); #endif } void vpn::script_init_env () { // the tunnel device mtu should be the physical mtu - overhead // the tricky part is rounding to the cipher key blocksize int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion mtu -= mtu % BLOCK_SIZE (CIPHER); // round mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again char *env; asprintf (&env, "CONFBASE=%s", confbase); putenv (env); asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env); asprintf (&env, "IFTYPE=%s", IFTYPE); putenv (env); asprintf (&env, "IFSUBTYPE=%s", IFSUBTYPE); putenv (env); asprintf (&env, "MTU=%d", mtu); putenv (env); asprintf (&env, "NODES=%d", conns.size ()); putenv (env); asprintf (&env, "NODEID=%d", THISNODE->id); putenv (env); conns [THISNODE->id - 1]->script_init_env (""); for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) { char ext[16]; snprintf (ext, 16, "_%d", (*c)->conf->id); (*c)->script_init_env (ext); } } inline const char * vpn::script_if_init () { script_init_env (); return tap->if_up (); } inline const char * vpn::script_if_up () { script_init_env (); return conf.config_filename (::conf.script_if_up, "if-up"); } int vpn::setup_socket (u8 prot, int family, int type, int proto) { int fd = socket (family, type, proto); if (fd < 0) { slog (L_ERR, _("unable to create %s socket: %s."), strprotocol (prot), strerror (errno)); return fd; } fcntl (fd, F_SETFL, O_NONBLOCK); fcntl (fd, F_SETFD, FD_CLOEXEC); #ifdef SO_MARK if (::conf.nfmark) if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark)) slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno)); #endif return fd; } int vpn::setup () { int success = 0; ipv4_tos = -1; ipv4_fd = -1; if (THISNODE->protocols & PROT_IPv4 && ::conf.ip_proto) { ipv4_fd = setup_socket (PROT_IPv4, PF_INET, SOCK_RAW, ::conf.ip_proto); if (ipv4_fd < 0) return -1; #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) // this I really consider a linux bug. I am neither connected // nor do I fragment myself. Linux still sets DF and doesn't // fragment for me sometimes. { int oval = IP_PMTUDISC_DONT; setsockopt (ipv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); } #endif sockinfo si (THISNODE, PROT_IPv4); if (bind (ipv4_fd, si.sav4 (), si.salenv4 ())) { slog (L_ERR, _("can't bind ipv4 socket on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } ipv4_ev_watcher.start (ipv4_fd, EV_READ); ++success; } else THISNODE->protocols &= ~PROT_IPv4; udpv4_tos = -1; udpv4_fd = -1; if (THISNODE->protocols & PROT_UDPv4 && THISNODE->udp_port) { udpv4_fd = setup_socket (PROT_UDPv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (udpv4_fd < 0) return -1; // standard daemon practise... { int oval = 1; setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); } #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) // this I really consider a linux bug. I am neither connected // nor do I fragment myself. Linux still sets DF and doesn't // fragment for me sometimes. { int oval = IP_PMTUDISC_DONT; setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); } #endif sockinfo si (THISNODE, PROT_UDPv4); if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) { slog (L_ERR, _("can't bind udpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } udpv4_ev_watcher.start (udpv4_fd, EV_READ); ++success; } else THISNODE->protocols &= ~PROT_UDPv4; icmpv4_tos = -1; icmpv4_fd = -1; #if ENABLE_ICMP if (THISNODE->protocols & PROT_ICMPv4) { icmpv4_fd = setup_socket (PROT_ICMPv4, PF_INET, SOCK_RAW, IPPROTO_ICMP); if (icmpv4_fd < 0) return -1; #ifdef ICMP_FILTER { icmp_filter oval; oval.data = 0xffffffff; if (::conf.icmp_type < 32) oval.data &= ~(1 << ::conf.icmp_type); setsockopt (icmpv4_fd, SOL_RAW, ICMP_FILTER, &oval, sizeof oval); } #endif #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) // this I really consider a linux bug. I am neither connected // nor do I fragment myself. Linux still sets DF and doesn't // fragment for me sometimes. { int oval = IP_PMTUDISC_DONT; setsockopt (icmpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); } #endif sockinfo si (THISNODE, PROT_ICMPv4); if (bind (icmpv4_fd, si.sav4 (), si.salenv4 ())) { slog (L_ERR, _("can't bind icmpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } icmpv4_ev_watcher.start (icmpv4_fd, EV_READ); ++success; } #endif tcpv4_fd = -1; #if ENABLE_TCP if (THISNODE->protocols & PROT_TCPv4 && THISNODE->tcp_port) { tcpv4_fd = setup_socket (PROT_TCPv4, PF_INET, SOCK_STREAM, IPPROTO_TCP); if (tcpv4_fd < 0) return -1; // standard daemon practise... { int oval = 1; setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); } sockinfo si (THISNODE, PROT_TCPv4); if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ())) { slog (L_ERR, _("can't bind tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } if (listen (tcpv4_fd, 5)) { slog (L_ERR, _("can't listen tcpv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } tcpv4_ev_watcher.start (tcpv4_fd, EV_READ); ++success; } else THISNODE->protocols &= ~PROT_TCPv4; #endif dnsv4_tos = -1; dnsv4_fd = -1; #if ENABLE_DNS if (THISNODE->protocols & PROT_DNSv4) { dns_forwarder.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); dnsv4_fd = setup_socket (PROT_DNSv4, PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (dnsv4_fd < 0) return -1; # if defined(SOL_IP) && defined(IP_MTU_DISCOVER) // this I really consider a linux bug. I am neither connected // nor do I fragment myself. Linux still sets DF and doesn't // fragment for me sometimes. { int oval = IP_PMTUDISC_DONT; setsockopt (dnsv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); } # endif // standard daemon practise... { int oval = 1; setsockopt (dnsv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); } sockinfo si (THISNODE->dns_hostname, THISNODE->dns_hostname ? THISNODE->dns_port : 0, PROT_DNSv4); if (bind (dnsv4_fd, si.sav4 (), si.salenv4 ())) { slog (L_ERR, _("can't bind dnsv4 on %s: %s, exiting."), (const char *)si, strerror (errno)); return -1; } dnsv4_ev_watcher.start (dnsv4_fd, EV_READ); ++success; } #endif ///////////////////////////////////////////////////////////////////////////// if (!success) { slog (L_ERR, _("no protocols enabled.")); return -1; } reconnect_all (); ///////////////////////////////////////////////////////////////////////////// tap = new tap_device (); if (!tap) //D this, of course, never catches { slog (L_ERR, _("cannot create network interface '%s'."), conf.ifname); return -1; } fcntl (tap->fd, F_SETFD, FD_CLOEXEC); run_script_cb cb; cb.set (this); if (tap->if_up () && !run_script (cb, true)) { slog (L_ERR, _("interface initialization command '%s' failed."), tap->if_up ()); return -1; } cb.set (this); if (!run_script (cb, true)) { slog (L_ERR, _("if-up command execution failed.")); return -1; } tap_ev_watcher.start (tap->fd, EV_READ); return 0; } bool vpn::drop_privileges () { if (::conf.change_root) { if (!strcmp (::conf.change_root, "/")) { char dir [L_tmpnam]; if (!tmpnam (dir)) { slog (L_CRIT, _("unable to create anonymous root path.")); return false; } if (mkdir (dir, 0700)) { slog (L_CRIT, _("unable to create anonymous root directory.")); return false; } if (chdir (dir)) { slog (L_CRIT, _("unable to change to anonymous root directory.")); return false; } if (rmdir (dir)) slog (L_ERR, _("unable to remove anonymous root directory, continuing.")); } else { if (chdir (::conf.change_root)) { slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root); return false; } } if (chroot (".")) { slog (L_CRIT, _("unable to set new root directory.")); return false; } if (chdir ("/")) { slog (L_CRIT, _("unable to set cwd to new root directory.")); return false; } } if (::conf.change_gid) if (setgid (::conf.change_gid)) { slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid); return false; } if (::conf.change_uid) if (setuid (::conf.change_uid)) { slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid); return false; } return true; } bool vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { set_tos (ipv4_fd, ipv4_tos, tos); xsendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; } static u16 ipv4_checksum (u16 *data, unsigned int len) { // use 32 bit accumulator and fold back carry bits at the end u32 sum = 0; while (len > 1) { sum += *data++; len -= 2; } // odd byte left? if (len) sum += *(u8 *)data; // add back carry bits sum = (sum >> 16) + (sum & 0xffff); // lo += hi sum += (sum >> 16); // carry return ~sum; } #if ENABLE_ICMP bool vpn::send_icmpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { pkt->unshift_hdr (4); icmp_header *hdr = (icmp_header *)&((*pkt)[0]); hdr->type = ::conf.icmp_type; hdr->code = 255; hdr->checksum = 0; hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); set_tos (icmpv4_fd, icmpv4_tos, tos); xsendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; } #endif bool vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { set_tos (udpv4_fd, udpv4_tos, tos); xsendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); return true; } void vpn::inject_data_packet (tap_packet *pkt, int dst) { if (dst) { // unicast if (dst != THISNODE->id) conns[dst - 1]->inject_data_packet (pkt); } else { // broadcast, this is ugly, but due to the security policy // we have to connect to all hosts... for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) if ((*c)->conf != THISNODE) (*c)->inject_data_packet (pkt); } } void vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) { unsigned int src = pkt->src (); unsigned int dst = pkt->dst (); slog (L_NOISE, _("<typ (), pkt->src (), pkt->dst (), pkt->len); if (src == 0 || src > conns.size () || dst > conns.size () || pkt->typ () >= vpn_packet::PT_MAX) slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); else { connection *c = conns[src - 1]; if (dst == 0) slog (L_WARN, _("%s(%s): received broadcast (protocol violation)."), c->conf->nodename, (const char *)rsi); else if (dst != THISNODE->id) { if (THISNODE->routerprio) // the tos setting gets lost here. who cares. conns[dst - 1]->inject_vpn_packet (pkt); else slog (L_WARN, _("%s(%s): request to forward packet to %s, but we are no router (config mismatch?)."), c->conf->nodename, (const char *)rsi, conns[dst - 1]->conf->nodename); } else c->recv_vpn_packet (pkt, rsi); } } bool vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) { switch (si.prot) { case PROT_IPv4: return send_ipv4_packet (pkt, si, tos); case PROT_UDPv4: return send_udpv4_packet (pkt, si, tos); #if ENABLE_TCP case PROT_TCPv4: return send_tcpv4_packet (pkt, si, tos); #endif #if ENABLE_ICMP case PROT_ICMPv4: return send_icmpv4_packet (pkt, si, tos); #endif #if ENABLE_DNS case PROT_DNSv4: return send_dnsv4_packet (pkt, si, tos); #endif default: slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); } return false; } inline void vpn::ipv4_ev (ev::io &w, int revents) { if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; socklen_t sa_len = sizeof (sa); int len; len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); sockinfo si(sa, PROT_IPv4); if (len > 0) { pkt->len = len; // raw sockets deliver the ipv4 header, but don't expect it on sends pkt->skip_hdr (pkt->ipv4_hdr_len ()); recv_vpn_packet (pkt, si); } else { // probably ECONNRESET or somesuch slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno)); } delete pkt; } else { slog (L_ERR, _("FATAL: unknown revents %08x in socket, exiting.\n"), revents); exit (EXIT_FAILURE); } } #if ENABLE_ICMP inline void vpn::icmpv4_ev (ev::io &w, int revents) { if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; socklen_t sa_len = sizeof (sa); int len; len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); sockinfo si(sa, PROT_ICMPv4); if (len > 0) { pkt->len = len; icmp_header *hdr = (icmp_header *)&((*pkt)[IP_OVERHEAD]); if (hdr->type == ::conf.icmp_type && hdr->code == 255) { // raw sockets deliver the ipv4, but don't expect it on sends // this is slow, but... pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD)); recv_vpn_packet (pkt, si); } } else { // probably ECONNRESET or somesuch slog (L_DEBUG, _("%s: %s."), (const char *)si, strerror (errno)); } delete pkt; } else { slog (L_ERR, _("FATAL: unknown revents %08x in socket, exiting.\n"), revents); exit (EXIT_FAILURE); } } #endif inline void vpn::udpv4_ev (ev::io &w, int revents) { if (revents & EV_READ) { vpn_packet *pkt = new vpn_packet; struct sockaddr_in sa; socklen_t sa_len = sizeof (sa); int len; len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); sockinfo si(sa, PROT_UDPv4); if (len > 0) { pkt->len = len; recv_vpn_packet (pkt, si); } else { // probably ECONNRESET or somesuch slog (L_DEBUG, _("%s: fd %d, %s."), (const char *)si, w.fd, strerror (errno)); } delete pkt; } else { slog (L_ERR, _("FATAL: unknown revents %08x in socket, exiting.\n"), revents); exit (EXIT_FAILURE); } } inline void vpn::tap_ev (ev::io &w, int revents) { if (revents & EV_READ) { /* process data */ tap_packet *pkt; pkt = tap->recv (); if (!pkt) return; if (pkt->len > 14) { int dst = mac2id (pkt->dst); int src = mac2id (pkt->src); if (src != THISNODE->id) { slog (L_ERR, _("FATAL: tap packet not originating on current node received (if-up script not working properly?), exiting.")); exit (EXIT_FAILURE); } if (dst == THISNODE->id) { slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting.")); exit (EXIT_FAILURE); } if (dst > conns.size ()) slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst); else inject_data_packet (pkt, dst); } delete pkt; } else abort (); } inline void vpn::event_cb (ev::timer &w, int) { if (events) { if (events & EVENT_SHUTDOWN) { slog (L_INFO, _("preparing shutdown...")); shutdown_all (); remove_pid (conf.pidfilename); slog (L_INFO, _("exiting.")); exit (EXIT_SUCCESS); } if (events & EVENT_RECONNECT) { slog (L_INFO, _("forced reconnect.")); reconnect_all (); } events = 0; } } void vpn::shutdown_all () { for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) (*c)->shutdown (); } void vpn::reconnect_all () { for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) delete *c; conns.clear (); connection_init (); for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i) conns.push_back (new connection (this, *i)); for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) (*c)->establish_connection (); } bool vpn::can_direct (conf_node *src, conf_node *dst) const { return src != dst && src->may_direct (dst) && dst->may_direct (src) && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS) || (src->protocols & dst->connectable_protocols ())); } // only works for indirect and routed connections: find a router // from THISNODE to dst connection * vpn::find_router_for (const connection *dst) { connection *router = 0; // first try to find a router with a direct connection, route there // regardless of any other considerations. { u32 prio = 1; for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) { connection *c = *i; if (c->conf->routerprio > prio && c->conf != THISNODE && can_direct (c->conf, dst->conf) && c->ictx && c->octx) { prio = c->conf->routerprio; router = c; } } } if (router) return router; // second try find the router with the highest priority, higher than ours { u32 prio = THISNODE->routerprio ? THISNODE->routerprio : 1; for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) { connection *c = *i; if (c->conf->routerprio > prio && c != dst && c->conf != THISNODE && c->ictx && c->octx) { prio = c->conf->routerprio; router = c; } } } return router; } void vpn::connection_established (connection *c) { for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) { connection *o = *i; if (o->si.valid () && c->si != o->si && c == find_router_for (o) && !can_direct (THISNODE, o->conf)) { slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."), o->conf->nodename, c->conf->nodename); o->rekey (); } } } void vpn::send_connect_request (connection *c) { connection *r = find_router_for (c); if (r) { slog (L_TRACE, _("%s: no address known, sending mediated connection request via %s."), c->conf->nodename, r->conf->nodename); r->send_connect_request (c->conf->id); } else slog (L_DEBUG, _("%s: no way to connect and no router found: unable to connect at this time."), c->conf->nodename); } void connection::dump_status () { slog (L_NOTICE, _("node %s (id %d)"), conf->nodename, conf->id); slog (L_NOTICE, _(" connectmode %d (%d) / sockaddr %s / minor %d"), connectmode, conf->connectmode, (const char *)si, (int)prot_minor); slog (L_NOTICE, _(" ictx/octx %08lx/%08lx / oseqno %d / retry_cnt %d"), (long)ictx, (long)octx, (int)oseqno, (int)retry_cnt); } void vpn::dump_status () { slog (L_NOTICE, _("BEGIN status dump (%ld)"), (long)ev_now ()); for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) (*c)->dump_status (); slog (L_NOTICE, _("END status dump")); } vpn::vpn (void) { event .set (this); udpv4_ev_watcher .set (this); ipv4_ev_watcher .set (this); #if ENABLE_TCP tcpv4_ev_watcher .set (this); #endif #if ENABLE_ICMP icmpv4_ev_watcher.set (this); #endif #if ENABLE_DNS dnsv4_ev_watcher .set (this); #endif tap_ev_watcher .set (this); } vpn::~vpn () { } gvpe-3.0/src/vpn_tcp.C0000644000000000000000000002771512615056110011561 00000000000000/* vpn_tcp.C -- handle the tcp part of the protocol. Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #if ENABLE_TCP // tcp processing is extremely ugly, since the gvpe protocol is simply // designed for unreliable datagram networks. tcp is implemented by // multiplexing packets over tcp. errors are completely ignored, as we // rely on the higher level layers to time out and reconnect. #include #include #include #include #include #include #include #include #include #include #include "netcompat.h" #include "vpn.h" #if ENABLE_HTTP_PROXY # include "conf.h" #endif struct tcp_connection; struct lt_sockinfo { bool operator()(const sockinfo *a, const sockinfo *b) const { return *a < *b; } }; struct tcp_si_map : public map { inline void cleaner_cb (ev::timer &w, int revents); ev::timer cleaner; tcp_si_map () { ev_default_loop (0); cleaner.set (this); cleaner.start (::conf.keepalive / 2, ::conf.keepalive / 2); } }; static tcp_si_map tcp_si; struct tcp_connection : ev::io { int tos; tstamp last_activity; const sockinfo si; vpn &v; bool active; // this connection has been actively established enum { ERROR, IDLE, CONNECTING, CONNECTING_PROXY, ESTABLISHED } state; vpn_packet *r_pkt; u32 r_len, r_ofs; vpn_packet *w_pkt; u32 w_len, w_ofs; #if ENABLE_HTTP_PROXY char *proxy_req; int proxy_req_len; #endif inline void tcpv4_ev (ev::io &w, int revents); bool send_packet (vpn_packet *pkt, int tos); bool write_packet (); void error (); // abort conenction && cleanup operator tcp_si_map::value_type() { return tcp_si_map::value_type (&si, this); } tcp_connection (int fd_, const sockinfo &si_, vpn &v_); ~tcp_connection (); }; void tcp_si_map::cleaner_cb (ev::timer &w, int revents) { tstamp to = ev_now () - ::conf.keepalive - 30 - 60; for (iterator i = begin (); i != end(); ) if (i->second->last_activity >= to) ++i; else { delete i->second; erase (i); i = begin (); } } void vpn::tcpv4_ev (ev::io &w, int revents) { if (revents & EV_READ) { struct sockaddr_in sa; socklen_t sa_len = sizeof (sa); int len; int fd = accept (w.fd, (sockaddr *)&sa, &sa_len); if (fd >= 0) { fcntl (fd, F_SETFL, O_NONBLOCK); fcntl (fd, F_SETFD, FD_CLOEXEC); sockinfo si(sa, PROT_TCPv4); slog (L_DEBUG, _("%s: accepted tcp connection"), (const char *)si);//D tcp_connection *i = new tcp_connection (fd, si, *this); tcp_si.insert (*i); } } } bool vpn::send_tcpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { tcp_si_map::iterator info = tcp_si.find (&si); tcp_connection *i; if (info == tcp_si.end ()) { i = new tcp_connection (-1, si, *this); tcp_si.insert (*i); } else i = info->second; return i->send_packet (pkt, tos); } bool tcp_connection::write_packet () { ssize_t len; if (w_ofs < 2) { u16 plen = htons (w_pkt->len); iovec vec[2]; //TODO: char* is the right type? hardly... vec[0].iov_base = (char *)((u8 *)&plen) + w_ofs; vec[0].iov_len = 2 - w_ofs; vec[1].iov_base = (char *)&((*w_pkt)[0]); vec[1].iov_len = w_len - 2; len = writev (fd, vec, 2); } else len = write (fd, &((*w_pkt)[w_ofs - 2]), w_len); if (len > 0) { w_ofs += len; w_len -= len; return w_len == 0; } else if (len < 0 && (errno == EAGAIN || errno == EINTR)) return false; else { error (); return false; } } void tcp_connection::tcpv4_ev (ev::io &w, int revents) { last_activity = ev_now (); if (revents & EV_WRITE) { if (state == CONNECTING) { state = ESTABLISHED; set (EV_READ); #if ENABLE_HTTP_PROXY if (::conf.proxy_host && ::conf.proxy_port) { state = CONNECTING_PROXY; if (write (fd, proxy_req, proxy_req_len) == 0) { error (); return; } free (proxy_req); proxy_req = 0; } #endif } else if (state == ESTABLISHED) { if (w_pkt) { if (write_packet ()) { delete w_pkt; w_pkt = 0; set (EV_READ); } } else set (EV_READ); } else set (EV_READ); } if (revents & EV_READ) { if (state == ESTABLISHED) for (;;) { if (!r_pkt) { r_pkt = new vpn_packet; r_ofs = 0; r_len = 2; // header } ssize_t len = read (fd, &((*r_pkt)[r_ofs < 2 ? r_ofs : r_ofs - 2]), r_len); if (len > 0) { r_len -= len; r_ofs += len; if (r_len == 0) { if (r_ofs == 2) { r_len = ntohs (*(u16 *)&((*r_pkt)[0])); r_pkt->len = r_len; if (r_len > 0 && r_len < MAXSIZE) continue; } else { v.recv_vpn_packet (r_pkt, si); delete r_pkt; r_pkt = 0; continue; } } else break; } else if (len < 0 && (errno == EINTR || errno == EAGAIN)) break; // len == 0 <-> EOF error (); break; } #if ENABLE_HTTP_PROXY else if (state == CONNECTING_PROXY) { fcntl (fd, F_SETFL, 0); char r[1024]; int i; bool emptyline = false; // we do a blocking read of the response, to hell with it for (i = 0; i < 1023; i++) { int l = read (fd, &r[i], 1); if (l <= 0) { error (); return; } if (r[i] == '\012') { if (emptyline) break; else emptyline = true; } else if (r[i] != '\015') emptyline = false; } fcntl (fd, F_SETFL, O_NONBLOCK); if (i < 12) { slog (L_ERR, _("(%s): unable to do proxy-forwarding, short response"), (const char *)si); error (); } else if (r[0] != 'H' || r[1] != 'T' || r[2] != 'T' || r[3] != 'P' || r[4] != '/' || r[5] != '1' // http-major || r[9] != '2') // response { slog (L_ERR, _("(%s): malformed or unexpected proxy response (%.12s)"), (const char *)si, r); error (); } else state = ESTABLISHED; } #endif } } bool tcp_connection::send_packet (vpn_packet *pkt, int tos) { last_activity = ev_now (); if (state == IDLE) { // woaw, the first lost packet ;) fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd >= 0) { const sockinfo *csi = &si; #if ENABLE_HTTP_PROXY sockinfo psi; if (::conf.proxy_host && ::conf.proxy_port) { psi.set (::conf.proxy_host, ::conf.proxy_port, PROT_TCPv4); if (psi.valid ()) { csi = ψ proxy_req_len = asprintf (&proxy_req, "CONNECT %s:%d HTTP/1.0\015\012" "%s%s%s" // optional proxy-auth "\015\012", si.ntoa (), ntohs (si.port), ::conf.proxy_auth ? "Proxy-Authorization: Basic " : "", ::conf.proxy_auth ? ::conf.proxy_auth : "", ::conf.proxy_auth ? "\015\012" : ""); } else slog (L_ERR, _("unable to resolve http proxy hostname '%s', trying direct"), ::conf.proxy_host); } #endif fcntl (fd, F_SETFL, O_NONBLOCK); if (connect (fd, csi->sav4 (), csi->salenv4 ()) >= 0 || errno == EINPROGRESS) { fcntl (fd, F_SETFL, O_NONBLOCK); fcntl (fd, F_SETFD, FD_CLOEXEC); state = CONNECTING; start (fd, EV_WRITE); } else close (fd); } } else if (state == ESTABLISHED) { // drop packet if the tcp write buffer is full. this *is* the // right thing to do, not using tcp *is* the right thing to do. if (!w_pkt) { // how this maps to the underlying tcp packets we don't know // and we don't care. at least we tried ;) #if defined(SOL_IP) && defined(IP_TOS) if (tos != this->tos) { this->tos = tos; setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); } #endif w_pkt = pkt; w_ofs = 0; w_len = pkt->len + 2; // length + size header if (write_packet ()) w_pkt = 0; else { w_pkt = new vpn_packet; w_pkt->set (*pkt); set (EV_READ | EV_WRITE); } } } return state != ERROR; } void tcp_connection::error () { stop (); if (fd >= 0) { close (fd); tos = -1; fd = -1; } delete r_pkt; r_pkt = 0; delete w_pkt; w_pkt = 0; #if ENABLE_HTTP_PROXY free (proxy_req); proxy_req = 0; #endif state = active ? IDLE : ERROR; } tcp_connection::tcp_connection (int fd_, const sockinfo &si_, vpn &v_) : v(v_), si(si_) { set (this); last_activity = ev_now (); r_pkt = 0; w_pkt = 0; tos = -1; fd = fd_; #if ENABLE_HTTP_PROXY proxy_req = 0; #endif if (fd < 0) { active = true; state = IDLE; } else { active = false; state = ESTABLISHED; start (fd, EV_READ); } } tcp_connection::~tcp_connection () { error (); } #endif gvpe-3.0/src/vpn_dns.C0000644000000000000000000011123412615056110011545 00000000000000/* vpn_dns.C -- handle the dns tunnel part of the protocol. Copyright (C) 2003-2011 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ // TODO: EDNS0 option to increase dns mtu? // TODO: re-write dns packet parsing/creation using a safe mem-buffer // to ensure no buffer overflows or similar problems. #include "config.h" #if ENABLE_DNS // dns processing is EXTREMELY ugly. For obvious(?) reasons. // it's a hack, use only in emergency situations please. #include #include #include #include #include #include #include #include #include #include #include #include /* bug in libgmp: gmp.h relies on cstdio being included */ #include #include "netcompat.h" #include "vpn.h" #define MIN_POLL_INTERVAL 0.025 // poll at most this often when no data received #define MAX_POLL_INTERVAL 1. // how often to poll minimally when the server has no data #define INITIAL_TIMEOUT 0.1 // retry timeouts #define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn #define MAX_SEND_INTERVAL 5. // optimistic? #define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog #define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE #define MAX_DOMAIN_SIZE 235 // 255 is legal limit, but bind doesn't compress well // 240 leaves about 4 bytes of server reply data // every request byte less give room for two reply bytes #define SEQNO_MASK 0x3fff #define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) #define MAX_LBL_SIZE 63 #define MAX_PKT_SIZE 512 #define RR_TYPE_A 1 #define RR_TYPE_NULL 10 #define RR_TYPE_TXT 16 #define RR_TYPE_AAAA 28 #define RR_TYPE_ANY 255 #define RR_CLASS_IN 1 #define CMD_IP_1 207 #define CMD_IP_2 46 #define CMD_IP_3 236 #define CMD_IP_RST 29 // some error, reset and retry #define CMD_IP_REJ 32 // do not want you #define CMD_IP_SYN 113 // connection established #define CMD_IP_CSE 213 // connection established, but likely case mismatch static bool is_uc (char c) { return 'A' <= c && c <= 'Z'; } static bool is_lc (char c) { return 'a' <= c && c <= 'z'; } // works for cmaps up to 255 (not 256!) struct charmap { enum { INVALID = (u8)255 }; char encode [256]; // index => char u8 decode [256]; // char => index unsigned int size; charmap (const char *cmap); }; charmap::charmap (const char *cmap) { char *enc = encode; u8 *dec = decode; memset (enc, (char) 0, 256); memset (dec, (char)INVALID, 256); for (size = 0; cmap [size]; size++) { char c = cmap [size]; enc [size] = c; dec [(u8)c] = size; // allow lowercase/uppercase aliases if possible if (is_uc (c) && dec [c + ('a' - 'A')] == INVALID) dec [c + ('a' - 'A')] = size; if (is_lc (c) && dec [c - ('a' - 'A')] == INVALID) dec [c - ('a' - 'A')] = size; } assert (size < 256); } #define MAX_DEC_LEN 500 #define MAX_ENC_LEN (MAX_DEC_LEN * 2) #define MAX_LIMBS ((MAX_DEC_LEN * 8 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS + 1) // ugly. minimum base is 16(!) struct basecoder { charmap cmap; unsigned int enc_len [MAX_DEC_LEN]; unsigned int dec_len [MAX_ENC_LEN]; unsigned int encode_len (unsigned int len) const; unsigned int decode_len (unsigned int len) const; unsigned int encode (char *dst, u8 *src, unsigned int len) const; unsigned int decode (u8 *dst, char *src, unsigned int len) const; basecoder (const char *cmap); }; basecoder::basecoder (const char *cmap) : cmap (cmap) { int decn = -1; for (unsigned int len = 0; len < MAX_DEC_LEN; ++len) { u8 src [MAX_DEC_LEN]; u8 dst [MAX_ENC_LEN]; memset (src, 255, len); mp_limb_t m [MAX_LIMBS]; mp_size_t n; n = mpn_set_str (m, src, len, 256); n = mpn_get_str (dst, this->cmap.size, m, n); for (int i = 0; n && !dst [i]; ++i, --n) ; enc_len [len] = n; while (decn < n) dec_len [++decn] = len; } } unsigned int basecoder::encode_len (unsigned int len) const { return enc_len [len]; } unsigned int basecoder::decode_len (unsigned int len) const { return dec_len [len]; } unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) const { if (!len || len > MAX_DEC_LEN) return 0; int elen = encode_len (len); mp_limb_t m [MAX_LIMBS]; mp_size_t n; u8 dst_ [MAX_ENC_LEN]; n = mpn_set_str (m, src, len, 256); n = mpn_get_str (dst_, cmap.size, m, n); int plen = elen; // for padding while (n < plen) { *dst++ = cmap.encode [0]; plen--; } for (unsigned int i = n - plen; i < n; ++i) *dst++ = cmap.encode [dst_ [i]]; return elen; } unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) const { if (!len || len > MAX_ENC_LEN) return 0; u8 src_ [MAX_ENC_LEN]; unsigned int elen = 0; while (len--) { u8 val = cmap.decode [(u8)*src++]; if (val != charmap::INVALID) src_ [elen++] = val; } int dlen = decode_len (elen); mp_limb_t m [MAX_LIMBS]; mp_size_t n; u8 dst_ [MAX_DEC_LEN]; n = mpn_set_str (m, src_, elen, cmap.size); n = mpn_get_str (dst_, 256, m, n); if (n < dlen) { memset (dst, 0, dlen - n); memcpy (dst + dlen - n, dst_, n); } else memcpy (dst, dst_ + n - dlen, dlen); return dlen; } #if 0 struct test { test (); } test; test::test () { basecoder cdc ("0123456789abcdefghijklmnopqrstuvwxyz"); u8 in[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static char enc[200]; static u8 dec[200]; for (int i = 1; i < 20; i++) { int elen = cdc.encode (enc, in, i); int dlen = cdc.decode (dec, enc, elen); printf ("%d>%d>%d (%s>%s)\n", i, elen, dlen, enc, dec); } abort (); } #endif static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); // a-zA-Z0-9 static basecoder cdc36 ("dPhZr06QmJkB34tSvL81xAeF92wGyO57uCnI"); // a-z0-9 for case-changers static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyOuCnI"); // a-z ///////////////////////////////////////////////////////////////////////////// #define HDRSIZE 5 inline void encode_header (char *data, int clientid, int seqno, int retry = 0) { assert (clientid < 256); seqno &= SEQNO_MASK; u8 hdr[3] = { seqno, (seqno >> 8) | (retry << 6), clientid, }; cdc36.encode (data, hdr, 3); } inline void decode_header (char *data, int &clientid, int &seqno) { u8 hdr[3]; cdc36.decode (hdr, data, HDRSIZE); clientid = hdr[2]; seqno = ((hdr[1] << 8) | hdr[0]) & SEQNO_MASK; } ///////////////////////////////////////////////////////////////////////////// struct byte_stream { u8 *data; int maxsize; int fill; byte_stream (int maxsize); ~byte_stream (); bool empty () { return !fill; } int size () { return fill; } bool put (u8 *data, unsigned int datalen); bool put (vpn_packet *pkt); vpn_packet *get (); u8 *begin () { return data; } void remove (int count); }; byte_stream::byte_stream (int maxsize) : maxsize (maxsize), fill (0) { data = new u8 [maxsize]; } byte_stream::~byte_stream () { delete data; } void byte_stream::remove (int count) { assert (count <= fill); memmove (data, data + count, fill -= count); } bool byte_stream::put (u8 *data, unsigned int datalen) { if (maxsize - fill < datalen) return false; memcpy (this->data + fill, data, datalen); fill += datalen; return true; } bool byte_stream::put (vpn_packet *pkt) { if (maxsize - fill < pkt->len + 2) return false; data [fill++] = pkt->len >> 8; data [fill++] = pkt->len; memcpy (data + fill, pkt->at (0), pkt->len); fill += pkt->len; return true; } vpn_packet * byte_stream::get () { unsigned int len; for (;;) { if (fill < 2) return 0; len = (data [0] << 8) | data [1]; if (len <= MAXSIZE) break; // TODO: handle this better than skipping, e.g. by reset slog (L_DEBUG, _("DNS: corrupted packet (%02x %02x > %d) stream skipping a byte..."), data [0], data [1], MAXSIZE); remove (1); } if (fill < len + 2) return 0; vpn_packet *pkt = new vpn_packet; pkt->len = len; memcpy (pkt->at (0), data + 2, len); remove (len + 2); return pkt; } ///////////////////////////////////////////////////////////////////////////// #define FLAG_QUERY ( 0 << 15) #define FLAG_RESPONSE ( 1 << 15) #define FLAG_OP_MASK (15 << 11) #define FLAG_OP_QUERY ( 0 << 11) #define FLAG_AA ( 1 << 10) #define FLAG_TC ( 1 << 9) #define FLAG_RD ( 1 << 8) #define FLAG_RA ( 1 << 7) #define FLAG_AUTH ( 1 << 5) #define FLAG_RCODE_MASK (15 << 0) #define FLAG_RCODE_OK ( 0 << 0) #define FLAG_RCODE_FORMERR ( 1 << 0) #define FLAG_RCODE_SERVFAIL ( 2 << 0) #define FLAG_RCODE_NXDOMAIN ( 3 << 0) #define FLAG_RCODE_REFUSED ( 5 << 0) #define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD) #define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA) struct dns_cfg { static int next_uid; u8 chksum; u8 rrtype; u16 uid; // to make request unique u8 version; u8 flags; u16 max_size; u8 id1, id2, id3, id4; u16 client; u8 def_ttl; u8 r0; u8 syn_cdc; // cdc en/decoder for syn (A?) requests u8 hdr_cdc; // cdc en/decoder for regular request headers u8 req_cdc; // cdc en/decoder for regular (ANY?) request data u8 rep_cdc; // cdc en/decoder for regular (TXT) replies, 0 == 8 bit encoding u8 r1, r2, r3, r4; void reset (int clientid); bool valid (); u8 get_chksum (); }; int dns_cfg::next_uid; void dns_cfg::reset (int clientid) { // this ID must result in some mixed-case characters in cdc26-encoding id1 = 'G'; id2 = 'V'; id3 = 'P'; id4 = 'E'; version = 2; rrtype = RR_TYPE_TXT; flags = 0; def_ttl = 0; syn_cdc = 26; hdr_cdc = 36; req_cdc = conf.dns_case_preserving ? 62 : 36; rep_cdc = 0; max_size = htons (MAX_PKT_SIZE); client = htons (clientid); uid = ++next_uid; r0 = r1 = r2 = r3 = r4 = 0; chksum = get_chksum (); } // simple but not trivial chksum u8 dns_cfg::get_chksum () { unsigned int sum = 0xff00; // only 16 bits required u8 old_chksum = chksum; chksum = 0; for (unsigned int i = 0; i < sizeof (*this); ++i) sum += ((u8 *)this)[i] * (i + 1); chksum = old_chksum; return sum + (sum >> 8); } bool dns_cfg::valid () { // although the protocol itself allows for some configurability, // only the following encoding/decoding settings are implemented. return id1 == 'G' && id2 == 'V' && id3 == 'P' && id4 == 'E' && version == 2 && syn_cdc == 26 && hdr_cdc == 36 && (req_cdc == 36 || req_cdc == 62) && rep_cdc == 0 && chksum == get_chksum (); } struct dns_packet : net_packet { u16 id; u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4 u16 qdcount, ancount, nscount, arcount; u8 data [MAXSIZE - 6 * 2]; int decode_label (char *data, int size, int &offs); }; int dns_packet::decode_label (char *data, int size, int &offs) { char *orig = data; memset (data, 0, size); while (offs < size - 1) { u8 len = (*this)[offs++]; if (!len) break; else if (len < 64) { if (size < len + 1 || offs + len >= MAXSIZE - 1) break; memcpy (data, &((*this)[offs]), len); data += len; size -= len; offs += len; *data++ = '.'; size--; } else { int offs2 = ((len & 63) << 8) + (*this)[offs++]; data += decode_label (data, size, offs2); break; } } return data - orig; } ///////////////////////////////////////////////////////////////////////////// static u16 next_id () { static u16 dns_id = 0; // TODO: should be per-vpn #if 1 if (!dns_id) dns_id = time (0); // the simplest lsfr with periodicity 65535 i could find dns_id = (dns_id << 1) | (((dns_id >> 1) ^ (dns_id >> 2) ^ (dns_id >> 4) ^ (dns_id >> 15)) & 1); return dns_id; #else dns_id++;//D return htons (dns_id); #endif } struct dns_rcv; struct dns_snd; struct dns_connection { connection *c; struct vpn *vpn; dns_cfg cfg; bool established; const basecoder *cdc; tstamp last_received; tstamp last_sent; double min_latency; double poll_interval, send_interval; vector rcvpq; byte_stream rcvdq; int rcvseq; int repseq; byte_stream snddq; int sndseq; inline void time_cb (ev::timer &w, int revents); ev::timer tw; void receive_rep (dns_rcv *r); void reset (); // quite like tcp RST void set_cfg (); // to be called after any cfg changes dns_connection (connection *c); ~dns_connection (); }; struct dns_snd { dns_packet *pkt; tstamp timeout, sent; int retry; struct dns_connection *dns; int seqno; bool stdhdr; void gen_stream_req (int seqno, byte_stream &stream); void gen_syn_req (); dns_snd (dns_connection *dns); ~dns_snd (); }; dns_snd::dns_snd (dns_connection *dns) : dns (dns) { timeout = 0; retry = 0; seqno = 0; sent = ev_now (); stdhdr = false; pkt = new dns_packet; pkt->id = next_id (); } dns_snd::~dns_snd () { delete pkt; } static void append_domain (dns_packet &pkt, int &offs, const char *domain) { // add tunnel domain for (;;) { const char *end = strchr (domain, '.'); if (!end) end = domain + strlen (domain); int len = end - domain; pkt [offs++] = len; memcpy (pkt.at (offs), domain, len); offs += len; if (!*end) break; domain = end + 1; } } void dns_snd::gen_stream_req (int seqno, byte_stream &stream) { stdhdr = true; this->seqno = seqno; timeout = ev_now () + INITIAL_TIMEOUT; pkt->flags = htons (DEFAULT_CLIENT_FLAGS); pkt->qdcount = htons (1); int offs = 6*2; int dlen = MAX_DOMAIN_SIZE - (strlen (dns->c->conf->domain) + 2); // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well, // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra char enc[256], *encp = enc; encode_header (enc, THISNODE->id, seqno); int datalen = dns->cdc->decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE); if (datalen > stream.size ()) datalen = stream.size (); int enclen = dns->cdc->encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE; stream.remove (datalen); while (enclen) { int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE; (*pkt)[offs++] = lbllen; memcpy (pkt->at (offs), encp, lbllen); offs += lbllen; encp += lbllen; enclen -= lbllen; } append_domain (*pkt, offs, dns->c->conf->domain); (*pkt)[offs++] = 0; (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY; (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; pkt->len = offs; } void dns_snd::gen_syn_req () { timeout = ev_now () + INITIAL_SYN_TIMEOUT; pkt->flags = htons (DEFAULT_CLIENT_FLAGS); pkt->qdcount = htons (1); int offs = 6 * 2; int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg)); assert (elen <= MAX_LBL_SIZE); (*pkt)[offs] = elen; offs += elen + 1; append_domain (*pkt, offs, dns->c->conf->domain); (*pkt)[offs++] = 0; (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A; (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; pkt->len = offs; } struct dns_rcv { int seqno; dns_packet *pkt; // reply packet u8 data [MAXSIZE]; // actually part of the reply packet... int datalen; dns_rcv (int seqno, u8 *data, int datalen); ~dns_rcv (); }; dns_rcv::dns_rcv (int seqno, u8 *data, int datalen) : seqno (seqno), pkt (new dns_packet), datalen (datalen) { memcpy (this->data, data, datalen); } dns_rcv::~dns_rcv () { delete pkt; } ///////////////////////////////////////////////////////////////////////////// dns_connection::dns_connection (connection *c) : c (c) , rcvdq (MAX_BACKLOG * 2) , snddq (MAX_BACKLOG) { tw.set (this); vpn = c->vpn; reset (); } dns_connection::~dns_connection () { reset (); } void dns_connection::reset () { while (!rcvpq.empty ()) { delete rcvpq.back (); rcvpq.pop_back (); } for (int i = vpn->dns_sndpq.size (); i--; ) if (vpn->dns_sndpq [i]->dns == this) { vpn->dns_sndpq [i] = vpn->dns_sndpq.back (); vpn->dns_sndpq.pop_back (); } established = false; rcvseq = repseq = sndseq = 0; last_sent = 0; poll_interval = 0.5; // starting here send_interval = 0.5; // starting rate min_latency = INITIAL_TIMEOUT; } void dns_connection::set_cfg () { cdc = cfg.req_cdc == 36 ? &cdc36 : &cdc62; } void dns_connection::receive_rep (dns_rcv *r) { if (r->datalen) poll_interval = max (poll_interval * (1. / 1.2), MIN_POLL_INTERVAL); else poll_interval = min (poll_interval * 1.1, MAX_POLL_INTERVAL); rcvpq.push_back (r); redo: // find next packet for (vector::iterator i = rcvpq.end (); i-- != rcvpq.begin (); ) if (SEQNO_EQ (rcvseq, (*i)->seqno)) { //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D // enter the packet into our input stream r = *i; // remove the oldest packet, look forward, as it's oldest first for (vector::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j) if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW)) { //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D delete *j; rcvpq.erase (j); break; } rcvseq = (rcvseq + 1) & SEQNO_MASK; if (!rcvdq.put (r->data, r->datalen)) { // MUST never overflow, can be caused by data corruption, TODO slog (L_CRIT, "DNS: !rcvdq.put (r->data, r->datalen)"); reset (); return; } while (vpn_packet *pkt = rcvdq.get ()) { sockinfo si; si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4; vpn->recv_vpn_packet (pkt, si); delete pkt; } // check for further packets goto redo; } } void vpn::dnsv4_server (dns_packet &pkt) { u16 flags = ntohs (pkt.flags); int offs = 6 * 2; // skip header pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK)) && pkt.qdcount == htons (1)) { char qname [MAXSIZE]; int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs); u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++]; u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++]; pkt.qdcount = htons (1); pkt.ancount = 0; pkt.nscount = 0; // should be self, as other nameservers reply like this pkt.arcount = 0; // a record for self, as other nameservers reply like this pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_SERVFAIL); int dlen = strlen (THISNODE->domain); if (qclass == RR_CLASS_IN && qlen > dlen + 1 && !memcmp (qname + qlen - (dlen + 1), THISNODE->domain, dlen)) { // now generate reply pkt.ancount = htons (1); // one answer RR pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); if ((qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT || qtype == RR_TYPE_NULL) && qlen > dlen + 1 + HDRSIZE) { // correct class, domain: parse int client, seqno; decode_header (qname, client, seqno); if (0 < client && client <= conns.size ()) { connection *c = conns [client - 1]; dns_connection *dns = c->dns; dns_rcv *rcv; if (dns) { u8 data[MAXSIZE]; int datalen = dns->cdc->decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE)); for (vector::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) if (SEQNO_EQ ((*i)->seqno, seqno)) { // already seen that request: simply reply with the cached reply dns_rcv *r = *i; slog (L_DEBUG, "DNS: duplicate packet received ID %d, SEQ %d", htons (r->pkt->id), seqno); // refresh header & id, as the retry count could have changed memcpy (r->pkt->at (6 * 2 + 1), pkt.at (6 * 2 + 1), HDRSIZE); r->pkt->id = pkt.id; memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); goto duplicate_request; } // new packet, queue rcv = new dns_rcv (seqno, data, datalen); dns->receive_rep (rcv); } { pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class pkt [offs++] = 0; pkt [offs++] = 0; pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL int rdlen_offs = offs += 2; if (dns) { int dlen = ntohs (dns->cfg.max_size) - offs; // bind doesn't compress well, so reduce further by one label length dlen -= qlen; // only put data into in-order sequence packets, if // we receive out-of-order packets we generate empty // replies //printf ("%d - %d & %x (=%d) < %d\n", seqno, dns->repseq, SEQNO_MASK, (seqno - dns->repseq) & SEQNO_MASK, MAX_WINDOW);//D if (((seqno - dns->repseq) & SEQNO_MASK) <= MAX_WINDOW) { dns->repseq = seqno; while (dlen > 1 && !dns->snddq.empty ()) { int txtlen = dlen <= 255 ? dlen - 1 : 255; if (txtlen > dns->snddq.size ()) txtlen = dns->snddq.size (); pkt[offs++] = txtlen; memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); offs += txtlen; dns->snddq.remove (txtlen); dlen -= txtlen + 1; } } // avoid completely empty TXT rdata if (offs == rdlen_offs) pkt[offs++] = 0; slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); } else { // send RST pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; pkt [offs++] = CMD_IP_RST; } int rdlen = offs - rdlen_offs; pkt [rdlen_offs - 2] = rdlen >> 8; pkt [rdlen_offs - 1] = rdlen; if (dns) { // now update dns_rcv copy rcv->pkt->len = offs; memcpy (rcv->pkt->at (0), pkt.at (0), offs); } } duplicate_request: ; } else pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); } else if (qtype == RR_TYPE_A && qlen > dlen + 1 + cdc26.encode_len (sizeof (dns_cfg))) { dns_cfg cfg; cdc26.decode ((u8 *)&cfg, qname, cdc26.encode_len (sizeof (dns_cfg))); int client = ntohs (cfg.client); pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section pkt [offs++] = RR_TYPE_A >> 8; pkt [offs++] = RR_TYPE_A; // type pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class pkt [offs++] = 0; pkt [offs++] = 0; pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL pkt [offs++] = 0; pkt [offs++] = 4; // rdlength pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; pkt [offs++] = CMD_IP_REJ; if (0 < client && client <= conns.size ()) { connection *c = conns [client - 1]; if (cfg.valid ()) { slog (L_INFO, _("DNS: client %d connects (version %d, req_cdc %d)"), client, cfg.version, cfg.req_cdc); // check for any encoding mismatches - hints at a case problem char qname2 [MAX_ENC_LEN]; cdc26.encode (qname2, (u8 *)&cfg, sizeof (dns_cfg)); delete c->dns; pkt [offs - 1] = memcmp (qname, qname2, cdc26.encode_len (sizeof (dns_cfg))) ? CMD_IP_CSE : CMD_IP_SYN; c->dns = new dns_connection (c); c->dns->cfg = cfg; c->dns->set_cfg (); } } } } pkt.len = offs; } } void vpn::dnsv4_client (dns_packet &pkt) { u16 flags = ntohs (pkt.flags); int offs = 6 * 2; // skip header pkt.qdcount = ntohs (pkt.qdcount); pkt.ancount = ntohs (pkt.ancount); // go through our request list and find the corresponding request for (vector::iterator i = dns_sndpq.begin (); i != dns_sndpq.end (); ++i) if ((*i)->pkt->id == pkt.id) { dns_connection *dns = (*i)->dns; connection *c = dns->c; int seqno = (*i)->seqno; u8 data[MAXSIZE], *datap = data; //printf ("rcv pkt %x\n", seqno);//D if ((*i)->retry) { dns->send_interval *= 1.01; if (dns->send_interval > MAX_SEND_INTERVAL) dns->send_interval = MAX_SEND_INTERVAL; } else { #if 0 dns->send_interval *= 0.999; #endif // the latency surely puts an upper bound on // the minimum send interval double latency = ev_now () - (*i)->sent; if (latency < dns->min_latency) dns->min_latency = latency; if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor) dns->send_interval = dns->min_latency * conf.dns_overlap_factor; if (dns->send_interval < conf.dns_send_interval) dns->send_interval = conf.dns_send_interval; } delete *i; dns_sndpq.erase (i); if (flags & FLAG_RESPONSE && !(flags & FLAG_OP_MASK)) { char qname[MAXSIZE]; while (pkt.qdcount-- && offs < MAXSIZE - 4) { int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs); offs += 4; // skip qtype, qclass } while (pkt.ancount-- && offs < MAXSIZE - 10 && datap) { int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs); u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++]; u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++]; u32 ttl = pkt [offs++] << 24; ttl |= pkt [offs++] << 16; ttl |= pkt [offs++] << 8; ttl |= pkt [offs++]; u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++]; if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT || qtype == dns->cfg.rrtype) { if (rdlen <= MAXSIZE - offs) { // decode bytes, finally while (rdlen) { int txtlen = pkt [offs++]; assert (txtlen + offs < MAXSIZE - 1); memcpy (datap, pkt.at (offs), txtlen); datap += txtlen; offs += txtlen; rdlen -= txtlen + 1; } } } else if (qtype == RR_TYPE_A) { u8 ip [4]; ip [0] = pkt [offs++]; ip [1] = pkt [offs++]; ip [2] = pkt [offs++]; ip [3] = pkt [offs++]; if (ip [0] == CMD_IP_1 && ip [1] == CMD_IP_2 && ip [2] == CMD_IP_3) { slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]); if (ip [3] == CMD_IP_RST) { slog (L_DEBUG, _("DNS: got tunnel RST request.")); dns->reset (); return; } else if (ip [3] == CMD_IP_SYN) { slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); dns->established = true; } else if (ip [3] == CMD_IP_CSE) { if (conf.dns_case_preserving) { slog (L_INFO, _("DNS: got tunnel CSE reply, globally downgrading to case-insensitive protocol.")); conf.dns_case_preserving = false; dns->reset (); return; } else { slog (L_DEBUG, _("DNS: got tunnel CSE reply, server likes us.")); dns->established = true; } } else if (ip [3] == CMD_IP_REJ) { slog (L_ERR, _("DNS: got tunnel REJ reply, server does not like us.")); dns->tw.start (60.); } else { slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]); dns->tw.start (60.); } } else slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"), ip [0], ip [1], ip [2], ip [3]); return; } int client, rseqno; decode_header (qname, client, rseqno); if (client != THISNODE->id) { slog (L_INFO, _("DNS: got dns tunnel response with wrong clientid, ignoring")); datap = 0; } else if (rseqno != seqno) { slog (L_DEBUG, _("DNS: got dns tunnel response with wrong seqno, badly caching nameserver?")); datap = 0; } } } // todo: pkt now used if (datap) dns->receive_rep (new dns_rcv (seqno, data, datap - data)); break; } } void vpn::dnsv4_ev (ev::io &w, int revents) { if (revents & EV_READ) { dns_packet *pkt = new dns_packet; struct sockaddr_in sa; socklen_t sa_len = sizeof (sa); pkt->len = recvfrom (w.fd, pkt->at (0), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); if (pkt->len > 0) { if (ntohs (pkt->flags) & FLAG_RESPONSE) dnsv4_client (*pkt); else { dnsv4_server (*pkt); sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len); } delete pkt; } } } bool vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { int client = ntohl (si.host); assert (0 < client && client <= conns.size ()); connection *c = conns [client - 1]; if (!c->dns) c->dns = new dns_connection (c); if (c->dns->snddq.put (pkt)) { min_it (c->dns->poll_interval, 0.25); c->dns->tw (); } // always return true even if the buffer overflows return true; } void dns_connection::time_cb (ev::timer &w, int revents) { // servers have to be polled if (THISNODE->dns_port) return; // check for timeouts and (re)transmit tstamp next = 86400 * 365; dns_snd *send = 0; for (vector::iterator i = vpn->dns_sndpq.begin (); i != vpn->dns_sndpq.end (); ++i) { dns_snd *r = *i; if (r->timeout <= ev_now ()) { if (!send) { send = r; r->retry++; r->timeout = ev_now () + r->retry * min_latency * conf.dns_timeout_factor; //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D // the following code changes the query section a bit, forcing // the forwarder to generate a new request if (r->stdhdr) encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry); } } else min_it (next, r->timeout - ev_now ()); } if (!send) { // generate a new packet, if wise if (!established) { if (vpn->dns_sndpq.empty ()) { send = new dns_snd (this); cfg.reset (THISNODE->id); set_cfg (); send->gen_syn_req (); } } else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) { if (last_sent + send_interval <= ev_now ()) { //printf ("sending data request etc.\n"); //D if (!snddq.empty ()) min_it (next, send_interval); send = new dns_snd (this); send->gen_stream_req (sndseq, snddq); send->timeout = ev_now () + min_latency * conf.dns_timeout_factor; //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D sndseq = (sndseq + 1) & SEQNO_MASK; } else min_it (next, last_sent + send_interval - ev_now ()); } if (send) vpn->dns_sndpq.push_back (send); } if (send) { last_sent = ev_now (); sendto (vpn->dnsv4_fd, send->pkt->at (0), send->pkt->len, 0, vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); } min_it (next, last_sent + max (poll_interval, send_interval) - ev_now ()); slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)", poll_interval, send_interval, next - ev_now (), vpn->dns_sndpq.size (), snddq.size (), rcvpq.size ()); w.start (next); } #endif gvpe-3.0/src/sockinfo.h0000644000000000000000000000514112615056110011755 00000000000000/* sockinfo.h -- socket address management Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_SOCKINFO_H__ #define GVPE_SOCKINFO_H__ #include "netcompat.h" #include "conf.h" // encapsulate one or more network addresses. this structure // gets transferred over the wire, so be careful with endianness etc. struct sockinfo { u32 host; u16 port; u8 prot; u8 pad1; void set (const sockaddr_in *sa, u8 prot_); void set (const conf_node *conf, u8 prot_); void set (const char *hostname, u16 port_, u8 prot_); // return the supported protocols u8 supported_protocols (conf_node *conf = 0); bool upgrade_protocol (u8 prot_, conf_node *conf = 0); operator const char *() const; const sockaddr *sav4 () const; const socklen_t salenv4 () const { return sizeof (sockaddr_in); } const char *ntoa () const; bool valid () const; sockinfo() { prot = 0; } sockinfo(const char *hostname, u16 port, u8 prot) { set (hostname, port, prot); } sockinfo(const sockaddr_in &sa, u8 prot) { set (&sa, prot); } sockinfo(const conf_node *conf, u8 prot) { set (conf, prot); } }; bool operator == (const sockinfo &a, const sockinfo &b); bool operator < (const sockinfo &a, const sockinfo &b); inline bool operator != (const sockinfo &a, const sockinfo &b) { return !(a == b); } #endif gvpe-3.0/src/sockinfo.C0000644000000000000000000001207512615056110011714 00000000000000/* sockinfo.C -- socket address management Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" // for gethostbyname #include // for inet_aton #include #include #include #include "gettext.h" #include "sockinfo.h" #include "slog.h" #include #include // all ipv4-based protocols #define PROTv4 (PROT_UDPv4 | PROT_TCPv4 | PROT_ICMPv4 | PROT_IPv4 | PROT_DNSv4) void sockinfo::set (const sockaddr_in *sa, u8 prot_) { host = sa->sin_addr.s_addr; port = prot_ & (PROT_IPv4 | PROT_ICMPv4) ? 0 : sa->sin_port; prot = prot_; } void sockinfo::set (const char *hostname, u16 port_, u8 prot_) { prot = prot_; host = 0; port = htons (port_); if (prot & PROTv4 && hostname) { struct in_addr in; struct hostent *he; if (inet_aton (hostname, &in)) host = in.s_addr; else if ((he = gethostbyname (hostname)) && he->h_addrtype == AF_INET && he->h_length == 4 && he->h_addr_list[0]) memcpy (&host, he->h_addr_list[0], 4); //sa->sin_family = he->h_addrtype; else slog (L_NOTICE, _("unable to resolve host '%s'"), hostname); } } void sockinfo::set (const conf_node *conf, u8 prot_) { if (prot_ == PROT_DNSv4) { host = htonl (conf->id); port = 0; prot = prot_; } else set (conf->hostname, prot_ == PROT_UDPv4 ? conf->udp_port : prot_ == PROT_TCPv4 ? conf->tcp_port : prot_ == PROT_DNSv4 ? conf->dns_port : 0, prot_); } const sockaddr * sockinfo::sav4() const { static sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_port = port; sa.sin_addr.s_addr = host; return (const sockaddr *)&sa; } static char hostport[10 + 15 + 1 + 5 + 1]; // proto / IPv4 : port const char * sockinfo::ntoa () const { in_addr ia = { host }; sprintf (hostport, "%.15s", inet_ntoa (ia)); return hostport; } bool sockinfo::valid () const { return (prot & THISNODE->protocols) && host; } sockinfo::operator const char *() const { in_addr ia = { host }; sprintf (hostport, "%s/%.15s:%d", strprotocol (prot), inet_ntoa (ia), ntohs (port) & 0xffff); return hostport; } u8 sockinfo::supported_protocols (conf_node *conf) { u8 protocols = prot; if (prot & (PROT_IPv4 | PROT_ICMPv4 | PROT_UDPv4 | PROT_TCPv4)) protocols |= PROT_IPv4 | PROT_ICMPv4; if (conf && prot & PROTv4) { if (conf->protocols & PROT_UDPv4 && conf->udp_port) protocols |= PROT_UDPv4; if (conf->protocols & PROT_TCPv4 && conf->tcp_port) protocols |= PROT_TCPv4; if (conf->protocols & PROT_DNSv4 && conf->dns_port) protocols |= PROT_DNSv4; } return protocols; } bool sockinfo::upgrade_protocol (u8 prot_, conf_node *conf) { if (prot_ == prot) return true; if (prot & PROTv4 && prot_ & PROTv4) { if (prot_ & (PROT_IPv4 | PROT_ICMPv4)) { prot = prot_; port = 0; return true; } if (conf && prot_ & PROT_UDPv4 && conf->protocols & PROT_UDPv4 && conf->udp_port) { prot = prot_; port = htons (conf->udp_port); return true; } if (conf && prot_ & PROT_TCPv4 && conf->protocols & PROT_TCPv4 && conf->tcp_port) { prot = prot_; port = htons (conf->tcp_port); return true; } } return false; } bool operator == (const sockinfo &a, const sockinfo &b) { return a.host == b.host && a.port == b.port && a.prot == b.prot; } bool operator < (const sockinfo &a, const sockinfo &b) { return a.host < b.host || (a.host == b.host && (a.port < b.port || (a.port == b.port && a.prot < b.prot))); } gvpe-3.0/src/curve25519.h0000644000000000000000000000326012615056110011674 00000000000000/* curve25519.h -- diffie hellman key exchange Copyright (C) 2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef CURVE25519_H__ #define CURVE25519_H__ #define CURVE25519_SIZE 32 typedef unsigned char curve25519_key[CURVE25519_SIZE]; void curve25519_generate (curve25519_key &a, curve25519_key &b); void curve25519_combine (const curve25519_key &a, const curve25519_key &b, curve25519_key &s); void curve25519_verify (); #endif gvpe-3.0/src/curve25519.C0000644000000000000000000000730312615056110011631 00000000000000/* curve25519.C -- diffie hellman key exchange Copyright (C) 2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include "util.h" #include "curve25519.h" #if __GNUC__ >= 4 && __SIZEOF_LONG__ == 8 #include "curve25519-donna-c64.c" #else #include "curve25519-donna.c" #endif static void curve25519_derive (const curve25519_key &a, curve25519_key &b) { static const curve25519_key basepoint = { 9 }; curve25519_donna (b, a, basepoint); } void curve25519_generate (curve25519_key &a, curve25519_key &b) { rand_fill (a); #if 0 a [ 0] &= 0xf8; a [31] &= 0x7f; a [31] |= 0x40; #endif curve25519_derive (a, b); } void curve25519_combine (const curve25519_key &a, const curve25519_key &b, curve25519_key &s) { curve25519_donna (s, a, b); } void curve25519_verify () { // NaCl test vector static const curve25519_key alice_private = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a }; static const curve25519_key alice_public = { 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a }; static const curve25519_key bob_private = { 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb }; static const curve25519_key bob_public = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f }; static const curve25519_key alice_mult_bob = { 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e, 0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42 }; curve25519_key a, b, s1, s2; curve25519_derive (alice_private, a); curve25519_derive (bob_private , b); curve25519_combine (alice_private, b, s1); curve25519_combine (bob_private , a, s2); require (!memcmp (alice_public , a , sizeof a )); require (!memcmp (bob_public , b , sizeof b )); require (!memcmp (alice_mult_bob, s1, sizeof s1)); require (!memcmp (alice_mult_bob, s2, sizeof s2)); } gvpe-3.0/src/iv_gen.h0000644000000000000000000000321512615056110011411 00000000000000/* iv_gen.h -- efficiently generate IV values using AES Copyright (C) 2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef IV_GEN_H__ #define IV_GEN_H__ #include "global.h" #include #if 0 // only good for up to 2**31 sequence numbers struct iv_gen { AES_KEY ctx; u32 count; // low 32 bit of counter value void reset (); void get (void *buf, int len); }; #endif #endif gvpe-3.0/src/iv_gen.C0000644000000000000000000000406112615056110011344 00000000000000/* iv_gen.C -- efficiently generate IV values using AES Copyright (C) 2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include "util.h" #include "iv_gen.h" #if 0 void iv_gen::reset () { u8 key[128/8]; rand_fill (key); require (AES_set_encrypt_key (key, 128, &ctx) >= 0); rand_fill (count); } void iv_gen::get (void *buf, int len) { u8 *ptr = (u8 *)buf; // we currently do not reuse partial blocks for (;;) { u32 block[4] = { 0x5c5c5c5c, 0x36363636, 0x88442211, ++count }; AES_encrypt ((u8 *)block, (u8 *)block, &ctx); if (len <= AES_BLOCK_SIZE) { memcpy (ptr, block, len); return; } memcpy (ptr, block, AES_BLOCK_SIZE); ptr += AES_BLOCK_SIZE; len -= AES_BLOCK_SIZE; } } #endif gvpe-3.0/src/hkdf.h0000644000000000000000000000347612735244447011106 00000000000000/* hkdf.h -- RFC 5869 HKDF implementation Copyright (C) 2013,2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef HKDF_H__ #define HKDF_H__ #include "global.h" #include "crypto.h" // see RFC5869 struct hkdf { hmac ctx; u8 prk[EVP_MAX_MD_SIZE]; const void *salt; int salt_len; hkdf (const void *salt = 0, int len = 0, const EVP_MD *xtr_hash = EVP_sha512 ()); void extract (const void *ikm, int len); void extract_done (const EVP_MD *prf_hash = 0); void expand (void *okm, int len, const void *info = 0, int infolen = 0); static void verify (); }; #endif gvpe-3.0/src/hkdf.C0000644000000000000000000001554512735244315011033 00000000000000/* hkdf.C -- RFC 5869 HKDF implementation Copyright (C) 2013,2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include "crypto.h" #include "util.h" #include "hkdf.h" hkdf::hkdf (const void *salt, int len, const EVP_MD *xtr_hash) : salt (salt), salt_len (len) { ctx.init (salt, salt_len, xtr_hash); } void hkdf::extract (const void *ikm, int len) { ctx.add (ikm, len); } void hkdf::extract_done (const EVP_MD *prf_hash) { ctx.digest (prk); ctx.init (salt, salt_len, prf_hash); } void hkdf::expand (void *okm, int len, const void *info, int infolen) { u8 tn[sizeof prk]; u8 iter = 0; int md_size = ctx.size (); while (len) { ctx.init (prk, md_size); if (iter) ctx.add (tn, md_size); ctx.add (info, infolen); ++iter; require (iter); ctx.add (&iter, 1); ctx.digest (tn); int ol = len > md_size ? md_size : len; memcpy (okm, tn, ol); okm = (void *)(ol + (char *)okm); len -= ol; } } // try to verify all test vectors from the RFC // since I implemented the hkdf myself, and I am no crypto expert, // we run verification on every startup. void hkdf::verify () { struct unhex { u8 *p; int l; u8 s[256]; unhex (const char *hs) { l = 0; p = s; if (!hs) return; while (*hs) { int d1 = *hs >= '0' && *hs <= '9' ? *hs - '0' : *hs - 'a' + 10; ++hs; int d2 = *hs >= '0' && *hs <= '9' ? *hs - '0' : *hs - 'a' + 10; ++hs; *p++ = d1 * 16 + d2; ++l; } p = s; } }; const struct hkdf_test { int hash; const char *IKM, *salt, *info; const char *PRK, *OKM; } tests[] = { { // 0 256, "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "077709362c2e32df0ddc3f0dc47bba63" "90b6c73bb50f9c3122ec844ad7c2b3e5", "3cb25f25faacd57a90434f64d0362f2a" "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" "34007208d5b887185865" }, { // 1 256, "000102030405060708090a0b0c0d0e0f" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" "303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f" "707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f" "909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "06a6b88c5853361a06104c9ceb35b45c" "ef760014904671014a193f40c15fc244", "b11e398dc80327a1c8e7f78c596a4934" "4f012eda2d4efad8a050cc4c19afa97c" "59045a99cac7827271cb41c65e590e09" "da3275600c2f09b8367793a9aca3db71" "cc30c58179ec3e87c14c01d5c1f3434f" "1d87" }, { // 2 256, "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "19ef24a32c717b167f33a91d6f648bdf" "96596776afdb6377ac434c1c293ccb04", "8da4e775a563c18f715f802a063c5a31" "b8a11f5c5ee1879ec3454e5f3c738d2d" "9d201395faa4b61a96c8" }, { // 3 1, "0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243", "085a01ea1b10f36933068b56efa5ad81" "a4f14b822f5b091568a9cdd4f155fda2" "c22e422478d305f3f896" }, { // 4 1, "000102030405060708090a0b0c0d0e0f" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" "303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f" "707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f" "909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "8adae09a2a307059478d309b26c4115a224cfaf6", "0bd770a74d1160f7c9f12cd5912a06eb" "ff6adcae899d92191fe4305673ba2ffe" "8fa3f1a4e5ad79f3f334b3b202b2173c" "486ea37ce3d397ed034c7f9dfeb15c5e" "927336d0441f4c4300e2cff0d0900b52" "d3b4" }, { // 5 1, "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01", "0ac1af7002b3d761d1e55298da9d0506" "b9ae52057220a306e07b6b87e8df21d0" "ea00033de03984d34918" }, { // 6 1, "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", 0, "", "2adccada18779e7c2077ad2eb19d3f3e731385dd", "2c91117204d745f3500d636a62f64f0a" "b3bae548aa53d423b0d1f27ebba6f5e5" "673a081d70cce7acfc48" } }; for (int i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) { const hkdf_test &test = tests[i]; unhex salt (test.salt); unhex ikm (test.IKM); unhex info (test.info); unhex prk_correct (test.PRK); unhex okm_correct (test.OKM); char okm[256]; hkdf h (salt.p, salt.l, test.hash == 1 ? EVP_sha1 () : EVP_sha256 ()); h.extract (ikm.p, ikm.l); h.extract_done (); h.expand (okm, okm_correct.l, info.p, info.l); require (!memcmp (h.prk, prk_correct.p, prk_correct.l)); require (!memcmp (okm , okm_correct.p, okm_correct.l)); } } gvpe-3.0/src/connection.h0000644000000000000000000001555012735202336012314 00000000000000/* connection.h -- header for connection.C Copyright (C) 2003-2008,2013,2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_CONNECTION_H__ #define GVPE_CONNECTION_H__ #include #include "global.h" #include "conf.h" #include "sockinfo.h" #include "util.h" #include "device.h" #include "curve25519.h" #include "iv_gen.h" struct vpn; // called after HUP etc. to (re-)initialize global data structures void connection_init (); typedef curve25519_key ecdh_key; struct rsa_data { u32 seqno; // (ictx) initial sequence nr (31 bits) u8 mac_key[MAC_IKMSIZE]; // (ictx) used to generate hmac key u8 cipher_key[CIPHER_IKMSIZE]; // (ictx) used to generate cipher key u8 hkdf_salt[HKDF_SALT]; // (octx) used as hkdf salt u8 extra_auth[ // (ictx) additional auth randomness (RSABITS >> 3) - RSA_OAEP_SIZE - sizeof (u32) // seqno - MAC_IKMSIZE - CIPHER_IKMSIZE - HKDF_SALT - 3 // struct alignment... ]; }; struct auth_data { rsa_data rsa; ecdh_key ecdh; }; typedef u8 rsa_crypt[RSA_KEYLEN]; // encrypted challenge struct auth_encr { rsa_crypt rsa; ecdh_key ecdh; }; typedef u8 auth_mac[AUTH_SIZE]; struct auth_response { auth_mac mac; ecdh_key ecdh; }; //////////////////////////////////////////////////////////////////////////////////////// struct crypto_ctx; struct hmac_packet : net_packet { u8 hmac[HMACLENGTH]; // each and every packet has a hmac field, but that is not (yet) checked everywhere void hmac_set (crypto_ctx *ctx); bool hmac_chk (crypto_ctx *ctx); private: void hmac_gen (crypto_ctx *ctx, u8 *hmac_digest); }; struct vpn_packet : hmac_packet { enum ptype { PT_RESET = 0, PT_DATA_UNCOMPRESSED, PT_DATA_COMPRESSED, PT_PING, PT_PONG, // wasting namespace space? ;) PT_AUTH_REQ, // authentification request PT_AUTH_RES, // authentification response PT_CONNECT_REQ, // want other node to contact me PT_CONNECT_INFO, // request connection to some node PT_DATA_BRIDGED, // uncompressed packet with foreign mac pot. larger than path mtu (NYI) PT_MAX }; u8 type; u8 srcdst, src1, dst1; void set_hdr (ptype type_, unsigned int dst); unsigned int src () const { return src1 | ((srcdst >> 4) << 8); } unsigned int dst () const { return dst1 | ((srcdst & 0xf) << 8); } ptype typ () const { return (ptype) type; } }; //////////////////////////////////////////////////////////////////////////////////////// // a very simple fifo pkt-queue class pkt_queue { int i, j; int max_queue; double max_ttl; struct pkt { ev_tstamp tstamp; net_packet *pkt; } *queue; void expire_cb (ev::timer &w, int revents); ev::timer expire; public: void put (net_packet *p); net_packet *get (); bool empty () { return i == j; } pkt_queue (double max_ttl, int max_queue); ~pkt_queue (); }; enum { FEATURE_COMPRESSION = 0x01, FEATURE_ROHC = 0x02, FEATURE_BRIDGING = 0x04, }; struct connection { conf_node *conf; struct vpn *vpn; sockinfo si; // the current(!) destination ip to send packets to int retry_cnt; tstamp last_activity; // time of last packet received tstamp last_establish_attempt; //tstamp last_si_change; // time we last changed the socket address u32 oseqno; sliding_window iseqno; u8 protocol; u8 features; pkt_queue data_queue, vpn_queue; crypto_ctx *octx, *ictx; void generate_auth_data (); ev_tstamp auth_expire; // when the snd_* and *_ecdh values expire ev_tstamp hmac_error; // time of first hmac error in a series // send auth data - used for octx auth_data snd_auth; ecdh_key snd_ecdh_a; // the secret ecdh key we used for our request ecdh_key snd_ecdh_b; // the public ecdh key we received in the response bool have_snd_auth; // received response for our req // receive auth data - used for ictx auth_data rcv_auth; ecdh_key rcv_ecdh_a; // the secret ecdh key we used for our response ecdh_key rcv_ecdh_b; // the public ecdh key we sent in our response bool have_rcv_auth; // received auth from other side #if ENABLE_DNS struct dns_connection *dns; #endif enum conf_node::connectmode connectmode; u8 prot_minor; // minor number of other side void reset_si (); const sockinfo &forward_si (const sockinfo &si) const; void shutdown (); void connection_established (const sockinfo &rsi); void reset_connection (const char *reason); void establish_connection_cb (ev::timer &w, int revents); ev::timer establish_connection; void rekey_cb (ev::timer &w, int revents); ev::timer rekey; // next rekeying (actually current reset + reestablishing) void keepalive_cb (ev::timer &w, int revents); ev::timer keepalive; // next keepalive probe void send_connect_request (int id); void send_auth_request (const sockinfo &si, bool initiate); void send_auth_response (const sockinfo &si); void send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols); void send_reset (const sockinfo &dsi); void send_ping (const sockinfo &dsi, u8 pong = 0); void send_data_packet (tap_packet *pkt); void post_inject_queue (); void inject_data_packet (tap_packet *pkt); void inject_vpn_packet (vpn_packet *pkt, int tos = 0); // for forwarding void recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi); void send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos = 0); void script_init_env (const char *ext); void script_init_connect_env (); const char *script_node_up (); const char *script_node_change (); const char *script_node_down (); void dump_status (); connection (struct vpn *vpn, conf_node *conf); ~connection (); }; #endif gvpe-3.0/src/connection.C0000644000000000000000000011564412735204036012253 00000000000000/* connection.C -- manage a single connection Copyright (C) 2003-2008,2010,2011,2013,2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include "conf.h" #include "slog.h" #include "crypto.h" #include "device.h" #include "vpn.h" #include "connection.h" #include "hkdf.h" #include "netcompat.h" #define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic #define ULTRA_FAST 1 #define HLOG 15 #include "lzf/lzf.h" #include "lzf/lzf_c.c" #include "lzf/lzf_d.c" ////////////////////////////////////////////////////////////////////////////// static std::queue< std::pair > rs_queue; static ev::child rs_child_ev; namespace { void // c++ requires external linkage here, apparently :( rs_child_cb (ev::child &w, int revents) { w.stop (); if (rs_queue.empty ()) return; pid_t pid = run_script (*rs_queue.front ().first, false); if (pid) { w.set (pid); w.start (); } else slog (L_WARN, rs_queue.front ().second); delete rs_queue.front ().first; rs_queue.pop (); } }; // despite the fancy name, this is quite a hack static void run_script_queued (run_script_cb *cb, const char *warnmsg) { rs_queue.push (std::make_pair (cb, warnmsg)); if (!rs_child_ev.is_active ()) { rs_child_ev.set (); rs_child_ev (); } } ////////////////////////////////////////////////////////////////////////////// struct crypto_ctx { cipher cctx; hmac hctx; crypto_ctx (const auth_data &auth1, const auth_data &auth2, const ecdh_key &a, const ecdh_key &b, int enc); ~crypto_ctx (); }; crypto_ctx::crypto_ctx (const auth_data &auth1, const auth_data &auth2, const ecdh_key &a, const ecdh_key &b, int enc) { ecdh_key s; curve25519_combine (a, b, s); { u8 mac_key[MAC_KEYSIZE]; static const unsigned char mac_info[] = "gvpe mac key"; hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ()); kdf.extract (auth1.rsa.mac_key, sizeof (auth1.rsa.mac_key)); kdf.extract (s, sizeof (s)); kdf.extract_done (HKDF_PRF_HASH ()); kdf.expand (mac_key, sizeof (mac_key), mac_info, sizeof (mac_info)); hctx.init (mac_key, MAC_KEYSIZE, MAC_DIGEST ()); } { u8 cipher_key[CIPHER_KEYSIZE]; static const unsigned char cipher_info[] = "gvpe cipher key"; hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ()); kdf.extract (auth1.rsa.cipher_key, sizeof (auth1.rsa.cipher_key)); kdf.extract (s, sizeof (s)); kdf.extract_done (HKDF_PRF_HASH ()); kdf.expand (cipher_key, sizeof (cipher_key), cipher_info, sizeof (cipher_info)); EVP_CIPHER_CTX_init (cctx); require (EVP_CipherInit_ex (cctx, CIPHER (), 0, cipher_key, 0, enc)); } } crypto_ctx::~crypto_ctx () { require (EVP_CIPHER_CTX_cleanup (cctx)); } static inline void auth_encrypt (RSA *key, const auth_data &auth, auth_encr &encr) { if (RSA_public_encrypt (sizeof (auth.rsa), (unsigned char *)&auth.rsa, (unsigned char *)&encr.rsa, key, RSA_PKCS1_OAEP_PADDING) < 0) fatal ("RSA_public_encrypt error"); memcpy (&encr.ecdh, &auth.ecdh, sizeof (encr.ecdh)); } static inline bool auth_decrypt (RSA *key, const auth_encr &encr, auth_data &auth) { u8 rsa_decrypt[RSA_KEYLEN]; if (RSA_private_decrypt (sizeof (encr.rsa), (const unsigned char *)&encr.rsa, (unsigned char *)rsa_decrypt, key, RSA_PKCS1_OAEP_PADDING) != sizeof (auth.rsa)) return 0; memcpy (&auth.rsa, rsa_decrypt, sizeof (auth.rsa)); memcpy (&auth.ecdh, &encr.ecdh, sizeof (auth.ecdh)); return 1; } static void auth_hash (const auth_data &auth, const ecdh_key &b, auth_mac &mac) { hkdf kdf (b, sizeof b, AUTH_DIGEST ()); // use response ecdh b as salt kdf.extract (&auth.rsa, sizeof (auth.rsa)); kdf.extract_done (); kdf.expand (mac, sizeof mac, auth.ecdh, sizeof (auth.ecdh)); // use challenge ecdh b as info } void connection::generate_auth_data () { if (auth_expire < ev_now ()) { // request data rand_fill (snd_auth.rsa); curve25519_generate (snd_ecdh_a, snd_auth.ecdh); // eventual response data curve25519_generate (rcv_ecdh_a, rcv_ecdh_b); } // every use prolongs the expiry auth_expire = ev_now () + AUTH_TTL; } ////////////////////////////////////////////////////////////////////////////// pkt_queue::pkt_queue (double max_ttl, int max_queue) : max_ttl (max_ttl), max_queue (max_queue) { queue = new pkt [max_queue]; i = 0; j = 0; expire.set (this); } pkt_queue::~pkt_queue () { while (net_packet *p = get ()) delete p; delete [] queue; } void pkt_queue::expire_cb (ev::timer &w, int revents) { ev_tstamp expire = ev_now () - max_ttl; for (;;) { if (empty ()) break; double diff = queue[j].tstamp - expire; if (diff >= 0.) { w.start (diff > 0.5 ? diff : 0.5); break; } delete get (); } } void pkt_queue::put (net_packet *p) { ev_tstamp now = ev_now (); // start expiry timer if (empty ()) expire.start (max_ttl); int ni = i + 1 == max_queue ? 0 : i + 1; if (ni == j) delete get (); queue[i].pkt = p; queue[i].tstamp = now; i = ni; } net_packet * pkt_queue::get () { if (empty ()) return 0; net_packet *p = queue[j].pkt; queue[j].pkt = 0; j = j + 1 == max_queue ? 0 : j + 1; return p; } struct net_rateinfo { u32 host; double pcnt, diff; tstamp last; }; // only do action once every x seconds per host whole allowing bursts. // this implementation ("splay list" ;) is inefficient, // but low on resources. struct net_rate_limiter : list { # define NRL_ALPHA (1. - 1. / 600.) // allow bursts # define NRL_CUTOFF 10. // one event every CUTOFF seconds # define NRL_EXPIRE (NRL_CUTOFF * 30.) // expire entries after this time # define NRL_MAXDIF (NRL_CUTOFF * (1. / (1. - NRL_ALPHA))) // maximum diff /count value bool can (const sockinfo &si) { return can((u32)si.host); } bool can (u32 host); }; static net_rate_limiter auth_rate_limiter, reset_rate_limiter; bool net_rate_limiter::can (u32 host) { iterator i; for (i = begin (); i != end (); ) if (i->host == host) break; else if (i->last < ev_now () - NRL_EXPIRE) i = erase (i); else i++; if (i == end ()) { net_rateinfo ri; ri.host = host; ri.pcnt = 1.; ri.diff = NRL_MAXDIF; ri.last = ev_now (); push_front (ri); return true; } else { net_rateinfo ri (*i); erase (i); ri.pcnt = ri.pcnt * NRL_ALPHA; ri.diff = ri.diff * NRL_ALPHA + (ev_now () - ri.last); ri.last = ev_now (); double dif = ri.diff / ri.pcnt; bool send = dif > NRL_CUTOFF; if (dif > NRL_MAXDIF) { ri.pcnt = 1.; ri.diff = NRL_MAXDIF; } else if (send) ri.pcnt++; push_front (ri); return send; } } ///////////////////////////////////////////////////////////////////////////// void hmac_packet::hmac_gen (crypto_ctx *ctx, u8 *hmac_digest) { ctx->hctx.init (); ctx->hctx.add (((unsigned char *) this) + sizeof (hmac_packet), len - sizeof (hmac_packet)); ctx->hctx.digest (hmac_digest); } void hmac_packet::hmac_set (crypto_ctx *ctx) { unsigned char hmac_digest[EVP_MAX_MD_SIZE]; hmac_gen (ctx, hmac_digest); memcpy (hmac, hmac_digest, HMACLENGTH); } bool hmac_packet::hmac_chk (crypto_ctx *ctx) { unsigned char hmac_digest[EVP_MAX_MD_SIZE]; hmac_gen (ctx, hmac_digest); return slow_memeq (hmac, hmac_digest, HMACLENGTH); } void vpn_packet::set_hdr (ptype type_, unsigned int dst) { type = type_; int src = THISNODE->id; src1 = src; srcdst = ((src >> 8) << 4) | (dst >> 8); dst1 = dst; } #define MAXVPNDATA (MAX_MTU - 6 - 6) struct vpndata_packet : vpn_packet { u32 ctr; // seqno u8 data[MAXVPNDATA]; void setup (connection *conn, int dst, u8 *d, u32 len, u32 seqno); tap_packet *unpack (connection *conn, u32 &seqno); private: const u32 data_hdr_size () const { // the distance from beginning of packet to data member return data - at (0); } }; // expands packet counter (unlike seqno, in network byte order) to counter mode IV static unsigned char * expand_iv (u32 ctr) { static u32 iv[IV_SIZE (CIPHER) / 4]; require (sizeof (iv) == 4 * 4); require (IV_SIZE (CIPHER) % 4 == 0); iv[0] = iv[1] = iv[2] = ctr; // I would reuse ctr here to to avoid potential endianness issues, // but it seems openssl wraps around. While this would be still ok, // and I don't even know if its true, let's play safe and initialise // to 0. iv[3] = 0; return (unsigned char *)iv; } void vpndata_packet::setup (connection *conn, int dst, u8 *d, u32 l, u32 seqno) { EVP_CIPHER_CTX *cctx = conn->octx->cctx; int outl = 0, outl2; ptype type = PT_DATA_UNCOMPRESSED; #if ENABLE_COMPRESSION u8 cdata[MAX_MTU]; if (conn->features & FEATURE_COMPRESSION) { u32 cl = lzf_compress (d, l, cdata + 2, (l - 2) & ~7); if (cl) { type = PT_DATA_COMPRESSED; d = cdata; l = cl + 2; d[0] = cl >> 8; d[1] = cl; } } #endif ctr = htonl (seqno); require (EVP_EncryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr))); require (EVP_EncryptUpdate (cctx, (unsigned char *)data + outl, &outl2, (unsigned char *)d, l)); outl += outl2; // it seems this is a nop for us, but we do it anyways require (EVP_EncryptFinal_ex (cctx, (unsigned char *)data + outl, &outl2)); outl += outl2; len = data_hdr_size () + outl; set_hdr (type, dst); hmac_set (conn->octx); } tap_packet * vpndata_packet::unpack (connection *conn, u32 &seqno) { EVP_CIPHER_CTX *cctx = conn->ictx->cctx; int outl = 0, outl2; tap_packet *p = new tap_packet; u8 *d; seqno = ntohl (ctr); require (EVP_DecryptInit_ex (cctx, 0, 0, 0, expand_iv (ctr))); #if ENABLE_COMPRESSION u8 cdata[MAX_MTU]; if (type == PT_DATA_COMPRESSED) d = cdata; else #endif d = &(*p)[6 + 6]; // this can overwrite the len/dst/src fields require (EVP_DecryptUpdate (cctx, d, &outl2, (unsigned char *)&data, len - data_hdr_size ())); outl += outl2; // it seems this is a nop for us, but we do it anyways require (EVP_DecryptFinal_ex (cctx, (unsigned char *)d + outl, &outl2)); outl += outl2; id2mac (dst () ? dst() : THISNODE->id, p->dst); id2mac (src (), p->src); #if ENABLE_COMPRESSION if (type == PT_DATA_COMPRESSED) { u32 cl = (d[0] << 8) | d[1]; p->len = lzf_decompress (d + 2, cl < MAX_MTU - 2 ? cl : 0, &(*p)[6 + 6], MAX_MTU) + 6 + 6; } else p->len = outl + (6 + 6); #endif return p; } struct ping_packet : vpn_packet { void setup (int dst, ptype type) { set_hdr (type, dst); len = sizeof (*this) - sizeof (net_packet); } }; struct config_packet : vpn_packet { u8 serial[SERIAL_SIZE]; u8 prot_major, prot_minor, randsize; u8 flags, features, pad6, pad7, pad8; u32 cipher_nid, mac_nid, auth_nid; void setup (ptype type, int dst); bool chk_config (const conf_node *conf, const sockinfo &rsi) const; static u8 get_features () { u8 f = 0; #if ENABLE_COMPRESSION f |= FEATURE_COMPRESSION; #endif #if ENABLE_ROHC f |= FEATURE_ROHC; #endif #if ENABLE_BRIDGING f |= FEATURE_BRIDGING; #endif return f; } }; void config_packet::setup (ptype type, int dst) { prot_major = PROTOCOL_MAJOR; prot_minor = PROTOCOL_MINOR; flags = 0; features = get_features (); strncpy ((char *)serial, conf.serial, sizeof (serial)); cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ())); mac_nid = htonl (EVP_MD_type (MAC_DIGEST ())); auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ())); len = sizeof (*this) - sizeof (net_packet); set_hdr (type, dst); } bool config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const { if (prot_major != PROTOCOL_MAJOR) slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"), conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR); else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"), conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"), conf->nodename, (const char *)rsi, ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ())); else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ()))) slog (L_WARN, _("%s(%s): auth algo mismatch (remote %x <=> local %x)"), conf->nodename, (const char *)rsi, ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ())); else { int cmp = memcmp (serial, ::conf.serial, sizeof (serial)); if (cmp > 0) slog (L_WARN, _("%s(%s): remote serial newer than local serial - outdated config?"), conf->nodename, (const char *)rsi); else if (cmp == 0) return true; } return false; } struct auth_req_packet : config_packet // UNPROTECTED { char magic[8]; u8 initiate; // false if this is just an automatic reply u8 protocols; // supported protocols (will be patched on forward) u8 pad2, pad3; auth_encr encr; auth_req_packet (int dst, bool initiate_, u8 protocols_) { config_packet::setup (PT_AUTH_REQ, dst); memcpy (magic, MAGIC, 8); initiate = !!initiate_; protocols = protocols_; len = sizeof (*this) - sizeof (net_packet); } }; struct auth_res_packet : vpn_packet // UNPROTECTED { auth_response response; auth_res_packet (int dst) { set_hdr (PT_AUTH_RES, dst); len = sizeof (*this) - sizeof (net_packet); } }; struct connect_req_packet : vpn_packet { u8 id, protocols; u8 pad1, pad2; connect_req_packet (int dst, int id_, u8 protocols_) : id(id_) , protocols(protocols_) { set_hdr (PT_CONNECT_REQ, dst); len = sizeof (*this) - sizeof (net_packet); } }; struct connect_info_packet : vpn_packet { u8 id, protocols; u8 pad1, pad2; sockinfo si; connect_info_packet (int dst, int id_, const sockinfo &si_, u8 protocols_) : id(id_) , protocols(protocols_) , si(si_) { set_hdr (PT_CONNECT_INFO, dst); len = sizeof (*this) - sizeof (net_packet); } }; ///////////////////////////////////////////////////////////////////////////// void connection::connection_established (const sockinfo &rsi) { if (!have_snd_auth || !have_rcv_auth) return; si = rsi; protocol = rsi.prot; slog (L_INFO, _("%s(%s): connection established (%s), protocol version %d.%d."), conf->nodename, (const char *)rsi, vpn->can_direct (THISNODE, conf) ? "direct" : "forwarded", PROTOCOL_MAJOR, prot_minor); if (::conf.script_node_up) { run_script_cb *cb = new run_script_cb; cb->set (this); run_script_queued (cb, _("node-up command execution failed, continuing.")); } delete ictx; ictx = new crypto_ctx (rcv_auth, snd_auth, rcv_ecdh_a, rcv_auth.ecdh, 0); iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff); delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1); oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff; // make sure rekeying timeouts are slightly asymmetric ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0); rekey.start (rekey_interval, rekey_interval); hmac_error = 0.; keepalive.start (::conf.keepalive); // send queued packets while (tap_packet *p = (tap_packet *)data_queue.get ()) { if (p->len) send_data_packet (p); delete p; } while (vpn_packet *p = (vpn_packet *)vpn_queue.get ()) { if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY); delete p; } vpn->connection_established (this); } void connection::reset_si () { if (vpn->can_direct (THISNODE, conf)) protocol = best_protocol (THISNODE->protocols & conf->connectable_protocols ()); else { slog (L_TRACE, _("%s: direct connection denied by config."), conf->nodename); protocol = 0; } si.set (conf, protocol); } // ensure sockinfo is valid, forward if necessary const sockinfo & connection::forward_si (const sockinfo &si) const { if (!si.valid ()) { connection *r = vpn->find_router_for (this); if (r) { slog (L_DEBUG, _("%s: no common protocol, trying to route through %s."), conf->nodename, r->conf->nodename); return r->si; } else slog (L_DEBUG, _("%s: node unreachable, no common protocol or no router available."), conf->nodename); } return si; } void connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) { if (!vpn->send_vpn_packet (pkt, si, tos)) reset_connection ("packet send error"); } void connection::send_ping (const sockinfo &si, u8 pong) { ping_packet *pkt = new ping_packet; pkt->setup (conf->id, pong ? ping_packet::PT_PONG : ping_packet::PT_PING); slog (L_TRACE, "%s << %s [%s]", conf->nodename, pong ? "PT_PONG" : "PT_PING", (const char *)si); send_vpn_packet (pkt, si, IPTOS_LOWDELAY); delete pkt; } void connection::send_reset (const sockinfo &si) { if (reset_rate_limiter.can (si) && connectmode != conf_node::C_DISABLED) { config_packet *pkt = new config_packet; pkt->setup (vpn_packet::PT_RESET, conf->id); send_vpn_packet (pkt, si, IPTOS_MINCOST); delete pkt; } } void connection::send_auth_request (const sockinfo &si, bool initiate) { auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); generate_auth_data (); auth_encrypt (conf->rsa_key, snd_auth, pkt->encr); slog (L_TRACE, "%s << PT_AUTH_REQ [%s]", conf->nodename, (const char *)si); send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly delete pkt; } void connection::send_auth_response (const sockinfo &si) { auth_res_packet *pkt = new auth_res_packet (conf->id); memcpy (pkt->response.ecdh, rcv_ecdh_b, sizeof rcv_ecdh_b); auth_hash (rcv_auth, rcv_ecdh_b, pkt->response.mac); slog (L_TRACE, "%s << PT_AUTH_RES [%s]", conf->nodename, (const char *)si); send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly delete pkt; } void connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols) { slog (L_TRACE, "%s << PT_CONNECT_INFO(%s,%s,p%02x)", conf->nodename, vpn->conns[rid - 1]->conf->nodename, (const char *)rsi, conf->protocols); connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); r->hmac_set (octx); send_vpn_packet (r, si); delete r; } inline void connection::establish_connection_cb (ev::timer &w, int revents) { if (!(ictx && octx) && conf != THISNODE && connectmode != conf_node::C_NEVER && connectmode != conf_node::C_DISABLED && !w.is_active ()) { // a bit hacky, if ondemand, and packets are no longer queued, then reset the connection // and stop trying. should probably be handled by a per-connection expire handler. if (connectmode == conf_node::C_ONDEMAND && vpn_queue.empty () && data_queue.empty ()) { reset_connection ("no demand"); return; } last_establish_attempt = ev_now (); ev::tstamp retry_int = ev::tstamp (retry_cnt & 3 ? (retry_cnt & 3) + 1 : 1 << (retry_cnt >> 2)); reset_si (); bool slow = (si.prot & PROT_SLOW) || (conf->low_power || THISNODE->low_power); if (si.prot && !si.host && vpn->can_direct (THISNODE, conf)) { /*TODO*/ /* start the timer so we don't recurse endlessly */ w.start (1); vpn->send_connect_request (this); } else { if (si.valid ()) slog (L_DEBUG, _("%s: sending direct connection request to %s."), conf->nodename, (const char *)si); const sockinfo &dsi = forward_si (si); slow = slow || (dsi.prot & PROT_SLOW); if (dsi.valid () && auth_rate_limiter.can (dsi)) { // use ping after the first few retries // TODO: on rekeys, the other node might not interpret ping correctly, // TODO: as it will still have a valid connection if (retry_cnt < 4 && (!conf->low_power || THISNODE->low_power)) send_auth_request (dsi, true); else send_ping (dsi, 0); } } retry_int *= slow ? 4. : 0.9; if (retry_int < conf->max_retry) retry_cnt++; else retry_int = conf->max_retry; w.start (retry_int); } } void connection::reset_connection (const char *reason) { if (ictx && octx) { slog (L_INFO, _("%s(%s): connection lost (%s)"), conf->nodename, (const char *)si, reason); if (::conf.script_node_down) { run_script_cb *cb = new run_script_cb; cb->set (this); run_script_queued (cb, _("node-down command execution failed, continuing.")); } } delete ictx; ictx = 0; delete octx; octx = 0; si.host = 0; have_snd_auth = false; have_rcv_auth = false; auth_expire = 0.; last_activity = 0.; //last_si_change = 0.; retry_cnt = 0; rekey.stop (); keepalive.stop (); establish_connection.stop (); } void connection::shutdown () { if (ictx && octx) send_reset (si); reset_connection ("shutdown"); } // poor-man's rekeying inline void connection::rekey_cb (ev::timer &w, int revents) { reset_connection ("rekeying"); establish_connection (); } void connection::send_data_packet (tap_packet *pkt) { vpndata_packet *p = new vpndata_packet; int tos = 0; // I am not hilarious about peeking into packets, but so be it. if (conf->inherit_tos && pkt->is_ipv4 ()) tos = (*pkt)[15] & IPTOS_TOS_MASK; p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs send_vpn_packet (p, si, tos); delete p; if (oseqno > MAX_SEQNO) rekey (); } void connection::post_inject_queue () { // force a connection every now and when when packets are sent (max 1/s) if (ev_now () - last_establish_attempt >= (conf->low_power || THISNODE->low_power ? 2.95 : 0.95)) // arbitrary establish_connection.stop (); establish_connection (); } void connection::inject_data_packet (tap_packet *pkt) { if (ictx && octx) send_data_packet (pkt); else { data_queue.put (new tap_packet (*pkt)); post_inject_queue (); } } void connection::inject_vpn_packet (vpn_packet *pkt, int tos) { if (ictx && octx) send_vpn_packet (pkt, si, tos); else { vpn_queue.put ((vpn_packet *)new data_packet (*(data_packet *)pkt)); post_inject_queue (); } } void connection::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) { last_activity = ev_now (); slog (L_NOISE, "%s >> received packet type %d from %d to %d.", conf->nodename, pkt->typ (), pkt->src (), pkt->dst ()); if (connectmode == conf_node::C_DISABLED) return; switch (pkt->typ ()) { case vpn_packet::PT_PING: slog (L_TRACE, "%s >> PT_PING", conf->nodename); // we send pings instead of auth packets after some retries, // so reset the retry counter and establish a connection // when we receive a ping. if (!ictx) { if (auth_rate_limiter.can (rsi)) send_auth_request (rsi, true); } else // we would love to change the socket address here, but ping's aren't // authenticated, so we best ignore it. send_ping (rsi, 1); // pong break; case vpn_packet::PT_PONG: slog (L_TRACE, "%s >> PT_PONG", conf->nodename); // a PONG might mean that the other side doesn't really know // about our desire for communication. establish_connection (); break; case vpn_packet::PT_RESET: slog (L_TRACE, "%s >> PT_RESET", conf->nodename); if (ictx && octx) { reset_connection ("remote reset"); config_packet *p = (config_packet *) pkt; if (p->chk_config (conf, rsi) && connectmode == conf_node::C_ALWAYS) establish_connection (); } break; case vpn_packet::PT_AUTH_REQ: if (auth_rate_limiter.can (rsi)) { auth_req_packet *p = (auth_req_packet *)pkt; slog (L_TRACE, "%s >> PT_AUTH_REQ(%s,p%02x,f%02x)", conf->nodename, p->initiate ? "initiate" : "reply", p->protocols, p->features); if (memcmp (p->magic, MAGIC, 8)) { slog (L_WARN, _("%s(%s): protocol magic mismatch - stray packet?"), conf->nodename, (const char *)rsi); } else if (p->chk_config (conf, rsi)) { if (p->prot_minor != PROTOCOL_MINOR) slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), conf->nodename, (const char *)rsi, PROTOCOL_MINOR, conf->nodename, p->prot_minor); if (p->initiate) { send_auth_request (rsi, false); if (ictx && octx) reset_connection ("reconnect"); } auth_data auth; if (!auth_decrypt (::conf.rsa_key, p->encr, auth)) { slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"), conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0)); } else { bool chg = !have_rcv_auth || !slow_memeq (&rcv_auth, &auth, sizeof auth); rcv_auth = auth; have_rcv_auth = true; send_auth_response (rsi); if (chg) { conf->protocols = p->protocols; features = p->features & config_packet::get_features (); connection_established (rsi); } } break; } send_reset (rsi); } break; case vpn_packet::PT_AUTH_RES: { auth_res_packet *p = (auth_res_packet *)pkt; slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); auth_mac local_mac; auth_hash (snd_auth, p->response.ecdh, local_mac); if (!slow_memeq (&p->response.mac, local_mac, sizeof local_mac)) { slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), conf->nodename, (const char *)rsi); } else if (!have_snd_auth) { memcpy (snd_ecdh_b, p->response.ecdh, sizeof snd_ecdh_b); have_snd_auth = true; connection_established (rsi); } } break; case vpn_packet::PT_DATA_COMPRESSED: #if !ENABLE_COMPRESSION send_reset (rsi); break; #endif case vpn_packet::PT_DATA_UNCOMPRESSED: if (ictx && octx) { vpndata_packet *p = (vpndata_packet *)pkt; if (!p->hmac_chk (ictx)) { // rekeying often creates temporary hmac auth floods // we assume they don't take longer than a few seconds normally, // and suppress messages and resets during that time. //TODO: should be done per source address if (!hmac_error) { hmac_error = ev_now () + 3; break; } else if (hmac_error >= ev_now ()) break; // silently suppress else { slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n" "could be an attack, or just corruption or a synchronization error."), conf->nodename, (const char *)rsi); // reset } } else { u32 seqno; tap_packet *d = p->unpack (this, seqno); int seqclass = iseqno.seqno_classify (seqno); hmac_error = 0; if (seqclass == 0) // ok { vpn->tap->send (d); if (si != rsi) { // fast re-sync on source address changes, useful especially for tcp/ip //if (last_si_change < ev_now () + 5.) // { slog (L_INFO, _("%s(%s): changing socket address to %s."), conf->nodename, (const char *)si, (const char *)rsi); si = rsi; if (::conf.script_node_change) { run_script_cb *cb = new run_script_cb; cb->set (this); run_script_queued (cb, _("node-change command execution failed, continuing.")); } // } //else // slog (L_INFO, _("%s(%s): accepted packet from %s, not (yet) redirecting traffic."), // conf->nodename, (const char *)si, (const char *)rsi); } } else if (seqclass == 1) // far history slog (L_ERR, _("received very old packet (received %08lx, expected %08lx). " "possible replay attack, or just packet duplication/delay, ignoring."), seqno, iseqno.seq + 1); else if (seqclass == 2) // in-window duplicate, happens often on wireless slog (L_DEBUG, _("received recent duplicated packet (received %08lx, expected %08lx). " "possible replay attack, or just packet duplication, ignoring."), seqno, iseqno.seq + 1); else if (seqclass == 3) // reset { slog (L_ERR, _("received out-of-sync (far future) packet (received %08lx, expected %08lx). " "probably just massive packet loss, sending reset."), seqno, iseqno.seq + 1); send_reset (rsi); } delete d; break; } } send_reset (rsi); break; case vpn_packet::PT_CONNECT_REQ: if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) { connect_req_packet *p = (connect_req_packet *)pkt; if (p->id > 0 && p->id <= vpn->conns.size ()) { connection *c = vpn->conns[p->id - 1]; conf->protocols = p->protocols; slog (L_TRACE, "%s >> PT_CONNECT_REQ(%s,p%02x) [%d]", conf->nodename, vpn->conns[p->id - 1]->conf->nodename, p->protocols, c->ictx && c->octx); if (c->ictx && c->octx) { // send connect_info packets to both sides, in case one is // behind a nat firewall (or both ;) c->send_connect_info (conf->id, si, conf->protocols); send_connect_info (c->conf->id, c->si, c->conf->protocols); } else c->establish_connection (); } else slog (L_WARN, _("received authenticated connection request from unknown node #%d, config file mismatch?"), p->id); } break; case vpn_packet::PT_CONNECT_INFO: if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) { connect_info_packet *p = (connect_info_packet *)pkt; if (p->id > 0 && p->id <= vpn->conns.size ()) { connection *c = vpn->conns[p->id - 1]; c->conf->protocols = p->protocols; protocol = best_protocol (c->conf->protocols & THISNODE->protocols & p->si.supported_protocols (c->conf)); p->si.upgrade_protocol (protocol, c->conf); slog (L_TRACE, "%s >> PT_CONNECT_INFO(%s,%s,protocols=%02x,protocol=%02x,upgradable=%02x) [%d]", conf->nodename, vpn->conns[p->id - 1]->conf->nodename, (const char *)p->si, p->protocols, protocol, p->si.supported_protocols (c->conf), !c->ictx && !c->octx); const sockinfo &dsi = forward_si (p->si); if (dsi.valid ()) c->send_auth_request (dsi, true); else slog (L_INFO, "connect info for %s received (%s), but still unable to contact.", vpn->conns[p->id - 1]->conf->nodename, (const char *)p->si); } else slog (L_WARN, _("received authenticated connection request from unknown node #%d, config file mismatch?"), p->id); } break; default: send_reset (rsi); break; } } inline void connection::keepalive_cb (ev::timer &w, int revents) { ev_tstamp when = last_activity + ::conf.keepalive - ev::now (); if (when >= 0) w.start (when); else if (when < -15) { reset_connection ("keepalive overdue"); establish_connection (); } else if (conf->connectmode != conf_node::C_ONDEMAND || THISNODE->connectmode != conf_node::C_ONDEMAND) { w.start (3); send_ping (si); } else if (when >= -10) // hold ondemand connections implicitly a few seconds longer // should delete octx, though, or something like that ;) w.start (when + 10); else reset_connection ("keepalive timeout"); } void connection::send_connect_request (int id) { connect_req_packet *p = new connect_req_packet (conf->id, id, THISNODE->protocols); slog (L_TRACE, "%s << PT_CONNECT_REQ(%s,p%02x)", conf->nodename, vpn->conns[id - 1]->conf->nodename, THISNODE->protocols); p->hmac_set (octx); send_vpn_packet (p, si); delete p; } void connection::script_init_env (const char *ext) { char *env; asprintf (&env, "IFUPDATA%s=%s", ext, conf->if_up_data); putenv (env); asprintf (&env, "NODENAME%s=%s", ext, conf->nodename); putenv (env); asprintf (&env, "MAC%s=%02x:%02x:%02x:%02x:%02x:%02x", ext, 0xfe, 0xfd, 0x80, 0x00, conf->id >> 8, conf->id & 0xff); putenv (env); } void connection::script_init_connect_env () { vpn->script_init_env (); char *env; asprintf (&env, "DESTID=%d", conf->id); putenv (env); asprintf (&env, "DESTSI=%s", (const char *)si); putenv (env); asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env); asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env); asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env); } inline const char * connection::script_node_up () { script_init_connect_env (); putenv ((char *)"STATE=up"); char *filename; asprintf (&filename, "%s/%s", confbase, ::conf.script_node_up ? ::conf.script_node_up : "node-up"); return filename; } inline const char * connection::script_node_change () { script_init_connect_env (); putenv ((char *)"STATE=change"); char *filename; asprintf (&filename, "%s/%s", confbase, ::conf.script_node_change ? ::conf.script_node_change : "node-change"); return filename; } inline const char * connection::script_node_down () { script_init_connect_env (); putenv ((char *)"STATE=down"); char *filename; asprintf (&filename, "%s/%s", confbase, ::conf.script_node_down ? ::conf.script_node_down : "node-down"); return filename; } connection::connection (struct vpn *vpn, conf_node *conf) : vpn(vpn), conf(conf), #if ENABLE_DNS dns (0), #endif data_queue(conf->max_ttl, conf->max_queue + 1), vpn_queue(conf->max_ttl, conf->max_queue + 1) { rekey .set (this); keepalive .set (this); establish_connection.set (this); last_establish_attempt = 0.; octx = ictx = 0; connectmode = conf->connectmode; // queue a dummy packet to force an initial connection attempt if (connectmode != conf_node::C_ALWAYS && connectmode != conf_node::C_DISABLED) vpn_queue.put (new net_packet); reset_connection ("startup"); } connection::~connection () { shutdown (); } void connection_init () { auth_rate_limiter.clear (); reset_rate_limiter.clear (); } gvpe-3.0/src/callback.h0000644000000000000000000002415712615056110011706 00000000000000// THIS IS A GENERATED FILE: RUN callback.pl to regenerate it // THIS IS A GENERATED FILE: callback.pl is part of the GVPE // THIS IS A GENERATED FILE: distribution. /* * callback.h -- C++ callback mechanism * Copyright (C) 2003-2008 Marc Lehmann * * This file is part of GVPE. * * 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 3 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, see . * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with the OpenSSL project's OpenSSL library (or a modified * version of that library), containing parts covered by the terms of the * OpenSSL or SSLeay licenses, the licensors of this Program grant you * additional permission to convey the resulting work. Corresponding * Source for a non-source form of such a combination shall include the * source code for the parts of OpenSSL used as well as that of the * covered work. */ #ifndef CALLBACK_H__ #define CALLBACK_H__ #define CALLBACK_H_VERSION 3 template struct callback; template struct callback { typedef R (*ptr_type)(void *self); template void set (K *object) { self = object; func = thunk; } R call () const { return func (self); } R operator ()() const { return call (); } private: void *self; ptr_type func; template static R thunk (void *self) { klass *obj = static_cast(self); return (obj->*method) (); } }; template struct callback { typedef R (*ptr_type)(void *self, A1); template void set (K *object) { self = object; func = thunk; } R call (A1 a1) const { return func (self, a1); } R operator ()(A1 a1) const { return call (a1); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1) { klass *obj = static_cast(self); return (obj->*method) (a1); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2) const { return func (self, a1, a2); } R operator ()(A1 a1, A2 a2) const { return call (a1, a2); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2) { klass *obj = static_cast(self); return (obj->*method) (a1, a2); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3) const { return func (self, a1, a2, a3); } R operator ()(A1 a1, A2 a2, A3 a3) const { return call (a1, a2, a3); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4) const { return func (self, a1, a2, a3, a4); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) const { return call (a1, a2, a3, a4); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const { return func (self, a1, a2, a3, a4, a5); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const { return call (a1, a2, a3, a4, a5); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const { return func (self, a1, a2, a3, a4, a5, a6); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const { return call (a1, a2, a3, a4, a5, a6); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5, a6); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const { return func (self, a1, a2, a3, a4, a5, a6, a7); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const { return call (a1, a2, a3, a4, a5, a6, a7); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5, a6, a7); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const { return func (self, a1, a2, a3, a4, a5, a6, a7, a8); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const { return call (a1, a2, a3, a4, a5, a6, a7, a8); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const { return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const { return call (a1, a2, a3, a4, a5, a6, a7, a8, a9); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9); } }; template struct callback { typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); template void set (K *object) { self = object; func = thunk; } R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const { return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const { return call (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } private: void *self; ptr_type func; template static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) { klass *obj = static_cast(self); return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } }; #endif gvpe-3.0/src/device.h0000644000000000000000000000677212615056110011414 00000000000000/* device.h -- generic header for device.c Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_DEVICE_H__ #define GVPE_DEVICE_H__ #include "config.h" #define IFNAMESIZE 256 // be conservative #include "global.h" #include "util.h" struct net_packet { u32 len; // actually u16, but padding... u8 &operator[] (u16 offset) const; u8 *at (u16 offset) const; void unshift_hdr (u16 hdrsize) { memmove ((void *)&(*this)[hdrsize], (void *)&(*this)[0], len); len += hdrsize; } void skip_hdr (u16 hdrsize) { len -= hdrsize; memmove ((void *)&(*this)[0], (void *)&(*this)[hdrsize], len); } u16 ipv4_hdr_len () const { return ((*this)[0] & 15) << 2; } void set (const net_packet &pkt) { len = pkt.len; memcpy (&((*this)[0]), &(pkt[0]), len); } bool is_ipv4 () const { return (*this)[12] == 0x08 && (*this)[13] == 0x00 // IP && ((*this)[14] & 0xf0) == 0x40; // IPv4 } u32 &ipv4_src () const { return *(u32 *)&(*this)[26]; } u32 &ipv4_dst () const { return *(u32 *)&(*this)[30]; } bool is_arp () const { return (*this)[12] == 0x08 && (*this)[13] == 0x06 // 0806 protocol && (*this)[14] == 0x00 && (*this)[15] == 0x01 // 0001 hw_format && (*this)[16] == 0x08 && (*this)[17] == 0x00 // 0800 prot_format && (*this)[18] == 0x06 && (*this)[19] == 0x04; // 06 hw_len 04 prot_len } void *operator new (size_t s); void operator delete (void *p); }; struct data_packet : net_packet { u8 data_[MAXSIZE]; }; inline u8 &net_packet::operator[] (u16 offset) const { return ((data_packet *)this)->data_[offset]; } inline u8 *net_packet::at (u16 offset) const { return &((*this)[offset]); } struct tap_packet : net_packet { mac dst; mac src; u8 data[MAXSIZE - 12]; }; struct tap_device { int fd; // network interface name or identifier char ifrname[IFNAMESIZE + 1]; char *device; tap_device (); ~tap_device (); //bool open (); //void close (); const char *interface () { return ifrname; } const char *info (); const char *if_up (); tap_packet *recv (); void send (tap_packet *pkt); }; //extern tap_device *tap_device (); #endif gvpe-3.0/src/device.C0000644000000000000000000000477712615056110011352 00000000000000/* device.C -- include the correct low-level implementation. Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include "slog.h" #include "device.h" static void *pkt_cachep[PKTCACHESIZE]; static int pkt_cachen = 0; void * net_packet::operator new(size_t s) { if (s > sizeof (data_packet)) { slog (L_ERR, _("FATAL: allocation for network packet larger than max supported packet size (%d > %d)."), s, sizeof (data_packet)); abort (); } if (pkt_cachen) return pkt_cachep[--pkt_cachen]; else { void *p = malloc (sizeof (data_packet)); memset (p, 0, sizeof (data_packet)); return p; } } void net_packet::operator delete(void *p) { if (p) { if (pkt_cachen < PKTCACHESIZE) { memset (p, 0, sizeof (data_packet)); pkt_cachep[pkt_cachen++] = p; } else free (p); } } #if IFTYPE_tincd # include "device-tincd.C" #elif IFTYPE_native && IF_linux # include "device-linux.C" #elif IFTYPE_native && IF_cygwin # include "device-cygwin.C" #elif IFTYPE_native && IF_darwin # include "device-darwin.C" #else # error No interface implementation for your IFTYPE/IFSUBTYPE combination. #endif gvpe-3.0/src/global.h0000644000000000000000000001206012676647605011426 00000000000000/* global.h -- global variables and constants Copyright (C) 2003-2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GLOBAL_H__ #define GLOBAL_H__ #include "config.h" #include #define HASH_BITS(hash) hashbits_ ## hash #define HASH_SIZE(hash) (HASH_BITS (hash) >> 3) #define hashbits_EVP_ripemd160 160 #define hashbits_EVP_sha1 160 #define hashbits_EVP_sha224 224 #define hashbits_EVP_sha256 256 #define hashbits_EVP_sha384 384 #define hashbits_EVP_sha512 512 #define hashbits_EVP_whirlpool 512 #define KEY_BITS(cipher) keybits_ ## cipher #define KEY_SIZE(cipher) (KEY_BITS (cipher) >> 3) //#define keybits_EVP_bf_ctr 128 // actually 32-448 #define keybits_EVP_aes_128_ctr 128 #define keybits_EVP_aes_192_ctr 192 #define keybits_EVP_aes_256_ctr 256 #define BLOCK_BITS(cipher) blockbits_ ## cipher #define BLOCK_SIZE(cipher) (BLOCK_BITS (cipher) >> 3) //#define blockbits_EVP_bf_ctr 64 #define blockbits_EVP_aes_128_ctr 8 #define blockbits_EVP_aes_192_ctr 8 #define blockbits_EVP_aes_256_ctr 8 #define IV_BITS(cipher) ivbits_ ## cipher #define IV_SIZE(cipher) (IV_BITS (cipher) >> 3) //#define ivbits_EVP_bf_ctr 64 #define ivbits_EVP_aes_128_ctr 128 #define ivbits_EVP_aes_192_ctr 128 #define ivbits_EVP_aes_256_ctr 128 /* Protocol version. Different major versions are incompatible, * different minor versions probably are compatible ;) */ #define PROTOCOL_MAJOR 1 #define PROTOCOL_MINOR 0 #define SERIAL_SIZE 16 #define SEED_SIZE 64 // how many octets to seed rng with #define RSA_OAEP_SIZE 41 #define HKDF_XTR_HASH EVP_sha512 #define HKDF_PRF_HASH EVP_sha256 #define HKDF_SALT 24 // how many bytes for the hkdf salt #define RSA_KEYLEN (RSABITS >> 3) #define AUTH_DIGEST ENABLE_AUTH #define AUTH_SIZE (HASH_SIZE (AUTH_DIGEST)) #define AUTH_TTL 12 // challenge bytes timeout after n seconds of non-use #define CIPHER ENABLE_CIPHER #define CIPHER_KEYSIZE (KEY_SIZE (CIPHER)) #define CIPHER_IKMSIZE (CIPHER_KEYSIZE * 3 / 2) // randomness in rsa challenge #define MAC_DIGEST ENABLE_HMAC #define MAC_KEYSIZE HASH_SIZE (ENABLE_HMAC) // number of bits used for the HMAC key #define MAC_IKMSIZE (MAC_KEYSIZE * 3 / 2) // randomness in rsa challenge #define WINDOWSIZE 65536 // sliding window size #define MAX_SEQNO (0xfffffff0U - WINDOWSIZE * 8) // hdr seq len hmac MAC MAC #define VPE_OVERHEAD (4 + 4 + 4 + HMACLENGTH - 6 - 6) #define IP_OVERHEAD 20 // size of a (normal) ip header #define GRE_OVERHEAD (IP_OVERHEAD + 4) #define ICMP_OVERHEAD (IP_OVERHEAD + 4) #define UDP_OVERHEAD (IP_OVERHEAD + 20) // size of a (normal) ip + udp header (wrong, but don't care) #define TCP_OVERHEAD (IP_OVERHEAD + 22) // size of a (normal) ip + tcp header + packetlength #define MAX_OVERHEAD UDP_OVERHEAD // the max. overhead of any protocol (ok, tcp doesn't count) #define ETH_OVERHEAD 14 // the size of an ethernet header #define MAXSIZE (MAX_MTU + IP_OVERHEAD) // slightly too large, but who cares #define PKTCACHESIZE 128 // the size of the memory pool for packets extern char *confbase; // directory in which all config files are extern char *thisnode; // config for current node (TODO: remove) template static inline T min (T a, U b) { return a < (T)b ? a : (T)b; } template static inline void min_it (T &a, U b) { a = a < (T)b ? a : (T)b; } template static inline T max (T a, U b) { return a > (T)b ? a : (T)b; } template static inline void max_it (T &a, U b) { a = a > (T)b ? a : (T)b; } template static inline T clamp (T v, U a, V b) { return v < (T)a ? a : v >(T)b ? b : v; } template static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; } #endif gvpe-3.0/src/conf.h0000644000000000000000000001434412615056110011074 00000000000000/* conf.h -- configuration database Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_CONF_H__ #define GVPE_CONF_H__ #include #include #include #include "slog.h" #include "global.h" #define DEFAULT_REKEY 3607 // interval between rekeys #define DEFAULT_RESEED 3613 // interval between rng reseeds #define DEFAULT_KEEPALIVE 60 // one keepalive/minute (it's just 8 bytes...) #define DEFAULT_UDPPORT 655 // same as tinc, conflicts would be rare #define DEFAULT_MTU 1500 // let's ether-net #define DEFAULT_MAX_RETRY 3600 // retry at least this often #define DEFAULT_MAX_TTL 60 // packets expire after this many seconds #define DEFAULT_MAX_QUEUE 512 // never queue more than this many packets #define DEFAULT_DNS_TIMEOUT_FACTOR 8.F // initial retry timeout multiple #define DEFAULT_DNS_SEND_INTERVAL .01F // minimum send interval #define DEFAULT_DNS_OVERLAP_FACTOR .5F // RTT * LATENCY_FACTOR == sending rate #define DEFAULT_DNS_MAX_OUTSTANDING 100 // max. number of outstanding requests enum { PROT_UDPv4 = 0x01, // udp over ipv4 PROT_IPv4 = 0x02, // generic ip protocol PROT_TCPv4 = 0x04, // tcp over ipv4 (server) PROT_ICMPv4 = 0x08, // icmp over ipv4 PROT_DNSv4 = 0x10, // dns tunnel ipv4 (server) PROT_ALL = 0x1f }; #define PROT_RELIABLE (PROT_TCPv4 | PROT_DNSv4) #define PROT_SLOW PROT_DNSv4 // select the "best" protocol of the available ones u8 best_protocol (u8 protset); const char *strprotocol (u8 protocol); struct conf_node { int id; // the id of this node, a 12-bit-number RSA *rsa_key; // his public key char *nodename; // nodename, an internal nickname. char *hostname; // hostname, if known, or NULL. char *if_up_data; #if ENABLE_DNS char *domain; // dns tunnel domain #endif char *dns_hostname; u16 dns_port; u8 protocols; // protocols this host can send & receive u16 udp_port, tcp_port; // the port to bind to int max_retry; double max_ttl; // packets expire after this many seconds int max_queue; // maixmum send queue length enum connectmode { C_ONDEMAND, C_NEVER, C_ALWAYS, C_DISABLED } connectmode; bool compress; bool inherit_tos; // inherit TOS in packets send to this destination bool low_power; // node is a low-power node (reduce cpu usage, wakeups and assume higher latency) vector allow_direct; vector deny_direct; u32 routerprio; u8 connectable_protocols () const { u8 protocols = this->protocols; // mask out endpoints we can't connect to if (!udp_port) protocols &= ~PROT_UDPv4; if (!tcp_port) protocols &= ~PROT_TCPv4; if (!dns_port) protocols &= ~PROT_DNSv4; return protocols; } bool may_direct (struct conf_node *other); void finalise (); void print (); ~conf_node (); }; struct configuration { typedef vector node_vector; node_vector nodes; conf_node default_node; conf_node *thisnode; char serial[SERIAL_SIZE]; char *seed_dev; // the randomd evice to use for seeding double reseed; // the interval between additional seeds int mtu; // the mtu used for outgoing tunnel packets int nfmark; // the SO_MARK // netfilter mark // fwmark double rekey; // rekey interval double keepalive; // keepalive probes interval char *ifname; // the interface name (tap0 ...) bool ifpersist; // should the interface be persistent char *prikeyfile; RSA *rsa_key; // our private rsa key loglevel llevel; u8 ip_proto; // the ip protocol to use uid_t change_uid; // the uid of the user to switch to, or 0 gid_t change_gid; // the gid of the user to switch to, or 0 char *change_root;// the path to chroot to, "/" == anonymous #if ENABLE_ICMP u8 icmp_type; // the icmp type for the icmp-protocol #endif char *script_if_up; char *script_node_up; char *script_node_change; char *script_node_down; char *pidfilename; #if ENABLE_HTTP_PROXY char *proxy_auth; // login:password char *proxy_host; // the proxy hostname, e.g. proxy1.example.net u16 proxy_port; // the proxy port, e.g. 3128 #endif #if ENABLE_DNS char *dns_forw_host; bool dns_case_preserving; u16 dns_forw_port; float dns_timeout_factor; float dns_send_interval; float dns_overlap_factor; int dns_max_outstanding; #endif void init (); void cleanup (); void clear (); conf_node *find_node (const char *name); // create a filename from string, replacing %s by the nodename // and using relative paths under confbase. char *config_filename (const char *name, const char *dflt = 0); void print (); configuration (); ~configuration (); }; struct configuration_parser { configuration &conf; bool need_keys; conf_node *node; int argc; char **argv; configuration_parser (configuration &conf, bool need_keys, int argc, char **argv); void parse_file (const char *fname); const char *parse_line (char *line); void parse_argv (); }; extern struct configuration conf; #define THISNODE ::conf.thisnode #endif gvpe-3.0/src/conf.C0000644000000000000000000005071512615056110011031 00000000000000/* conf.C -- configuration code Copyright (C) 2003-2008,2011 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "netcompat.h" #include #include #include #include #include #include "conf.h" #include "slog.h" #include "util.h" char *confbase; char *thisnode; char *identname; struct configuration conf; u8 best_protocol (u8 protset) { if (protset & PROT_IPv4 ) return PROT_IPv4; if (protset & PROT_ICMPv4) return PROT_ICMPv4; if (protset & PROT_UDPv4 ) return PROT_UDPv4; if (protset & PROT_TCPv4 ) return PROT_TCPv4; if (protset & PROT_DNSv4 ) return PROT_DNSv4; return 0; } const char * strprotocol (u8 protocol) { if (protocol & PROT_IPv4 ) return "rawip"; if (protocol & PROT_ICMPv4) return "icmp"; if (protocol & PROT_UDPv4 ) return "udp"; if (protocol & PROT_TCPv4 ) return "tcp"; if (protocol & PROT_DNSv4 ) return "dns"; return ""; } static bool match_list (const vector &list, const char *str) { for (vector::const_iterator i = list.end (); i-- > list.begin (); ) if ((*i)[0] == '*' && !(*i)[1]) return true; else if (!strcmp (*i, str)) return true; return false; } bool conf_node::may_direct (struct conf_node *other) { if (match_list (allow_direct, other->nodename)) return true; if (match_list (deny_direct, other->nodename)) return false; return true; } conf_node::~conf_node () { #if 0 // does not work, because string pointers etc. are shared // is not called, however if (rsa_key) RSA_free (rsa_key); free (nodename); free (hostname); free (if_up_data); #if ENABLE_DNS free (domain); free (dns_hostname); #endif #endif } void configuration::init () { memset (this, 0, sizeof (*this)); mtu = DEFAULT_MTU; nfmark = 0; rekey = DEFAULT_REKEY; keepalive = DEFAULT_KEEPALIVE; llevel = L_INFO; ip_proto = IPPROTO_GRE; #if ENABLE_ICMP icmp_type = ICMP_ECHOREPLY; #endif default_node.udp_port = DEFAULT_UDPPORT; default_node.tcp_port = DEFAULT_UDPPORT; // ehrm default_node.connectmode = conf_node::C_ALWAYS; default_node.compress = true; default_node.protocols = 0; default_node.max_retry = DEFAULT_MAX_RETRY; default_node.max_ttl = DEFAULT_MAX_TTL; default_node.max_queue = DEFAULT_MAX_QUEUE; default_node.if_up_data = strdup (""); #if ENABLE_DNS default_node.dns_port = 0; // default is 0 == client dns_case_preserving = true; dns_forw_host = strdup ("127.0.0.1"); dns_forw_port = 53; dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; #endif pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); seed_dev = strdup ("/dev/urandom"); reseed = DEFAULT_RESEED; } void configuration::cleanup () { if (rsa_key) RSA_free (rsa_key); rsa_key = 0; free (seed_dev); seed_dev = 0; free (pidfilename); pidfilename = 0; free (ifname); ifname = 0; #if ENABLE_HTTP_PROXY free (proxy_host); proxy_host = 0; free (proxy_auth); proxy_auth = 0; #endif #if ENABLE_DNS free (dns_forw_host); dns_forw_host = 0; #endif free (change_root); change_root = 0; free (script_if_up); script_if_up = 0; free (script_node_up); script_node_up = 0; free (script_node_change); script_node_change = 0; free (script_node_down); script_node_down = 0; } void configuration::clear () { for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i) delete *i; nodes.clear (); cleanup (); init (); } conf_node * configuration::find_node (const char *name) { for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) if (!strcmp ((*i)->nodename, name)) return *i; return 0; } //static bool //is_true (const char *name) //{ //re //} #define parse_bool(target,name,trueval,falseval) do { \ if (!strcmp (val, "yes")) target = trueval; \ else if (!strcmp (val, "no")) target = falseval; \ else if (!strcmp (val, "true")) target = trueval; \ else if (!strcmp (val, "false")) target = falseval; \ else if (!strcmp (val, "on")) target = trueval; \ else if (!strcmp (val, "off")) target = falseval; \ else \ return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \ } while (0) const char * configuration_parser::parse_line (char *line) { { char *end = line + strlen (line); while (end >= line && *end < ' ') end--; *++end = 0; } char *tok = line; const char *var = strtok (tok, "\t ="); tok = 0; if (!var || !var[0]) return 0; /* no tokens on this line */ if (var[0] == '#') return 0; /* comment: ignore */ if (!strcmp (var, "global")) { node = &conf.default_node; return 0; } char *val = strtok (NULL, "\t\n\r ="); if (!val || val[0] == '#') return _("no value given for variable, ignored"); else if (!strcmp (var, "on")) { if (::thisnode && ((val[0] == '!' && strcmp (val + 1, ::thisnode)) || !strcmp (val, ::thisnode))) return parse_line (strtok (NULL, "\n\r")); } else if (!strcmp (var, "include")) { char *fname = conf.config_filename (val); parse_file (fname); free (fname); } // truly global else if (!strcmp (var, "loglevel")) { loglevel l = string_to_loglevel (val); if (l == L_NONE) return _("unknown loglevel, ignored"); } else if (!strcmp (var, "serial")) strncpy (conf.serial, val, sizeof (conf.serial)); else if (!strcmp (var, "ip-proto")) conf.ip_proto = atoi (val); else if (!strcmp (var, "icmp-type")) { #if ENABLE_ICMP conf.icmp_type = atoi (val); #endif } else if (!strcmp (var, "chuser")) { struct passwd *pw = getpwnam (val); if (!pw) return _("user specified for chuser not found"); conf.change_uid = pw->pw_uid; conf.change_gid = pw->pw_gid; } else if (!strcmp (var, "chuid")) conf.change_uid = atoi (val); else if (!strcmp (var, "chgid")) conf.change_gid = atoi (val); else if (!strcmp (var, "chroot")) free (conf.change_root), conf.change_root = strdup (val); // per node else if (!strcmp (var, "node")) { node = conf.find_node (val); if (!node) { conf.default_node.id++; node = new conf_node (conf.default_node); conf.nodes.push_back (node); node->nodename = strdup (val); } } else if (!strcmp (var, "private-key")) free (conf.prikeyfile), conf.prikeyfile = strdup (val); else if (!strcmp (var, "ifpersist")) parse_bool (conf.ifpersist, "ifpersist", true, false); else if (!strcmp (var, "ifname")) free (conf.ifname), conf.ifname = strdup (val); else if (!strcmp (var, "rekey")) conf.rekey = atoi (val); else if (!strcmp (var, "keepalive")) conf.keepalive = atoi (val); else if (!strcmp (var, "mtu")) conf.mtu = atoi (val); else if (!strcmp (var, "nfmark")) conf.nfmark = atoi (val); else if (!strcmp (var, "seed-device")) free (conf.seed_dev), conf.seed_dev = strdup (val); else if (!strcmp (var, "seed-interval")) conf.reseed = atoi (val); else if (!strcmp (var, "if-up")) free (conf.script_if_up), conf.script_if_up = strdup (val); else if (!strcmp (var, "node-up")) free (conf.script_node_up), conf.script_node_up = strdup (val); else if (!strcmp (var, "node-change")) free (conf.script_node_change), conf.script_node_change = strdup (val); else if (!strcmp (var, "node-down")) free (conf.script_node_down), conf.script_node_down = strdup (val); else if (!strcmp (var, "pid-file")) free (conf.pidfilename), conf.pidfilename = strdup (val); else if (!strcmp (var, "dns-forw-host")) { #if ENABLE_DNS free (conf.dns_forw_host), conf.dns_forw_host = strdup (val); #endif } else if (!strcmp (var, "dns-forw-port")) { #if ENABLE_DNS conf.dns_forw_port = atoi (val); #endif } else if (!strcmp (var, "dns-timeout-factor")) { #if ENABLE_DNS conf.dns_timeout_factor = atof (val); #endif } else if (!strcmp (var, "dns-send-interval")) { #if ENABLE_DNS conf.dns_send_interval = atoi (val); #endif } else if (!strcmp (var, "dns-overlap-factor")) { #if ENABLE_DNS conf.dns_overlap_factor = atof (val); #endif } else if (!strcmp (var, "dns-max-outstanding")) { #if ENABLE_DNS conf.dns_max_outstanding = atoi (val); #endif } else if (!strcmp (var, "dns-case-preserving")) { #if ENABLE_DNS parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false); #endif } else if (!strcmp (var, "http-proxy-host")) { #if ENABLE_HTTP_PROXY free (conf.proxy_host), conf.proxy_host = strdup (val); #endif } else if (!strcmp (var, "http-proxy-port")) { #if ENABLE_HTTP_PROXY conf.proxy_port = atoi (val); #endif } else if (!strcmp (var, "http-proxy-auth")) { #if ENABLE_HTTP_PROXY conf.proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val)); #endif } /* node-specific, non-defaultable */ else if (node != &conf.default_node && !strcmp (var, "hostname")) free (node->hostname), node->hostname = strdup (val); /* node-specific, defaultable */ else if (!strcmp (var, "udp-port")) node->udp_port = atoi (val); else if (!strcmp (var, "tcp-port")) node->tcp_port = atoi (val); else if (!strcmp (var, "dns-hostname")) { #if ENABLE_DNS free (node->dns_hostname), node->dns_hostname = strdup (val); #endif } else if (!strcmp (var, "dns-port")) { #if ENABLE_DNS node->dns_port = atoi (val); #endif } else if (!strcmp (var, "dns-domain")) { #if ENABLE_DNS free (node->domain), node->domain = strdup (val); #endif } else if (!strcmp (var, "if-up-data")) free (node->if_up_data), node->if_up_data = strdup (val); else if (!strcmp (var, "router-priority")) node->routerprio = atoi (val); else if (!strcmp (var, "max-retry")) node->max_retry = atoi (val); else if (!strcmp (var, "connect")) { if (!strcmp (val, "ondemand")) node->connectmode = conf_node::C_ONDEMAND; else if (!strcmp (val, "never")) node->connectmode = conf_node::C_NEVER; else if (!strcmp (val, "always")) node->connectmode = conf_node::C_ALWAYS; else if (!strcmp (val, "disabled")) node->connectmode = conf_node::C_DISABLED; else return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored"); } else if (!strcmp (var, "inherit-tos")) parse_bool (node->inherit_tos, "inherit-tos", true, false); else if (!strcmp (var, "compress")) parse_bool (node->compress, "compress", true, false); else if (!strcmp (var, "low-power")) parse_bool (node->low_power, "low-power", true, false); // all these bool options really really cost a lot of executable size! else if (!strcmp (var, "enable-tcp")) { #if ENABLE_TCP u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v; #endif } else if (!strcmp (var, "enable-icmp")) { #if ENABLE_ICMP u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v; #endif } else if (!strcmp (var, "enable-dns")) { #if ENABLE_DNS u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v; #endif } else if (!strcmp (var, "enable-udp")) { u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v; } else if (!strcmp (var, "enable-rawip")) { u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v; } else if (!strcmp (var, "allow-direct")) node->allow_direct.push_back (strdup (val)); else if (!strcmp (var, "deny-direct")) node->deny_direct.push_back (strdup (val)); else if (!strcmp (var, "max-ttl")) node->max_ttl = atof (val); else if (!strcmp (var, "max-queue")) node->max_queue = atoi (val); // unknown or misplaced else return _("unknown configuration directive - ignored"); return 0; } void conf_node::finalise () { if (max_queue < 1) { slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename); max_queue = 1; } if (routerprio > 1 && (connectmode != C_ALWAYS && connectmode != C_DISABLED)) { //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename); connectmode = C_ALWAYS; } } void configuration_parser::parse_file (const char *fname) { if (FILE *f = fopen (fname, "r")) { char line [2048]; int lineno = 0; while (fgets (line, sizeof (line), f)) { lineno++; const char *warn = parse_line (line); if (warn) slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno); } fclose (f); } else { slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); exit (EXIT_FAILURE); } } configuration_parser::configuration_parser (configuration &conf, bool need_keys, int argc, char **argv) : conf (conf), need_keys (need_keys), argc (argc), argv (argv) { char *fname; conf.clear (); node = &conf.default_node; asprintf (&fname, "%s/gvpe.conf", confbase); parse_file (fname); free (fname); fname = conf.config_filename (conf.prikeyfile, "hostkey"); if (FILE *f = fopen (fname, "r")) { conf.rsa_key = RSA_new (); if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) { ERR_load_RSA_strings (); ERR_load_PEM_strings (); slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); exit (EXIT_FAILURE); } require (RSA_blinding_on (conf.rsa_key, 0)); fclose (f); } else { if (need_keys) { slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); exit (EXIT_FAILURE); } } free (fname); fname = conf.config_filename (conf.pidfilename); free (conf.pidfilename); conf.pidfilename = fname; for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) { conf_node *node = *i; char *fname; FILE *f; asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); f = fopen (fname, "r"); if (f) { node->rsa_key = RSA_new (); if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL)) { ERR_load_RSA_strings (); ERR_load_PEM_strings (); slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); exit (EXIT_FAILURE); } require (RSA_blinding_on (node->rsa_key, 0)); fclose (f); } else { slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno)); if (need_keys) exit (EXIT_FAILURE); } free (fname); (*i)->finalise (); } if (::thisnode) { conf.thisnode = conf.find_node (::thisnode); if (need_keys) { if (!conf.thisnode) { slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode); exit (EXIT_FAILURE); } if (conf.rsa_key && conf.thisnode->rsa_key) if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) { slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); exit (EXIT_FAILURE); } } } parse_argv (); } void configuration_parser::parse_argv () { for (int i = 0; i < argc; ++i) { char *v = argv [i]; if (!*v) continue; char *enode = v; while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode) enode++; if (*enode != '.') enode = 0; if (enode) { char *val = strdup (v); val [enode - v] = 0; node = conf.find_node (val); free (val); if (!node) { slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v); continue; } } else node = &conf.default_node; const char *warn = parse_line (enode ? enode + 1 : v); if (warn) slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); } } char * configuration::config_filename (const char *name, const char *dflt) { char *fname; asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : ""); if (!ABSOLUTE_PATH (fname)) { char *rname = fname; asprintf (&fname, "%s/%s", confbase, rname); free (rname); } return fname; } void conf_node::print () { printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n", id, id >> 8, id & 0xff, compress ? 'Y' : 'N', connectmode == C_ONDEMAND ? "ondemand" : connectmode == C_NEVER ? "never" : connectmode == C_ALWAYS ? "always" : connectmode == C_DISABLED ? "disabled" : "", nodename, protocols, hostname ? hostname : "", hostname ? ":" : "", hostname ? udp_port : 0 ); } void configuration::print () { printf (_("\nConfiguration\n\n")); printf (_("# of nodes: %d\n"), nodes.size ()); printf (_("this node: %s\n"), thisnode ? thisnode->nodename : ""); printf (_("MTU: %d\n"), mtu); printf (_("rekeying interval: %d\n"), rekey); printf (_("keepalive interval: %d\n"), keepalive); printf (_("interface: %s\n"), ifname); printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : ""); printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); printf ("\n"); printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n", _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port")); for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) (*i)->print (); printf ("\n"); } configuration::configuration () { asprintf (&confbase, "%s/gvpe", CONFDIR); init (); } configuration::~configuration () { cleanup (); } gvpe-3.0/src/util.h0000644000000000000000000001005412615056110011116 00000000000000/* util.h -- process management and other utility functions Copyright (C) 1998-2002 Ivo Timmermans 2000-2002 Guus Sliepen 2003-2013 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef UTIL_H__ #define UTIL_H__ #include #include #include "gettext.h" #include "slog.h" #include "ev_cpp.h" #include "callback.h" #include "global.h" typedef ev_tstamp tstamp; /* * check for an existing gvpe for this net, and write pid to pidfile */ extern int write_pidfile (void); /* * kill older gvpe */ extern int kill_other (int signal); /* * Detach from current terminal, write pidfile, kill parent */ extern int detach (int do_detach); /* * check wether the given path is an absolute pathname */ #define ABSOLUTE_PATH(c) ((c)[0] == '/') /*****************************************************************************/ typedef u8 mac[6]; extern void id2mac (unsigned int id, void *m); #define mac2id(p) ((p)[0] & 0x01 ? 0 : ((p)[4] << 8) | (p)[5]) struct sliding_window { u32 v[(WINDOWSIZE + 31) / 32]; u32 seq; void reset (u32 seqno) { memset (v, -1, sizeof v); seq = seqno; } // 0 == ok, 1 == far history, 2 == duplicate in-window, 3 == far future int seqno_classify (u32 seqno) { if (seqno <= seq - WINDOWSIZE) return 1; else if (seqno > seq + WINDOWSIZE * 16) return 3; else { while (seqno > seq) { seq++; u32 s = seq % WINDOWSIZE; u32 *cell = v + (s >> 5); u32 mask = 1 << (s & 31); *cell &= ~mask; } u32 s = seqno % WINDOWSIZE; u32 *cell = v + (s >> 5); u32 mask = 1 << (s & 31); if (*cell & mask) return 2; else { *cell |= mask; return 0; } } } }; typedef callback run_script_cb; // run a shell script (or actually an external program). pid_t run_script (const run_script_cb &cb, bool wait); void hexdump (const char *header, void *data, int len); #if ENABLE_HTTP_PROXY u8 *base64_encode (const u8 *data, unsigned int len); #endif /* always take more or less the same time to compare */ bool slow_memeq (const void *a, const void *b, int len); /*****************************************************************************/ void rand_fill (void *data, int len); template inline void rand_fill (T &t) { rand_fill (&t, sizeof (T)); } /*****************************************************************************/ // run work_cb in another thread, call done_cb in main thread when finished // only one work_cb will execute at any one time. void async (callback work_cb, callback done_cb); #endif gvpe-3.0/src/util.C0000644000000000000000000002120312615056110011047 00000000000000/* util.C -- process management and other utility functions Copyright (C) 2003-2011 Marc Lehmann Some of these are taken from tinc, see the AUTHORS file. This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #if ENABLE_PTHREADS # include #endif #include #include "netcompat.h" #include "gettext.h" #include "pidfile.h" #include "dropin.h" #include "global.h" #include "conf.h" #include "util.h" #include "slog.h" int write_pidfile (void) { int pid; pid = check_pid (conf.pidfilename); if (pid) { fprintf (stderr, _("A gvpe daemon is already running with pid %d.\n"), pid); return 1; } /* if it's locked, write-protected, or whatever */ if (!write_pid (conf.pidfilename)) return 1; return 0; } int kill_other (int signal) { int pid; pid = read_pid (conf.pidfilename); if (!pid) { fprintf (stderr, _("No other gvpe daemon is running.\n")); return 1; } errno = 0; /* No error, sometimes errno is only changed on error */ /* ESRCH is returned when no process with that pid is found */ if (kill (pid, signal) && errno == ESRCH) { fprintf (stderr, _("The gvpe daemon is no longer running. ")); fprintf (stderr, _("Removing stale lock file.\n")); remove_pid (conf.pidfilename); } return 0; } int detach (int do_detach) { /* First check if we can open a fresh new pidfile */ if (write_pidfile ()) return -1; /* If we succeeded in doing that, detach */ log_to (0); if (do_detach) { if (daemon (0, 0) < 0) { log_to (LOGTO_SYSLOG | LOGTO_STDERR); slog (L_ERR, _("couldn't detach from terminal: %s"), strerror (errno)); return -1; } /* Now UPDATE the pid in the pidfile, because we changed it... */ if (!write_pid (conf.pidfilename)) return -1; log_to (LOGTO_SYSLOG); } else log_to (LOGTO_SYSLOG | LOGTO_STDERR); slog (L_INFO, _("gvpe daemon %s (%s %s) starting up."), VERSION, __DATE__, __TIME__); return 0; } /*****************************************************************************/ pid_t run_script (const run_script_cb &cb, bool wait) { sigset_t oldset; if (wait) { sigset_t sigchld; sigemptyset (&sigchld); sigaddset (&sigchld, SIGCHLD); sigprocmask (SIG_BLOCK, &sigchld, &oldset); } pid_t pid = fork (); if (pid == 0) { sigprocmask (SIG_SETMASK, &oldset, 0); execl ("/bin/sh", "/bin/sh", "-c", cb (), (char *) 0); exit (EXIT_FAILURE); } else if (pid > 0) { if (wait) { int status; int res = waitpid (pid, &status, 0); sigprocmask (SIG_SETMASK, &oldset, 0); if (res < 0) { slog (L_WARN, _("waiting for an external command failed: %s."), strerror (errno)); return 0; } else if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) { slog (L_WARN, _("external command returned with exit status %d (%04x)."), WEXITSTATUS (status), status); return 0; } } } else { slog (L_ERR, _("unable to fork, exiting: %s"), strerror (errno)); exit (EXIT_FAILURE); } return pid; } /*****************************************************************************/ #if 0 /* not yet used */ #if ENABLE_PTHREADS struct async_cb { callback work_cb; callback done_cb; }; static ev::async async_done_w; static std::queue< callback > async_q; static callback work_cb; static void * async_exec (void *) { work_cb (); async_done_w.send (); return 0; } static void async_q_next () { work_cb = async_q.front (); async_q.pop (); sigset_t fullsigset, oldsigset; pthread_attr_t attr; pthread_t tid; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); //pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < X_STACKSIZE ? X_STACKSIZE : PTHREAD_STACK_MIN); sigfillset (&fullsigset); pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset); if (pthread_create (&tid, &attr, async_exec, 0)) async_exec (0); pthread_sigmask (SIG_SETMASK, &oldsigset, 0); pthread_attr_destroy (&attr); } namespace { void async_done (ev::async &w, int revents) { callback done_cb = async_q.front (); async_q.pop (); if (async_q.empty ()) async_done_w.stop (); else async_q_next (); done_cb (); } }; void async (callback work_cb, callback done_cb) { bool was_empty = async_q.empty (); async_q.push (work_cb); async_q.push (done_cb); if (was_empty) { async_done_w.set (); async_done_w.start (); async_q_next (); } } #else void async (callback work_cb, callback done_cb) { work_cb (); done_cb (); } #endif #endif /*****************************************************************************/ void hexdump (const char *header, void *data, int len) { u8 *p = (u8 *)data; printf ("%s:", header); while (len--) printf (" %02x", *p++); printf ("\n"); } /*****************************************************************************/ #if ENABLE_HTTP_PROXY // works like strdup u8 * base64_encode (const u8 *data, unsigned int len) { const static char base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned int t, i; const u8 *end = data + len; u8 *res = new u8 [4 * ((len + 2) / 3) + 1]; u8 *out = res; while (data <= end - 3) { t = (((data[0] << 8) | data[1]) << 8) | data[2]; data += 3; *out++ = base64[(t >> 18) & 0x3f]; *out++ = base64[(t >> 12) & 0x3f]; *out++ = base64[(t >> 6) & 0x3f]; *out++ = base64[(t ) & 0x3f]; } for (t = 0, i = 0; data < end; i++) t = (t << 8) | *data++; switch (i) { case 2: *out++ = base64[(t >> 10) & 0x3f]; *out++ = base64[(t >> 4) & 0x3f]; *out++ = base64[(t << 2) & 0x3f]; *out++ = '='; break; case 1: *out++ = base64[(t >> 2) & 0x3f]; *out++ = base64[(t << 4) & 0x3f]; *out++ = '='; *out++ = '='; break; } *out++ = 0; return res; } #endif bool slow_memeq (const void *a, const void *b, int len) { volatile const u8 *pa = (const u8 *)a; volatile const u8 *pb = (const u8 *)b; u8 diff = 0; while (len--) diff |= *pa++ ^ *pb++; return !diff; } void id2mac (unsigned int id, void *m) { mac &p = *(mac *)m; if (id) { p[0] = 0xfe; p[1] = 0xfd; p[2] = 0x80; p[3] = 0x00; p[4] = id >> 8; p[5] = id; } else { p[0] = 0xff; p[1] = 0xff; p[2] = 0xff; p[3] = 0xff; p[4] = 0xff; p[5] = 0xff; } } /*****************************************************************************/ void rand_fill (void *data, int len) { int l = RAND_bytes ((unsigned char *)data, len); if (l > 0) return; else if (l == 0) slog (L_WARN, _("Not enough random entropy to generate secure keys. Using weaker pseudo-random session keys.")); else fatal (_("RAND_bytes failed, aborting.")); } gvpe-3.0/src/slog.h0000644000000000000000000000466312615056110011116 00000000000000/* slog.h -- logging Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef SLOG_H__ #define SLOG_H__ enum loglevel { L_NONE, L_NOISE, L_TRACE, L_DEBUG, L_INFO, L_NOTICE, L_WARN, L_ERR, L_CRIT }; enum { LOGTO_SYSLOG = 1, LOGTO_STDERR = 2 }; extern loglevel log_level; extern const char *log_identity; extern loglevel string_to_loglevel (const char *s); #define UNKNOWN_LOGLEVEL _("unknown loglevel, try 'noise', 'debug', 'info', 'notice', 'warn', 'error' or 'critical'") inline void set_loglevel (const loglevel l) { log_level = l; } inline loglevel get_loglevel () { return log_level; } inline void set_identity (const char *identname) { log_identity = identname; } inline const char *get_identity () { return log_identity; } extern void log_to (int mask); extern void slog_ (const loglevel l, const char *m, ...); #if __GNUC__ > 2 # define slog(l, ...) do { if ((l) >= log_level) slog_ (l, __VA_ARGS__); } while (0) #else # define slog slog_ #endif extern void fatal (const char *m); extern void require_failed (const char *file, int line, const char *info); #define require(expr) if (!(expr)) require_failed (__FILE__, __LINE__, #expr) #endif gvpe-3.0/src/slog.C0000644000000000000000000000723712615056110011051 00000000000000/* slog.C -- logging Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include #include #include #include #include #include #include "slog.h" loglevel log_level = L_INFO; const char *log_identity = ""; static int logto = LOGTO_STDERR; loglevel string_to_loglevel (const char *s) { if (!strcmp (s, "noise")) return L_NOISE; if (!strcmp (s, "trace")) return L_TRACE; if (!strcmp (s, "debug")) return L_DEBUG; if (!strcmp (s, "info")) return L_INFO; if (!strcmp (s, "notice")) return L_NOTICE; if (!strcmp (s, "warn")) return L_WARN; if (!strcmp (s, "error")) return L_ERR; if (!strcmp (s, "critical")) return L_CRIT; return L_NONE; } void log_to (int mask) { if (logto & LOGTO_SYSLOG) closelog (); logto = mask; if (logto & LOGTO_SYSLOG) openlog (log_identity, LOG_CONS | LOG_PID, LOG_DAEMON); } void slog_ (const loglevel l, const char *m, ...) { if (l >= log_level) { va_list ap; va_start (ap, m); char *msg = new char [2048]; vsnprintf (msg, 2048, m, ap); if (logto & LOGTO_SYSLOG) { int lvl = l == L_TRACE ? LOG_DEBUG : l == L_DEBUG ? LOG_DEBUG : l == L_INFO ? LOG_INFO : l == L_NOTICE ? LOG_NOTICE : l == L_ERR ? LOG_ERR : l == L_CRIT ? LOG_CRIT : LOG_ERR; syslog (lvl, "%s", msg); } if (logto & LOGTO_STDERR) { write (2, msg, strlen (msg)); write (2, "\n", 1); } delete [] msg; } } void fatal (const char *m) { slog (L_CRIT, m); exit (EXIT_FAILURE); } void require_failed (const char *file, int line, const char *info) { slog (L_CRIT, "FATAL: This program encountered a SHOULD NOT HAPPEN condition and will exit:"); slog (L_CRIT, "FATAL+ %s:%d '%s' is false", file, line, info); slog (L_CRIT, "FATAL+ This might indicates a bug in this program, a bug in your libraries,"); slog (L_CRIT, "FATAL+ your system setup or operating system. Or it might indicate a very"); slog (L_CRIT, "FATAL+ unusual, unanticipated operating condition, library version mismatch"); slog (L_CRIT, "FATAL+ or similar problem. If it's not obvious to you what was causing it,"); slog (L_CRIT, "FATAL+ then please report this to the program author(s)."); exit (126); } gvpe-3.0/src/netcompat.h0000644000000000000000000000526412615056110012142 00000000000000/* netcompat.h -- network compatibility header Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef GVPE_NETCOMPAT_H #define GVPE_NETCOMPAT_H #include #include #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #include #ifdef HAVE_NETINET_IN_SYSTM_H # include #endif #ifdef HAVE_NETINET_IP_H # include #endif #ifndef IPTOS_MINCOST # define IPTOS_MINCOST 0x02 #endif #ifndef IPTOS_RELIABILITY # define IPTOS_RELIABILITY 0x04 #endif #ifndef IPTOS_THROUGHPUT # define IPTOS_THROUGHPUT 0x08 #endif #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 #endif #ifndef IPTOS_TOS_MASK # define IPTOS_TOS_MASK (IPTOS_LOWDELAY | IPTOS_THROUGHPUT | IPTOS_RELIABILITY | IPTOS_MINCOST) #endif #if !defined(SOL_IP) && defined(IPPROTO_IP) # define SOL_IP IPPROTO_IP #endif #ifndef IPPROTO_GRE # define IPPROTO_GRE 47 #endif #ifndef ICMP_ECHOREPLY # define ICMP_ECHOREPLY 0 #endif #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif #if ENABLE_ICMP # include struct icmp_header { u8 type; u8 code; u16 checksum; union { struct { u16 id; u16 sequence; } echo; u32 gateway; struct { u16 unused; u16 mtu; } frag; } un; }; #endif #endif gvpe-3.0/src/ev_cpp.h0000644000000000000000000000035212615056110011415 00000000000000#define EV_COMPAT3 0 #define EV_CHILD_ENABLE 1 #define EV_USE_STDEXCEPT 0 #define EV_CONFIG_H #define EV_FEATURES 1+2+32+64 #define EV_IO_ENABLE 1 #define EV_TIMER_ENABLE 1 #define EV_ASYNC_ENABLE 1 #include "ev++.h" gvpe-3.0/src/ev_cpp.C0000644000000000000000000000004512615056110011347 00000000000000#include "ev_cpp.h" #include "ev.c" gvpe-3.0/src/crypto.h0000644000000000000000000000464512735244256011507 00000000000000/* crypto.h -- openssl crypto wrappers Copyright (C) 2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #ifndef CRYPTO_H__ #define CRYPTO_H__ #include #include #include #include // openssl 0.9.8/1.0.0 compatibility #if OPENSSL_VERSION_NUMBER < 0x10001000 #define require101(exp) exp #else #define require101(exp) require (exp) #endif /* this pretty much wraps the slightly weird openssl api */ class hmac { HMAC_CTX *ctx; public: hmac (); ~hmac (); void init (const void *key, int key_len, const EVP_MD *hash = 0) { require101 (HMAC_Init_ex (ctx, key, key_len, hash, 0)); } void init () { require101 (HMAC_Init_ex (ctx, 0, 0, 0, 0)); } void add (const void *data, int len) { require101 (HMAC_Update (ctx, (const unsigned char *)data, len)); } void digest (void *dgst) { require101 (HMAC_Final (ctx, (unsigned char *)dgst, 0)); } int size () { return HMAC_size (ctx); } }; /* cheap alloc/free wrapper only atm. */ class cipher { EVP_CIPHER_CTX *ctx; public: cipher (); ~cipher (); operator EVP_CIPHER_CTX *() { return ctx; } }; #endif gvpe-3.0/src/crypto.C0000644000000000000000000000413212735242265011427 00000000000000/* crypto.C -- openssl crypto wrappers Copyright (C) 2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include #include "crypto.h" hmac::hmac () { #if OPENSSL_VERSION_NUMBER < 0x10100000 require (ctx = (HMAC_CTX *)OPENSSL_malloc (sizeof (*ctx))); HMAC_CTX_init (ctx); #else require (ctx = HMAC_CTX_new ()); #endif } hmac::~hmac () { #if OPENSSL_VERSION_NUMBER < 0x10100000 HMAC_CTX_cleanup (ctx); OPENSSL_free (ctx); #else HMAC_CTX_free (ctx); #endif } cipher::cipher () { #if OPENSSL_VERSION_NUMBER < 0x10100000 require (ctx = (EVP_CIPHER_CTX *)OPENSSL_malloc (sizeof (*ctx))); EVP_CIPHER_CTX_init (ctx); #else require (ctx = EVP_CIPHER_CTX_new ()); #endif } cipher::~cipher () { #if OPENSSL_VERSION_NUMBER < 0x10100000 EVP_CIPHER_CTX_cleanup (ctx); OPENSSL_free (ctx); #else EVP_CIPHER_CTX_free (ctx); #endif } gvpe-3.0/src/gvpectrl.C0000644000000000000000000002641013006306757011737 00000000000000/* gvpectrl.C -- the main file for gvpectrl Copyright (C) 1998-2002 Ivo Timmermans 2000-2002 Guus Sliepen 2003-2016 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pidfile.h" #include "conf.h" #include "slog.h" #include "util.h" #include "vpn.h" /* If nonzero, display usage information and exit. */ static int show_help; /* If nonzero, print the version on standard output and exit. */ static int show_version; /* If nonzero, it will attempt to kill a running gvpe and exit. */ static int kill_gvpe; /* If nonzero, it will attempt to kill a running gvpe and exit. */ static int show_config; /* If nonzero, do not output anything but warnings/errors/very unusual conditions */ static int quiet; /* If nonzero, generate single public/private keypair. */ static const char *generate_key; /* If nonzero, generate public/private keypair for this net. */ static int generate_keys; // output some debugging info, interna constants &c static int debug_info; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, {"kill", optional_argument, NULL, 'k'}, {"help", no_argument, &show_help, 1}, {"version", no_argument, &show_version, 1}, {"generate-key", required_argument, NULL, 'g'}, {"generate-keys", no_argument, NULL, 'G'}, {"quiet", no_argument, &quiet, 1}, {"show-config", no_argument, &show_config, 's'}, {"debug-info", no_argument, &debug_info, 1}, {NULL, 0, NULL, 0} }; static void usage (int status) { if (status != 0) fprintf (stderr, _("Try `%s --help\' for more information.\n"), get_identity ()); else { printf (_("Usage: %s [option]...\n\n"), get_identity ()); printf (_ (" -c, --config=DIR Read configuration options from DIR.\n" " -k, --kill[=SIGNAL] Attempt to kill a running gvpe and exit.\n" " -g, --generate-key=file Generate public/private RSA keypair.\n" " -G, --generate-keys Generate all public/private RSA keypairs.\n" " -s, --show-config Display the configuration information.\n" " -q, --quiet Be quite quiet.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n\n")); printf (_("Report bugs to .\n")); } exit (status); } static void parse_options (int argc, char **argv, char **envp) { int r; int option_index = 0; while ((r = getopt_long (argc, argv, "c:k::qg:Gs", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; case 'c': /* config file */ confbase = strdup (optarg); break; case 'k': /* kill old gvpes */ if (optarg) { if (!strcasecmp (optarg, "HUP")) kill_gvpe = SIGHUP; else if (!strcasecmp (optarg, "TERM")) kill_gvpe = SIGTERM; else if (!strcasecmp (optarg, "KILL")) kill_gvpe = SIGKILL; else if (!strcasecmp (optarg, "USR1")) kill_gvpe = SIGUSR1; else if (!strcasecmp (optarg, "USR2")) kill_gvpe = SIGUSR2; else if (!strcasecmp (optarg, "INT")) kill_gvpe = SIGINT; else if (!strcasecmp (optarg, "ALRM")) kill_gvpe = SIGALRM; else { kill_gvpe = atoi (optarg); if (!kill_gvpe) { fprintf (stderr, _ ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"), optarg); usage (1); } } } else kill_gvpe = SIGTERM; break; case 'g': /* generate public/private keypair */ generate_key = optarg; break; case 'G': /* generate public/private keypairs */ generate_keys = 1; break; case 's': show_config = 1; break; case 'q': quiet = 1; break; case '?': usage (1); default: break; } } } // this function prettyprints the key generation process static int indicator (int a, int b, BN_GENCB *cb) { if (quiet) return 1; switch (a) { case 0: fprintf (stderr, "."); break; case 1: fprintf (stderr, "+"); break; case 2: fprintf (stderr, "-"); break; case 3: switch (b) { case 0: fprintf (stderr, " p\n"); break; case 1: fprintf (stderr, " q\n"); break; default: fprintf (stderr, "?"); } break; default: fprintf (stderr, "?"); } return 1; } /* * generate public/private RSA keypairs for all hosts that don't have one. */ static int keygen (const char *pub, const char *priv) { FILE *pubf = fopen (pub, "ab"); if (!pubf || fseek (pubf, 0, SEEK_END)) { perror (pub); exit (EXIT_FAILURE); } if (ftell (pubf)) { fclose (pubf); return 1; } FILE *privf = fopen (priv, "ab"); /* some libcs are buggy and require an extra seek to the end */ if (!privf || fseek (privf, 0, SEEK_END)) { perror (priv); exit (EXIT_FAILURE); } if (ftell (privf)) { fclose (pubf); fclose (privf); return 1; } RSA *rsa = RSA_new (); BIGNUM *e = BN_new (); BN_set_bit (e, 0); BN_set_bit (e, 16); // 0x10001, 65537 #if 0 #if OPENSSL_VERSION_NUMBER < 0x10100000 BN_GENCB cb_100; BN_GENCB *cb = &cb_100; #else BN_GENCB *cb = BN_GENCB_new (); require (cb); #endif BN_GENCB_set (cb, indicator, 0); require (RSA_generate_key_ex (rsa, RSABITS, e, cb)); #else require (RSA_generate_key_ex (rsa, RSABITS, e, 0)); #endif require (PEM_write_RSAPublicKey (pubf, rsa)); require (PEM_write_RSAPrivateKey (privf, rsa, NULL, NULL, 0, NULL, NULL)); fclose (pubf); fclose (privf); BN_free (e); RSA_free (rsa); return 0; } static int keygen_all () { char *fname; asprintf (&fname, "%s/pubkey", confbase); mkdir (fname, 0700); free (fname); for (configuration::node_vector::iterator i = conf.nodes.begin (); i != conf.nodes.end (); ++i) { conf_node *node = *i; ::thisnode = node->nodename; char *pub = conf.config_filename ("pubkey/%s", 0); char *priv = conf.config_filename (conf.prikeyfile, "hostkey"); int status = keygen (pub, priv); if (status == 0) { if (!quiet) fprintf (stderr, _("generated %d bits key for %s.\n"), RSABITS, node->nodename); } else if (status == 1) fprintf (stderr, _("'%s' keypair already exists, skipping node %s.\n"), pub, node->nodename); free (priv); free (pub); } return 0; } static int keygen_one (const char *pubname) { char *privname; asprintf (&privname, "%s.privkey", pubname); int status = keygen (pubname, privname); if (status == 0) { if (!quiet) fprintf (stderr, _("generated %d bits key as %s.\n"), RSABITS, pubname); } else if (status == 1) { fprintf (stderr, _("'%s' keypair already exists, not generating key.\n"), pubname); exit (EXIT_FAILURE); } free(privname); } int main (int argc, char **argv, char **envp) { set_identity (argv[0]); log_to (LOGTO_STDERR); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); parse_options (argc, argv, envp); if (show_version) { printf (_("%s version %s (built %s %s, protocol version %d.%d)\n"), get_identity (), VERSION, __DATE__, __TIME__, PROTOCOL_MAJOR, PROTOCOL_MINOR); printf (_("Built with kernel interface %s/%s.\n"), IFTYPE, IFSUBTYPE); printf (_ ("Copyright (C) 2003-2013 Marc Lehmann and others.\n" "See the AUTHORS file for a complete list.\n\n" "vpe comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" "see the file COPYING for details.\n")); return 0; } if (show_help) usage (0); { configuration_parser (conf, false, 0, 0); } if (debug_info) { printf ("cipher_nid=%d\n", EVP_CIPHER_nid (CIPHER ())); printf ("mac_nid=%d\n", EVP_MD_type (MAC_DIGEST ())); printf ("auth_nid=%d\n", EVP_MD_type (AUTH_DIGEST ())); printf ("sizeof_auth_data=%d\n", sizeof (auth_data)); printf ("sizeof_rsa_data=%d\n", sizeof (rsa_data)); printf ("sizeof_rsa_data_extra_auth=%d\n", sizeof (((rsa_data *)0)->extra_auth)); printf ("raw_overhead=%d\n", VPE_OVERHEAD); printf ("vpn_overhead=%d\n", VPE_OVERHEAD + 6 + 6); printf ("udp_overhead=%d\n", UDP_OVERHEAD + VPE_OVERHEAD + 6 + 6); exit (EXIT_SUCCESS); } if (generate_key) { RAND_load_file (conf.seed_dev, SEED_SIZE); exit (keygen_one (generate_key)); } if (generate_keys) { RAND_load_file (conf.seed_dev, SEED_SIZE); exit (keygen_all ()); } if (kill_gvpe) exit (kill_other (kill_gvpe)); if (show_config) { conf.print (); exit (EXIT_SUCCESS); } usage (1); } gvpe-3.0/src/device-linux.C0000644000000000000000000001024612615056110012473 00000000000000/* device-linux.C -- Interaction with Linux tun/tap device Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef LINUX_IF_TUN_H # include LINUX_IF_TUN_H #else #include #endif #define DEFAULT_DEVICE "/dev/net/tun" #include "gettext.h" #include "conf.h" #if TEST_ETHEREMU # define IF_istun # include "ether_emu.C" #endif const char * tap_device::info () { return _("Linux tun/tap device"); } const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU"; } tap_device::tap_device () { struct ifreq ifr; device = (char *)DEFAULT_DEVICE; fd = open (device, O_RDWR); if (fd < 0) { slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno)); exit (EXIT_FAILURE); } memset (&ifr, 0, sizeof (ifr)); #if TEST_ETHEREMU ifr.ifr_flags = IFF_TUN | IFF_NO_PI; #else ifr.ifr_flags = IFF_TAP | IFF_NO_PI; #endif if (conf.ifname) strncpy (ifr.ifr_name, conf.ifname, IFNAMSIZ); else ifr.ifr_name[0] = 0; if (!ioctl (fd, TUNSETIFF, &ifr)) { strncpy (ifrname, ifr.ifr_name, IFNAMSIZ); ifrname [IFNAMSIZ] = 0; } else { slog (L_CRIT, _("unable to configure tun/tap interface, exiting: %s"), strerror (errno)); exit (EXIT_FAILURE); } #if 0 does not work id2mac (THISNODE->id, &ifr.ifr_hwaddr.sa_data); if (ioctl (fd, SIOCSIFHWADDR, &ifr)) { slog (L_ERR, _("cannot set MAC address for device %s, exiting: %s"), ifrname, strerror (errno)); exit (EXIT_FAILURE); } #endif if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0)) slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno)); slog (L_DEBUG, _("%s is a %s"), device, info ()); } tap_device::~tap_device () { close (fd); } tap_packet * tap_device::recv () { tap_packet *pkt = new tap_packet; #if TEST_ETHEREMU pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14); #else pkt->len = read (fd, &((*pkt)[0]), MAX_MTU); #endif if (pkt->len <= 0) { delete pkt; slog (L_ERR, _("error while reading from %s %s: %s"), info (), DEFAULT_DEVICE, strerror (errno)); return 0; } #if TEST_ETHEREMU pkt->len += 14; // assume ipv4 (*pkt)[12] = 0x08; (*pkt)[13] = 0x00; if (!ether_emu.tun_to_tap (pkt)) { delete pkt; return 0; } #endif return pkt; } void tap_device::send (tap_packet *pkt) { #if TEST_ETHEREMU if (ether_emu.tap_to_tun (pkt) && write (fd, &((*pkt)[14]), pkt->len - 14) < 0) #else if (write (fd, &((*pkt)[0]), pkt->len) < 0) #endif slog (L_ERR, _("can't write %d byte packet to %s %s: %s"), pkt->len, info (), DEFAULT_DEVICE, strerror (errno)); } gvpe-3.0/src/device-cygwin.C0000644000000000000000000002175512615056110012643 00000000000000/* device-cygwin.C -- Stub for Cygwin environment Copyright (C) 2003-2008 Marc Lehmann Copyright (C) 2002-2003 Ivo Timmermans , 2002-2003 Guus Sliepen This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ // unfortunately, there is be no way to set MAC addresses under windows, // and the default cipedrvr uses a different MAC address than we do, // so this module tries to fix mac addresses in packets and arp packets. // this is probably not very fast, but neither is cygwin nor poll. // // http://cipe-win32.sourceforge.net/ // a newer driver is available as part of the openvpn package: // http://openvpn.sf.net/ #include "config.h" #include #include #include #include #include #include #include #include #include "conf.h" #include "util.h" #include #include #include #define REG_CONTROL_NET "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" #define USERMODEDEVICEDIR "\\\\.\\" #define USERDEVICEDIR "\\??\\" #define TAPSUFFIX ".tap" #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD | 8000, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_LASTMAC TAP_CONTROL_CODE(0, METHOD_BUFFERED) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE(1, METHOD_BUFFERED) #define TAP_IOCTL_SET_STATISTICS TAP_CONTROL_CODE(2, METHOD_BUFFERED) #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(7, METHOD_BUFFERED) static const char * wstrerror (int err) { static char buf[1024]; if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof (buf), NULL)) { strncpy (buf, _("(unable to format errormessage)"), sizeof (buf)); }; char *nl; if ((nl = strchr (buf, '\r'))) *nl = '\0'; return buf; } static HANDLE device_handle = INVALID_HANDLE_VALUE; static mac local_mac; static tap_packet *rcv_pkt; static int iopipe[2]; static HANDLE pipe_handle, send_event, thread; static DWORD WINAPI read_thread(void *) { static OVERLAPPED overlapped; static DWORD dlen; static u32 len; static u8 data[MAX_MTU]; overlapped.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); for (;;) { if (!ReadFile (device_handle, data, MAX_MTU, &dlen, &overlapped)) { if (GetLastError () == ERROR_IO_PENDING) GetOverlappedResult (device_handle, &overlapped, &dlen, TRUE); else { slog (L_ERR, "WIN32 TAP: ReadFile returned error: %s", wstrerror (GetLastError ())); exit (EXIT_FAILURE); } } if (dlen > 0) { len = dlen; WriteFile (pipe_handle, &len, sizeof (len), &dlen, NULL); WriteFile (pipe_handle, data, len, &dlen, NULL); } } } const char * tap_device::info () { return _("cygwin cipe/openvpn tap device"); } const char * tap_device::if_up () { return ""; } tap_device::tap_device () { HKEY key, key2; int i; char regpath[1024]; char adapterid[1024]; BYTE adaptername[1024]; char tapname[1024]; DWORD len; bool found = false; int sock, err; /* Open registry and look for network adapters */ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_CONTROL_NET, 0, KEY_READ, &key)) { slog (L_ERR, _("WIN32 TAP: unable to read registry: %s"), wstrerror (GetLastError ())); exit (EXIT_FAILURE); } for (i = 0;; i++) { len = sizeof (adapterid); if (RegEnumKeyEx (key, i, adapterid, &len, 0, 0, 0, NULL)) break; /* Find out more about this adapter */ snprintf (regpath, sizeof (regpath), "%s\\%s\\Connection", REG_CONTROL_NET, adapterid); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; len = sizeof (adaptername); err = RegQueryValueEx (key2, "Name", 0, 0, adaptername, &len); RegCloseKey (key2); if (err) continue; if (conf.ifname) { if (strcmp (conf.ifname, adapterid)) continue; } else { found = true; break; } snprintf (tapname, sizeof (tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); if (device_handle != INVALID_HANDLE_VALUE) { found = true; break; } } RegCloseKey (key); if (!found) { slog (L_ERR, _("WIN32 TAP: no windows tap device found!")); exit (EXIT_FAILURE); } /* Try to open the corresponding tap device */ if (device_handle == INVALID_HANDLE_VALUE) { snprintf (tapname, sizeof (tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile (tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); } if (device_handle == INVALID_HANDLE_VALUE) { slog (L_ERR, _("WIN32 TAP: %s is not a usable windows tap device %s: %s"), adaptername, tapname, wstrerror (GetLastError ())); exit (EXIT_FAILURE); } strcpy (ifrname, (char *)tapname); /* Get MAC address from tap device */ if (!DeviceIoControl (device_handle, TAP_IOCTL_GET_MAC, &local_mac, sizeof (local_mac), &local_mac, sizeof (local_mac), &len, 0)) { slog (L_ERR, _("WIN32 TAP: could not get MAC address from windows tap device %s: %s"), adaptername, wstrerror (GetLastError ())); exit (EXIT_FAILURE); } pipe (iopipe); fd = iopipe[0]; pipe_handle = (HANDLE) get_osfhandle (iopipe[1]); send_event = CreateEvent (NULL, FALSE, FALSE, NULL); thread = CreateThread (NULL, 0, read_thread, NULL, 0, NULL); /* try to set driver media status to 'connected' */ ULONG status = TRUE; DeviceIoControl (device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof (status), &status, sizeof (status), &len, NULL); // ignore error here on purpose } tap_device::~tap_device () { close (iopipe[0]); close (iopipe[1]); CloseHandle (device_handle); CloseHandle (send_event); } tap_packet * tap_device::recv () { tap_packet *pkt = new tap_packet; if (sizeof (u32) != read (iopipe[0], &pkt->len, sizeof (u32))) { slog (L_ERR, _("WIN32 TAP: i/o thread delivered incomplete pkt length")); delete pkt; return 0; } if (pkt->len != read (iopipe[0], &((*pkt)[0]), pkt->len)) { slog (L_ERR, _("WIN32 TAP: i/o thread delivered incomplete pkt")); delete pkt; return 0; } id2mac (THISNODE->id, &((*pkt)[6])); if (pkt->is_arp ()) { if (!memcmp (&(*pkt)[22], &local_mac, sizeof (mac))) id2mac (THISNODE->id, &((*pkt)[22])); if (!memcmp (&(*pkt)[32], &local_mac, sizeof (mac))) id2mac (THISNODE->id, &((*pkt)[32])); } return pkt; } void tap_device::send (tap_packet * pkt) { memcpy (&(*pkt)[6], &local_mac, sizeof (mac)); if (pkt->is_arp ()) { if ((*pkt)[22] == 0xfe && (*pkt)[27] == THISNODE->id) memcpy (&(*pkt)[22], &local_mac, sizeof (mac)); if ((*pkt)[32] == 0xfe && (*pkt)[37] == THISNODE->id) memcpy (&(*pkt)[32], &local_mac, sizeof (mac)); } DWORD dlen; OVERLAPPED overlapped; overlapped.hEvent = send_event; if (!WriteFile (device_handle, &((*pkt)[0]), pkt->len, &dlen, &overlapped)) { if (GetLastError () == ERROR_IO_PENDING) GetOverlappedResult (device_handle, &overlapped, &dlen, TRUE); else slog (L_ERR, _("WIN32 TAP: can't write to %s %s: %s"), info (), conf.ifname, wstrerror (GetLastError ())); } } gvpe-3.0/src/device-tincd.C0000644000000000000000000001341512615056110012436 00000000000000/* device-tincd.C -- include one of the tincd low level implementations. Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include #include #include #include #include #include #include #include #include #include "conf.h" // following headers used by cygwin (maybe others) #include "netcompat.h" #include #define xstrdup(strd) strdup(str) /* make the tincd sources feel comfortable in our environment. */ /* this was reasonably easy to do. */ #define routing_mode 1 #define RMODE_ROUTER 0 #define LOG_TO_L(level) \ (level) == LOG_ERR ? L_ERR \ : (level) == LOG_DEBUG ? L_DEBUG \ : (level) == LOG_WARNING ? L_WARN \ : (level) == LOG_INFO ? L_INFO \ : L_NOTICE #if __STDC_VERSION__ > 199900 # define logger(level, ...) slog (LOG_TO_L(level), __VA_ARGS__) #elif __GNUC__ # define logger(level, args...) slog (LOG_TO_L(level), ## args) #else # error either need ISO-C 99 compliant compiler or gcc. #endif #define ifdebug(subsys) if (0) #define cp() #define lookup_config(config_tree,key) (key) #define MTU MAX_MTU // BIGGEST hack of 'em all // will be casted to data_packet, due to structural similarity struct vpn_packet_t : net_packet { u8 data[MAXSIZE]; }; static bool overwrite_mac; static bool get_config_string(const char *key, char **res) { if (!strcmp (key, "Interface")) *res = conf.ifname; else if (!strcmp (key, "Device")) *res = 0; else if (!strcmp (key, "DeviceType")) *res = "tap"; else { slog (L_ERR, _("tincd layer asking for unknown config '%s'"), key); *res = 0; } return *res; } #define netname conf.ifname #if IF_linux # include "tincd/linux/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU"; } #elif IF_bsd # include "tincd/bsd/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; } #elif IF_freebsd # include "tincd/freebsd/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; } #elif IF_netbsd # define IF_istun 1 # include "tincd/netbsd/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME mtu $MTU"; } #elif IF_openbsd # define IF_istun 1 # include "tincd/openbsd/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME mtu $MTU"; } #elif IF_solaris # define IF_istun 1 # include "tincd/solaris/device.c" const char * tap_device::if_up () { return ""; } #elif IF_cygwin # include "tincd/cygwin/device.c" const char * tap_device::if_up () { return ""; } #elif IF_mingw # include "tincd/mingw/device.c" const char * tap_device::if_up () { return ""; } #elif IF_darwin # define IF_istun 1 # include "tincd/darwin/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; } #elif IF_raw_socket # include "tincd/raw_socket/device.c" const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; } #elif IF_uml_socket # include "tincd/uml_socket/device.c" const char * tap_device::if_up () { return 0; } #else # error No interface implementation for your IFTYPE/IFSUBTYPE combination. #endif #if IF_istun # include "ether_emu.C" #endif const char * tap_device::info () { return _("tincd compatibility layer"); } tap_device::tap_device () { device = "(null)"; bool ok = setup_device (); if (device_info) device = device_info; if (ok) { slog (L_DEBUG, _("interface %s on %s initialized"), info (), device); fd = device_fd; strcpy (ifrname, iface); } else { slog (L_ERR, _("error while configuring tincd device %s on %s"), info (), device); exit (EXIT_FAILURE); } } tap_device::~tap_device () { close_device (); } tap_packet * tap_device::recv () { tap_packet *pkt = new tap_packet; if (!read_packet (reinterpret_cast(pkt))) { delete pkt; slog (L_ERR, _("can't read from to %s %s: %s"), info (), device, strerror (errno)); return 0; } #if IF_istun // assume ipv4 (*pkt)[12] = 0x08; (*pkt)[13] = 0x00; if (!ether_emu.tun_to_tap (pkt)) { delete pkt; return 0; } #endif return pkt; } void tap_device::send (tap_packet *pkt) { if ( #if IF_istun ether_emu.tap_to_tun (pkt) && #endif !write_packet (reinterpret_cast(pkt))) slog (L_ERR, _("can't write to %s %s: %s"), info (), device, strerror (errno)); } gvpe-3.0/src/device-darwin.C0000644000000000000000000000561012615056110012617 00000000000000/* device-darwin.C -- device driver for mac os x Copyright (C) 2003-2008 Marc Lehmann This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ // uses the kernel driver at: // http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ #include #include #include #include #include #include #include #include #include #include "conf.h" // following headers used by cygwin (maybe others) #include "netcompat.h" #include #define DEFAULT_DEVICE "/dev/tap0" const char * tap_device::info () { return _("darwin tap driver"); } const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; } tap_device::tap_device () { const char *device = conf.ifname ? conf.ifname : DEFAULT_DEVICE; if ((fd = open (device, O_RDWR | O_NONBLOCK)) < 0) { slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno)); exit (EXIT_FAILURE); } slog (L_DEBUG, _("interface %s on %s initialized"), info (), device); strcpy (ifrname, rindex(device, '/') ? rindex(device, '/') + 1 : device); } tap_device::~tap_device () { close (fd); } tap_packet * tap_device::recv () { tap_packet *pkt = new tap_packet; pkt->len = read (fd, &((*pkt)[0]), MAX_MTU); if (pkt->len <= 0) { delete pkt; slog (L_ERR, _("error while reading from %s %s: %s"), info (), DEFAULT_DEVICE, strerror (errno)); return 0; } return pkt; } void tap_device::send (tap_packet *pkt) { if (write (fd, &((*pkt)[0]), pkt->len) < 0) slog (L_ERR, _("can't write to %s %s: %s"), info (), DEFAULT_DEVICE, strerror (errno)); } gvpe-3.0/src/callback.pl0000744000000000000000000000551611046632045012075 00000000000000#!/usr/bin/perl use strict; print < * * This file is part of GVPE. * * 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 3 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, see . * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with the OpenSSL project's OpenSSL library (or a modified * version of that library), containing parts covered by the terms of the * OpenSSL or SSLeay licenses, the licensors of this Program grant you * additional permission to convey the resulting work. Corresponding * Source for a non-source form of such a combination shall include the * source code for the parts of OpenSSL used as well as that of the * covered work. */ #ifndef CALLBACK_H__ #define CALLBACK_H__ #define CALLBACK_H_VERSION 3 template struct callback; EOF for my $a (0..10) { my $CLASS = join "", map ", class A$_", 1..$a; my $TYPE = join ", ", map "A$_", 1..$a; my $ARG = join ", ", map "a$_", 1..$a; my $TYPEARG = join ", ", map "A$_ a$_", 1..$a; my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a; my $TYPEvoid = $TYPE ? $TYPE : "void"; my $_ARG = $ARG ? ", $ARG" : ""; my $_TYPE = $TYPE ? ", $TYPE" : ""; my $_TYPEARG = $TYPEARG ? ", $TYPEARG" : ""; my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : ""; print < struct callback { typedef R (*ptr_type)(void *self$_TYPE); template void set (K *object) { self = object; func = thunk; } R call ($TYPEARG) const { return func (self$_ARG); } R operator ()($TYPEARG) const { return call ($ARG); } private: void *self; ptr_type func; template static R thunk (void *self$_TYPEARG) { klass *obj = static_cast(self); return (obj->*method) ($ARG); } }; EOF } print < This file is part of GVPE. GVPE 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 3 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, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. */ #include "config.h" #include #include "vpn.h" extern struct vpn network; struct ether_emu : map { typedef map ipv4map; ipv4map ipv4; bool tun_to_tap (tap_packet *pkt); bool tap_to_tun (tap_packet *pkt); void set_ipv4 (u32 ip, int dst) { (ipv4.insert (pair(ip, dst)).first)->second = dst; } }; static struct ether_emu ether_emu; bool ether_emu::tun_to_tap (tap_packet *pkt) { int dst; if (pkt->is_ipv4 ()) { // update arp cache for _local_ hosts set_ipv4 (pkt->ipv4_src (), THISNODE->id); ipv4map::iterator i = ipv4.find (pkt->ipv4_dst ()); if (i == ipv4.end ()) { u32 ip_src = pkt->ipv4_src (); u32 ip_dst = pkt->ipv4_dst (); // throw away current packet and make it an arp request (*pkt)[12] = 0x08; (*pkt)[13] = 0x06; (*pkt)[14] = 0x00; (*pkt)[15] = 0x01; // hw (*pkt)[16] = 0x08; (*pkt)[17] = 0x00; // prot (*pkt)[18] = 0x06; // hw_len (*pkt)[19] = 0x04; // prot_len (*pkt)[20] = 0x00; (*pkt)[21] = 0x01; // op id2mac (THISNODE->id, &(*pkt)[22]); *(u32 *)&(*pkt)[28] = ip_src; id2mac (0, &(*pkt)[32]); *(u32 *)&(*pkt)[38] = ip_dst; pkt->len = 42; dst = 0; } else dst = i->second; } else dst = 0; // broadcast non-ip id2mac (THISNODE->id, pkt->src); id2mac (dst, pkt->dst); return true; } bool ether_emu::tap_to_tun (tap_packet *pkt) { if (pkt->is_arp ()) { u32 ip_src = *(u32 *)&(*pkt)[28]; // always update with all info we can get. in this case, the arp sender. set_ipv4 (ip_src, mac2id (&(*pkt)[22])); //TODO: remove cache dumper //for (ipv4map::iterator i = ipv4.begin (); i != ipv4.end (); ++i) printf ("%08lx => %d\n", i->first, i->second); if ((*pkt)[20] == 0x00 && (*pkt)[21] == 0x01) // arp request { // send a reply, if applicable u32 ip_dst = *(u32 *)&(*pkt)[38]; ipv4map::iterator i = ipv4.find (ip_dst); // TODO: look up list of local networks and answer for them if (i != ipv4.end () && i->second == THISNODE->id) { // create an arp reply tap_packet *rep = new tap_packet; id2mac (THISNODE->id, rep->src); memcpy (rep->dst, pkt->src, sizeof (mac)); (*rep)[12] = 0x08; (*rep)[13] = 0x06; (*rep)[14] = 0x00; (*rep)[15] = 0x01; // hw (*rep)[16] = 0x08; (*rep)[17] = 0x00; // prot (*rep)[18] = 0x06; // hw_len (*rep)[19] = 0x04; // prot_len (*rep)[20] = 0x00; (*rep)[21] = 0x02; // op id2mac (THISNODE->id, &(*rep)[22]); *(u32 *)&(*rep)[28] = ip_dst; memcpy (&(*rep)[32], &(*pkt)[22], sizeof (mac)); *(u32 *)&(*rep)[38] = ip_src; rep->len = 42; network.inject_data_packet (rep, mac2id (rep->dst)); delete rep; } } else if ((*pkt)[20] == 0x00 && (*pkt)[21] == 0x02) // arp reply set_ipv4 (*(u32 *)&(*pkt)[28], mac2id (&(*pkt)[22])); return false; } else if (pkt->is_ipv4 ()) { // update arp cache set_ipv4 (pkt->ipv4_src (), mac2id (pkt->src)); set_ipv4 (pkt->ipv4_dst (), mac2id (pkt->dst)); } return true; } gvpe-3.0/src/curve25519-donna.c0000644000000000000000000007572312456410433013006 00000000000000/* Copyright 2008, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * curve25519-donna: Curve25519 elliptic curve, public key function * * http://code.google.com/p/curve25519-donna/ * * Adam Langley * * Derived from public domain C code by Daniel J. Bernstein * * More information about curve25519 can be found here * http://cr.yp.to/ecdh.html * * djb's sample implementation of curve25519 is written in a special assembly * language called qhasm and uses the floating point registers. * * This is, almost, a clean room reimplementation from the curve25519 paper. It * uses many of the tricks described therein. Only the crecip function is taken * from the sample implementation. */ #include #include #ifdef _MSC_VER #define inline __inline #endif typedef uint8_t u8; typedef int32_t s32; typedef int64_t limb; /* Field element representation: * * Field elements are written as an array of signed, 64-bit limbs, least * significant first. The value of the field element is: * x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ... * * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */ /* Sum two numbers: output += in */ static void fsum(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; i += 2) { output[0+i] = output[0+i] + in[0+i]; output[1+i] = output[1+i] + in[1+i]; } } /* Find the difference of two numbers: output = in - output * (note the order of the arguments!). */ static void fdifference(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; ++i) { output[i] = in[i] - output[i]; } } /* Multiply a number by a scalar: output = in * scalar */ static void fscalar_product(limb *output, const limb *in, const limb scalar) { unsigned i; for (i = 0; i < 10; ++i) { output[i] = in[i] * scalar; } } /* Multiply two numbers: output = in2 * in * * output must be distinct to both inputs. The inputs are reduced coefficient * form, the output is not. * * output[x] <= 14 * the largest product of the input limbs. */ static void fproduct(limb *output, const limb *in2, const limb *in) { output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + ((limb) ((s32) in2[1])) * ((s32) in[0]); output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[2]) + ((limb) ((s32) in2[2])) * ((s32) in[0]); output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) + ((limb) ((s32) in2[2])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[0]); output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) + 2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[1])) + ((limb) ((s32) in2[0])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[0]); output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[0]); output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[1])) + ((limb) ((s32) in2[2])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[2]) + ((limb) ((s32) in2[0])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[0]); output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[0]); output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) + 2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[1])) + ((limb) ((s32) in2[2])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[2]) + ((limb) ((s32) in2[0])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[0]); output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[4]) + ((limb) ((s32) in2[3])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[0]); output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) + ((limb) ((s32) in2[3])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[1])) + ((limb) ((s32) in2[4])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[4]) + ((limb) ((s32) in2[2])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[2]); output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[5]) + ((limb) ((s32) in2[4])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[4]) + ((limb) ((s32) in2[3])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[2]); output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) + 2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[5]) + ((limb) ((s32) in2[3])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[3])) + ((limb) ((s32) in2[4])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[4]); output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[6]) + ((limb) ((s32) in2[5])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[5]) + ((limb) ((s32) in2[4])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[4]); output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) + ((limb) ((s32) in2[5])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[5])) + ((limb) ((s32) in2[6])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[6]); output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[7]) + ((limb) ((s32) in2[6])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[6]); output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) + 2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[7])); output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[8]); output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); } /* Reduce a long form to a short form by taking the input mod 2^255 - 19. * * On entry: |output[i]| < 14*2^54 * On exit: |output[0..8]| < 280*2^54 */ static void freduce_degree(limb *output) { /* Each of these shifts and adds ends up multiplying the value by 19. * * For output[0..8], the absolute entry value is < 14*2^54 and we add, at * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */ output[8] += output[18] << 4; output[8] += output[18] << 1; output[8] += output[18]; output[7] += output[17] << 4; output[7] += output[17] << 1; output[7] += output[17]; output[6] += output[16] << 4; output[6] += output[16] << 1; output[6] += output[16]; output[5] += output[15] << 4; output[5] += output[15] << 1; output[5] += output[15]; output[4] += output[14] << 4; output[4] += output[14] << 1; output[4] += output[14]; output[3] += output[13] << 4; output[3] += output[13] << 1; output[3] += output[13]; output[2] += output[12] << 4; output[2] += output[12] << 1; output[2] += output[12]; output[1] += output[11] << 4; output[1] += output[11] << 1; output[1] += output[11]; output[0] += output[10] << 4; output[0] += output[10] << 1; output[0] += output[10]; } #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif /* return v / 2^26, using only shifts and adds. * * On entry: v can take any value. */ static inline limb div_by_2_26(const limb v) { /* High word of v; no shift needed. */ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); /* Set to all 1s if v was negative; else set to 0s. */ const int32_t sign = ((int32_t) highword) >> 31; /* Set to 0x3ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 6; /* Should return v / (1<<26) */ return (v + roundoff) >> 26; } /* return v / (2^25), using only shifts and adds. * * On entry: v can take any value. */ static inline limb div_by_2_25(const limb v) { /* High word of v; no shift needed*/ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); /* Set to all 1s if v was negative; else set to 0s. */ const int32_t sign = ((int32_t) highword) >> 31; /* Set to 0x1ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 7; /* Should return v / (1<<25) */ return (v + roundoff) >> 25; } /* Reduce all coefficients of the short form input so that |x| < 2^26. * * On entry: |output[i]| < 280*2^54 */ static void freduce_coefficients(limb *output) { unsigned i; output[10] = 0; for (i = 0; i < 10; i += 2) { limb over = div_by_2_26(output[i]); /* The entry condition (that |output[i]| < 280*2^54) means that over is, at * most, 280*2^28 in the first iteration of this loop. This is added to the * next limb and we can approximate the resulting bound of that limb by * 281*2^54. */ output[i] -= over << 26; output[i+1] += over; /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < * 281*2^29. When this is added to the next limb, the resulting bound can * be approximated as 281*2^54. * * For subsequent iterations of the loop, 281*2^54 remains a conservative * bound and no overflow occurs. */ over = div_by_2_25(output[i+1]); output[i+1] -= over << 25; output[i+2] += over; } /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ output[0] += output[10] << 4; output[0] += output[10] << 1; output[0] += output[10]; output[10] = 0; /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 * So |over| will be no more than 2^16. */ { limb over = div_by_2_26(output[0]); output[0] -= over << 26; output[1] += over; } /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The * bound on |output[1]| is sufficient to meet our needs. */ } /* A helpful wrapper around fproduct: output = in * in2. * * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27. * * output must be distinct to both inputs. The output is reduced degree * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */ static void fmul(limb *output, const limb *in, const limb *in2) { limb t[19]; fproduct(t, in, in2); /* |t[i]| < 14*2^54 */ freduce_degree(t); freduce_coefficients(t); /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } /* Square a number: output = in**2 * * output must be distinct from the input. The inputs are reduced coefficient * form, the output is not. * * output[x] <= 14 * the largest product of the input limbs. */ static void fsquare_inner(limb *output, const limb *in) { output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + ((limb) ((s32) in[0])) * ((s32) in[2])); output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) + ((limb) ((s32) in[0])) * ((s32) in[3])); output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) + 4 * ((limb) ((s32) in[1])) * ((s32) in[3]) + 2 * ((limb) ((s32) in[0])) * ((s32) in[4]); output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) + ((limb) ((s32) in[1])) * ((s32) in[4]) + ((limb) ((s32) in[0])) * ((s32) in[5])); output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) + ((limb) ((s32) in[2])) * ((s32) in[4]) + ((limb) ((s32) in[0])) * ((s32) in[6]) + 2 * ((limb) ((s32) in[1])) * ((s32) in[5])); output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) + ((limb) ((s32) in[2])) * ((s32) in[5]) + ((limb) ((s32) in[1])) * ((s32) in[6]) + ((limb) ((s32) in[0])) * ((s32) in[7])); output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) + 2 * (((limb) ((s32) in[2])) * ((s32) in[6]) + ((limb) ((s32) in[0])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[1])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[5]))); output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) + ((limb) ((s32) in[3])) * ((s32) in[6]) + ((limb) ((s32) in[2])) * ((s32) in[7]) + ((limb) ((s32) in[1])) * ((s32) in[8]) + ((limb) ((s32) in[0])) * ((s32) in[9])); output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) + ((limb) ((s32) in[4])) * ((s32) in[6]) + ((limb) ((s32) in[2])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[3])) * ((s32) in[7]) + ((limb) ((s32) in[1])) * ((s32) in[9]))); output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) + ((limb) ((s32) in[4])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[8]) + ((limb) ((s32) in[2])) * ((s32) in[9])); output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) + 2 * (((limb) ((s32) in[4])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[5])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[9]))); output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) + ((limb) ((s32) in[5])) * ((s32) in[8]) + ((limb) ((s32) in[4])) * ((s32) in[9])); output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) + ((limb) ((s32) in[6])) * ((s32) in[8]) + 2 * ((limb) ((s32) in[5])) * ((s32) in[9])); output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) + ((limb) ((s32) in[6])) * ((s32) in[9])); output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) + 4 * ((limb) ((s32) in[7])) * ((s32) in[9]); output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]); output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); } /* fsquare sets output = in^2. * * On entry: The |in| argument is in reduced coefficients form and |in[i]| < * 2^27. * * On exit: The |output| argument is in reduced coefficients form (indeed, one * need only provide storage for 10 limbs) and |out[i]| < 2^26. */ static void fsquare(limb *output, const limb *in) { limb t[19]; fsquare_inner(t, in); /* |t[i]| < 14*2^54 because the largest product of two limbs will be < * 2^(27+27) and fsquare_inner adds together, at most, 14 of those * products. */ freduce_degree(t); freduce_coefficients(t); /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } /* Take a little-endian, 32-byte number and expand it into polynomial form */ static void fexpand(limb *output, const u8 *input) { #define F(n,start,shift,mask) \ output[n] = ((((limb) input[start + 0]) | \ ((limb) input[start + 1]) << 8 | \ ((limb) input[start + 2]) << 16 | \ ((limb) input[start + 3]) << 24) >> shift) & mask; F(0, 0, 0, 0x3ffffff); F(1, 3, 2, 0x1ffffff); F(2, 6, 3, 0x3ffffff); F(3, 9, 5, 0x1ffffff); F(4, 12, 6, 0x3ffffff); F(5, 16, 0, 0x1ffffff); F(6, 19, 1, 0x3ffffff); F(7, 22, 3, 0x1ffffff); F(8, 25, 4, 0x3ffffff); F(9, 28, 6, 0x1ffffff); #undef F } #if (-32 >> 1) != -16 #error "This code only works when >> does sign-extension on negative numbers" #endif /* s32_eq returns 0xffffffff iff a == b and zero otherwise. */ static s32 s32_eq(s32 a, s32 b) { a = ~(a ^ b); a &= a << 16; a &= a << 8; a &= a << 4; a &= a << 2; a &= a << 1; return a >> 31; } /* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are * both non-negative. */ static s32 s32_gte(s32 a, s32 b) { a -= b; /* a >= 0 iff a >= b. */ return ~(a >> 31); } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array. * * On entry: |input_limbs[i]| < 2^26 */ static void fcontract(u8 *output, limb *input_limbs) { int i; int j; s32 input[10]; s32 mask; /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ for (i = 0; i < 10; i++) { input[i] = input_limbs[i]; } for (j = 0; j < 2; ++j) { for (i = 0; i < 9; ++i) { if ((i & 1) == 1) { /* This calculation is a time-invariant way to make input[i] * non-negative by borrowing from the next-larger limb. */ const s32 mask = input[i] >> 31; const s32 carry = -((input[i] & mask) >> 25); input[i] = input[i] + (carry << 25); input[i+1] = input[i+1] - carry; } else { const s32 mask = input[i] >> 31; const s32 carry = -((input[i] & mask) >> 26); input[i] = input[i] + (carry << 26); input[i+1] = input[i+1] - carry; } } /* There's no greater limb for input[9] to borrow from, but we can multiply * by 19 and borrow from input[0], which is valid mod 2^255-19. */ { const s32 mask = input[9] >> 31; const s32 carry = -((input[9] & mask) >> 25); input[9] = input[9] + (carry << 25); input[0] = input[0] - (carry * 19); } /* After the first iteration, input[1..9] are non-negative and fit within * 25 or 26 bits, depending on position. However, input[0] may be * negative. */ } /* The first borrow-propagation pass above ended with every limb except (possibly) input[0] non-negative. If input[0] was negative after the first pass, then it was because of a carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. In the second pass, each limb is decreased by at most one. Thus the second borrow-propagation pass could only have wrapped around to decrease input[0] again if the first pass left input[0] negative *and* input[1] through input[9] were all zero. In that case, input[1] is now 2^25 - 1, and this last borrow-propagation step will leave input[1] non-negative. */ { const s32 mask = input[0] >> 31; const s32 carry = -((input[0] & mask) >> 26); input[0] = input[0] + (carry << 26); input[1] = input[1] - carry; } /* All input[i] are now non-negative. However, there might be values between * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ for (j = 0; j < 2; j++) { for (i = 0; i < 9; i++) { if ((i & 1) == 1) { const s32 carry = input[i] >> 25; input[i] &= 0x1ffffff; input[i+1] += carry; } else { const s32 carry = input[i] >> 26; input[i] &= 0x3ffffff; input[i+1] += carry; } } { const s32 carry = input[9] >> 25; input[9] &= 0x1ffffff; input[0] += 19*carry; } } /* If the first carry-chain pass, just above, ended up with a carry from * input[9], and that caused input[0] to be out-of-bounds, then input[0] was * < 2^26 + 2*19, because the carry was, at most, two. * * If the second pass carried from input[9] again then input[0] is < 2*19 and * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ /* It still remains the case that input might be between 2^255-19 and 2^255. * In this case, input[1..9] must take their maximum value and input[0] must * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ mask = s32_gte(input[0], 0x3ffffed); for (i = 1; i < 10; i++) { if ((i & 1) == 1) { mask &= s32_eq(input[i], 0x1ffffff); } else { mask &= s32_eq(input[i], 0x3ffffff); } } /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus * this conditionally subtracts 2^255-19. */ input[0] -= mask & 0x3ffffed; for (i = 1; i < 10; i++) { if ((i & 1) == 1) { input[i] -= mask & 0x1ffffff; } else { input[i] -= mask & 0x3ffffff; } } input[1] <<= 2; input[2] <<= 3; input[3] <<= 5; input[4] <<= 6; input[6] <<= 1; input[7] <<= 3; input[8] <<= 4; input[9] <<= 6; #define F(i, s) \ output[s+0] |= input[i] & 0xff; \ output[s+1] = (input[i] >> 8) & 0xff; \ output[s+2] = (input[i] >> 16) & 0xff; \ output[s+3] = (input[i] >> 24) & 0xff; output[0] = 0; output[16] = 0; F(0,0); F(1,3); F(2,6); F(3,9); F(4,12); F(5,16); F(6,19); F(7,22); F(8,25); F(9,28); #undef F } /* Input: Q, Q', Q-Q' * Output: 2Q, Q+Q' * * x2 z3: long form * x3 z3: long form * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved * * On entry and exit, the absolute value of the limbs of all inputs and outputs * are < 2^26. */ static void fmonty(limb *x2, limb *z2, /* output 2Q */ limb *x3, limb *z3, /* output Q + Q' */ limb *x, limb *z, /* input Q */ limb *xprime, limb *zprime, /* input Q' */ const limb *qmqp /* input Q - Q' */) { limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], zzprime[19], zzzprime[19], xxxprime[19]; memcpy(origx, x, 10 * sizeof(limb)); fsum(x, z); /* |x[i]| < 2^27 */ fdifference(z, origx); /* does x - z */ /* |z[i]| < 2^27 */ memcpy(origxprime, xprime, sizeof(limb) * 10); fsum(xprime, zprime); /* |xprime[i]| < 2^27 */ fdifference(zprime, origxprime); /* |zprime[i]| < 2^27 */ fproduct(xxprime, xprime, z); /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < * 2^(27+27) and fproduct adds together, at most, 14 of those products. * (Approximating that to 2^58 doesn't work out.) */ fproduct(zzprime, x, zprime); /* |zzprime[i]| < 14*2^54 */ freduce_degree(xxprime); freduce_coefficients(xxprime); /* |xxprime[i]| < 2^26 */ freduce_degree(zzprime); freduce_coefficients(zzprime); /* |zzprime[i]| < 2^26 */ memcpy(origxprime, xxprime, sizeof(limb) * 10); fsum(xxprime, zzprime); /* |xxprime[i]| < 2^27 */ fdifference(zzprime, origxprime); /* |zzprime[i]| < 2^27 */ fsquare(xxxprime, xxprime); /* |xxxprime[i]| < 2^26 */ fsquare(zzzprime, zzprime); /* |zzzprime[i]| < 2^26 */ fproduct(zzprime, zzzprime, qmqp); /* |zzprime[i]| < 14*2^52 */ freduce_degree(zzprime); freduce_coefficients(zzprime); /* |zzprime[i]| < 2^26 */ memcpy(x3, xxxprime, sizeof(limb) * 10); memcpy(z3, zzprime, sizeof(limb) * 10); fsquare(xx, x); /* |xx[i]| < 2^26 */ fsquare(zz, z); /* |zz[i]| < 2^26 */ fproduct(x2, xx, zz); /* |x2[i]| < 14*2^52 */ freduce_degree(x2); freduce_coefficients(x2); /* |x2[i]| < 2^26 */ fdifference(zz, xx); // does zz = xx - zz /* |zz[i]| < 2^27 */ memset(zzz + 10, 0, sizeof(limb) * 9); fscalar_product(zzz, zz, 121665); /* |zzz[i]| < 2^(27+17) */ /* No need to call freduce_degree here: fscalar_product doesn't increase the degree of its input. */ freduce_coefficients(zzz); /* |zzz[i]| < 2^26 */ fsum(zzz, xx); /* |zzz[i]| < 2^27 */ fproduct(z2, zz, zzz); /* |z2[i]| < 14*2^(26+27) */ freduce_degree(z2); freduce_coefficients(z2); /* |z2|i| < 2^26 */ } /* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave * them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid * side-channel attacks. * * NOTE that this function requires that 'iswap' be 1 or 0; other values give * wrong results. Also, the two limb arrays must be in reduced-coefficient, * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped, * and all all values in a[0..9],b[0..9] must have magnitude less than * INT32_MAX. */ static void swap_conditional(limb a[19], limb b[19], limb iswap) { unsigned i; const s32 swap = (s32) -iswap; for (i = 0; i < 10; ++i) { const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) ); a[i] = ((s32)a[i]) ^ x; b[i] = ((s32)b[i]) ^ x; } } /* Calculates nQ where Q is the x-coordinate of a point on the curve * * resultx/resultz: the x coordinate of the resulting curve point (short form) * n: a little endian, 32-byte number * q: a point of the curve (short form) */ static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0}; limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1}; limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; unsigned i, j; memcpy(nqpqx, q, sizeof(limb) * 10); for (i = 0; i < 32; ++i) { u8 byte = n[31 - i]; for (j = 0; j < 8; ++j) { const limb bit = byte >> 7; swap_conditional(nqx, nqpqx, bit); swap_conditional(nqz, nqpqz, bit); fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); swap_conditional(nqx2, nqpqx2, bit); swap_conditional(nqz2, nqpqz2, bit); t = nqx; nqx = nqx2; nqx2 = t; t = nqz; nqz = nqz2; nqz2 = t; t = nqpqx; nqpqx = nqpqx2; nqpqx2 = t; t = nqpqz; nqpqz = nqpqz2; nqpqz2 = t; byte <<= 1; } } memcpy(resultx, nqx, sizeof(limb) * 10); memcpy(resultz, nqz, sizeof(limb) * 10); } // ----------------------------------------------------------------------------- // Shamelessly copied from djb's code // ----------------------------------------------------------------------------- static void crecip(limb *out, const limb *z) { limb z2[10]; limb z9[10]; limb z11[10]; limb z2_5_0[10]; limb z2_10_0[10]; limb z2_20_0[10]; limb z2_50_0[10]; limb z2_100_0[10]; limb t0[10]; limb t1[10]; int i; /* 2 */ fsquare(z2,z); /* 4 */ fsquare(t1,z2); /* 8 */ fsquare(t0,t1); /* 9 */ fmul(z9,t0,z); /* 11 */ fmul(z11,z9,z2); /* 22 */ fsquare(t0,z11); /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9); /* 2^6 - 2^1 */ fsquare(t0,z2_5_0); /* 2^7 - 2^2 */ fsquare(t1,t0); /* 2^8 - 2^3 */ fsquare(t0,t1); /* 2^9 - 2^4 */ fsquare(t1,t0); /* 2^10 - 2^5 */ fsquare(t0,t1); /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0); /* 2^11 - 2^1 */ fsquare(t0,z2_10_0); /* 2^12 - 2^2 */ fsquare(t1,t0); /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0); /* 2^21 - 2^1 */ fsquare(t0,z2_20_0); /* 2^22 - 2^2 */ fsquare(t1,t0); /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0); /* 2^41 - 2^1 */ fsquare(t1,t0); /* 2^42 - 2^2 */ fsquare(t0,t1); /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0); /* 2^51 - 2^1 */ fsquare(t0,z2_50_0); /* 2^52 - 2^2 */ fsquare(t1,t0); /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0); /* 2^101 - 2^1 */ fsquare(t1,z2_100_0); /* 2^102 - 2^2 */ fsquare(t0,t1); /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0); /* 2^201 - 2^1 */ fsquare(t0,t1); /* 2^202 - 2^2 */ fsquare(t1,t0); /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0); /* 2^251 - 2^1 */ fsquare(t1,t0); /* 2^252 - 2^2 */ fsquare(t0,t1); /* 2^253 - 2^3 */ fsquare(t1,t0); /* 2^254 - 2^4 */ fsquare(t0,t1); /* 2^255 - 2^5 */ fsquare(t1,t0); /* 2^255 - 21 */ fmul(out,t1,z11); } int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[10], x[10], z[11], zmone[10]; uint8_t e[32]; int i; for (i = 0; i < 32; ++i) e[i] = secret[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); crecip(zmone, z); fmul(z, x, zmone); fcontract(mypublic, z); return 0; } gvpe-3.0/src/curve25519-donna-c64.c0000644000000000000000000003234312456416742013400 00000000000000/* Copyright 2008, Google Inc. * All rights reserved. * * Code released into the public domain. * * curve25519-donna: Curve25519 elliptic curve, public key function * * http://code.google.com/p/curve25519-donna/ * * Adam Langley * * Derived from public domain C code by Daniel J. Bernstein * * More information about curve25519 can be found here * http://cr.yp.to/ecdh.html * * djb's sample implementation of curve25519 is written in a special assembly * language called qhasm and uses the floating point registers. * * This is, almost, a clean room reimplementation from the curve25519 paper. It * uses many of the tricks described therein. Only the crecip function is taken * from the sample implementation. */ #include #include typedef uint8_t u8; typedef uint64_t limb; typedef limb felem[5]; // This is a special gcc mode for 128-bit integers. It's implemented on 64-bit // platforms only as far as I know. typedef unsigned uint128_t __attribute__((mode(TI))); #undef force_inline #define force_inline __attribute__((always_inline)) /* Sum two numbers: output += in */ static inline void force_inline fsum(limb *output, const limb *in) { output[0] += in[0]; output[1] += in[1]; output[2] += in[2]; output[3] += in[3]; output[4] += in[4]; } /* Find the difference of two numbers: output = in - output * (note the order of the arguments!) * * Assumes that out[i] < 2**52 * On return, out[i] < 2**55 */ static inline void force_inline fdifference_backwards(felem out, const felem in) { /* 152 is 19 << 3 */ static const limb two54m152 = (((limb)1) << 54) - 152; static const limb two54m8 = (((limb)1) << 54) - 8; out[0] = in[0] + two54m152 - out[0]; out[1] = in[1] + two54m8 - out[1]; out[2] = in[2] + two54m8 - out[2]; out[3] = in[3] + two54m8 - out[3]; out[4] = in[4] + two54m8 - out[4]; } /* Multiply a number by a scalar: output = in * scalar */ static inline void force_inline fscalar_product(felem output, const felem in, const limb scalar) { uint128_t a; a = ((uint128_t) in[0]) * scalar; output[0] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[1]) * scalar + ((limb) (a >> 51)); output[1] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[2]) * scalar + ((limb) (a >> 51)); output[2] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[3]) * scalar + ((limb) (a >> 51)); output[3] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[4]) * scalar + ((limb) (a >> 51)); output[4] = ((limb)a) & 0x7ffffffffffff; output[0] += (a >> 51) * 19; } /* Multiply two numbers: output = in2 * in * * output must be distinct to both inputs. The inputs are reduced coefficient * form, the output is not. * * Assumes that in[i] < 2**55 and likewise for in2. * On return, output[i] < 2**52 */ static inline void force_inline fmul(felem output, const felem in2, const felem in) { uint128_t t[5]; limb r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; s0 = in2[0]; s1 = in2[1]; s2 = in2[2]; s3 = in2[3]; s4 = in2[4]; t[0] = ((uint128_t) r0) * s0; t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0; t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1; t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1; t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2; r4 *= 19; r1 *= 19; r2 *= 19; r3 *= 19; t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2; t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3; t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4; t[3] += ((uint128_t) r4) * s4; r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51); t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51); t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51); t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51); t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff; r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff; r2 += c; output[0] = r0; output[1] = r1; output[2] = r2; output[3] = r3; output[4] = r4; } static inline void force_inline fsquare_times(felem output, const felem in, limb count) { uint128_t t[5]; limb r0,r1,r2,r3,r4,c; limb d0,d1,d2,d4,d419; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; do { d0 = r0 * 2; d1 = r1 * 2; d2 = r2 * 2 * 19; d419 = r4 * 19; d4 = d419 * 2; t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51); t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51); t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51); t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51); t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff; r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff; r2 += c; } while(--count); output[0] = r0; output[1] = r1; output[2] = r2; output[3] = r3; output[4] = r4; } /* Load a little-endian 64-bit number */ static limb load_limb(const u8 *in) { return ((limb)in[0]) | (((limb)in[1]) << 8) | (((limb)in[2]) << 16) | (((limb)in[3]) << 24) | (((limb)in[4]) << 32) | (((limb)in[5]) << 40) | (((limb)in[6]) << 48) | (((limb)in[7]) << 56); } static void store_limb(u8 *out, limb in) { out[0] = in & 0xff; out[1] = (in >> 8) & 0xff; out[2] = (in >> 16) & 0xff; out[3] = (in >> 24) & 0xff; out[4] = (in >> 32) & 0xff; out[5] = (in >> 40) & 0xff; out[6] = (in >> 48) & 0xff; out[7] = (in >> 56) & 0xff; } /* Take a little-endian, 32-byte number and expand it into polynomial form */ static void fexpand(limb *output, const u8 *in) { output[0] = load_limb(in) & 0x7ffffffffffff; output[1] = (load_limb(in+6) >> 3) & 0x7ffffffffffff; output[2] = (load_limb(in+12) >> 6) & 0x7ffffffffffff; output[3] = (load_limb(in+19) >> 1) & 0x7ffffffffffff; output[4] = (load_limb(in+24) >> 12) & 0x7ffffffffffff; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ static void fcontract(u8 *output, const felem input) { uint128_t t[5]; t[0] = input[0]; t[1] = input[1]; t[2] = input[2]; t[3] = input[3]; t[4] = input[4]; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; /* now t is between 0 and 2^255-1, properly carried. */ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ t[0] += 19; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; /* now between 19 and 2^255-1 in both cases, and offset by 19. */ t[0] += 0x8000000000000 - 19; t[1] += 0x8000000000000 - 1; t[2] += 0x8000000000000 - 1; t[3] += 0x8000000000000 - 1; t[4] += 0x8000000000000 - 1; /* now between 2^255 and 2^256-20, and offset by 2^255. */ t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[4] &= 0x7ffffffffffff; store_limb(output, t[0] | (t[1] << 51)); store_limb(output+8, (t[1] >> 13) | (t[2] << 38)); store_limb(output+16, (t[2] >> 26) | (t[3] << 25)); store_limb(output+24, (t[3] >> 39) | (t[4] << 12)); } /* Input: Q, Q', Q-Q' * Output: 2Q, Q+Q' * * x2 z3: long form * x3 z3: long form * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved */ static void fmonty(limb *x2, limb *z2, /* output 2Q */ limb *x3, limb *z3, /* output Q + Q' */ limb *x, limb *z, /* input Q */ limb *xprime, limb *zprime, /* input Q' */ const limb *qmqp /* input Q - Q' */) { limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], zzzprime[5]; memcpy(origx, x, 5 * sizeof(limb)); fsum(x, z); fdifference_backwards(z, origx); // does x - z memcpy(origxprime, xprime, sizeof(limb) * 5); fsum(xprime, zprime); fdifference_backwards(zprime, origxprime); fmul(xxprime, xprime, z); fmul(zzprime, x, zprime); memcpy(origxprime, xxprime, sizeof(limb) * 5); fsum(xxprime, zzprime); fdifference_backwards(zzprime, origxprime); fsquare_times(x3, xxprime, 1); fsquare_times(zzzprime, zzprime, 1); fmul(z3, zzzprime, qmqp); fsquare_times(xx, x, 1); fsquare_times(zz, z, 1); fmul(x2, xx, zz); fdifference_backwards(zz, xx); // does zz = xx - zz fscalar_product(zzz, zz, 121665); fsum(zzz, xx); fmul(z2, zz, zzz); } // ----------------------------------------------------------------------------- // Maybe swap the contents of two limb arrays (@a and @b), each @len elements // long. Perform the swap iff @swap is non-zero. // // This function performs the swap without leaking any side-channel // information. // ----------------------------------------------------------------------------- static void swap_conditional(limb a[5], limb b[5], limb iswap) { unsigned i; const limb swap = -iswap; for (i = 0; i < 5; ++i) { const limb x = swap & (a[i] ^ b[i]); a[i] ^= x; b[i] ^= x; } } /* Calculates nQ where Q is the x-coordinate of a point on the curve * * resultx/resultz: the x coordinate of the resulting curve point (short form) * n: a little endian, 32-byte number * q: a point of the curve (short form) */ static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { limb a[5] = {0}, b[5] = {1}, c[5] = {1}, d[5] = {0}; limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1}; limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; unsigned i, j; memcpy(nqpqx, q, sizeof(limb) * 5); for (i = 0; i < 32; ++i) { u8 byte = n[31 - i]; for (j = 0; j < 8; ++j) { const limb bit = byte >> 7; swap_conditional(nqx, nqpqx, bit); swap_conditional(nqz, nqpqz, bit); fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); swap_conditional(nqx2, nqpqx2, bit); swap_conditional(nqz2, nqpqz2, bit); t = nqx; nqx = nqx2; nqx2 = t; t = nqz; nqz = nqz2; nqz2 = t; t = nqpqx; nqpqx = nqpqx2; nqpqx2 = t; t = nqpqz; nqpqz = nqpqz2; nqpqz2 = t; byte <<= 1; } } memcpy(resultx, nqx, sizeof(limb) * 5); memcpy(resultz, nqz, sizeof(limb) * 5); } // ----------------------------------------------------------------------------- // Shamelessly copied from djb's code, tightened a little // ----------------------------------------------------------------------------- static void crecip(felem out, const felem z) { felem a,t0,b,c; /* 2 */ fsquare_times(a, z, 1); // a = 2 /* 8 */ fsquare_times(t0, a, 2); /* 9 */ fmul(b, t0, z); // b = 9 /* 11 */ fmul(a, b, a); // a = 11 /* 22 */ fsquare_times(t0, a, 1); /* 2^5 - 2^0 = 31 */ fmul(b, t0, b); /* 2^10 - 2^5 */ fsquare_times(t0, b, 5); /* 2^10 - 2^0 */ fmul(b, t0, b); /* 2^20 - 2^10 */ fsquare_times(t0, b, 10); /* 2^20 - 2^0 */ fmul(c, t0, b); /* 2^40 - 2^20 */ fsquare_times(t0, c, 20); /* 2^40 - 2^0 */ fmul(t0, t0, c); /* 2^50 - 2^10 */ fsquare_times(t0, t0, 10); /* 2^50 - 2^0 */ fmul(b, t0, b); /* 2^100 - 2^50 */ fsquare_times(t0, b, 50); /* 2^100 - 2^0 */ fmul(c, t0, b); /* 2^200 - 2^100 */ fsquare_times(t0, c, 100); /* 2^200 - 2^0 */ fmul(t0, t0, c); /* 2^250 - 2^50 */ fsquare_times(t0, t0, 50); /* 2^250 - 2^0 */ fmul(t0, t0, b); /* 2^255 - 2^5 */ fsquare_times(t0, t0, 5); /* 2^255 - 21 */ fmul(out, t0, a); } int curve25519_donna(u8 *, const u8 *, const u8 *); int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[5], x[5], z[5], zmone[5]; uint8_t e[32]; int i; for (i = 0;i < 32;++i) e[i] = secret[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); crecip(zmone, z); fmul(z, x, zmone); fcontract(mypublic, z); return 0; } gvpe-3.0/doc/0000755000000000000000000000000013011103357010023 500000000000000gvpe-3.0/doc/complex-example/0000755000000000000000000000000013011103357013123 500000000000000gvpe-3.0/doc/complex-example/README0000644000000000000000000000132610002074751013727 00000000000000These files are configuration files for "our" internal network. It is highly non-trivial, so don't use this configuration as the basis of your network unless you know what you are doing. It features: around 30 hosts, many of them have additional networks behind them and use an assortment of different tunneling protocols. The vpn is fully routed, no arp is used at all. The public IP addresses of connecting nodes are automatically registered via dns on the node ruth, using a node-up/node-down script. And last not least: the if-up script can generate information to be used in firewall rules (IP-net/MAC-address pairs) so ensure packet integrity so you can use your iptables etc. firewall to filter by IP address only. gvpe-3.0/doc/complex-example/if-up0000644000000000000000000001041710002074751014013 00000000000000#!/bin/bash # Some environment variables will be set: # # CONFBASE=/etc/vpe # the configuration directory prefix # IFNAME=vpn0 # the network interface (ifname) # MAC=fe:fd:80:00:00:01 # the mac-address to use for the interface # NODENAME=cerebro # the selected nodename (-n switch) # NODEID=1 # the numerical node id # MTU=1436 # the tunnel packet overhead (set mtu to 1500-$OVERHEAD) # this if-up script is rather full-featured, and is used to # generate a fully-routed (no arp traffic) vpn. the main portion # consists of "ipn" calls (see below). # some hosts require additional specific configuration, this is handled # using if statements near the end of the script. # with the --fw switch, outputs mac/net pairs for your firewall use: # if-up --fw | while read mac net; do # iptables -t filter -A INPUT -i vpn0 -p all -m mac --mac-source \! $mac -s $net -j DROP # done ipn() { local id="$1"; shift local mac=fe:fd:80:00:00:$(printf "%02x" $id) if [ -n "$FW" ]; then for net in "$@"; do echo "$mac $net" done else local ip="$1"; shift if [ "$id" == $NODEID ]; then [ -n "$ADDR_ONLY" ] && ip addr add $ip broadcast 10.255.255.255 dev $IFNAME elif [ -z "$ADDR_ONLY" ]; then ip neighbour add $ip lladdr $mac nud permanent dev $IFNAME for route in "$@"; do ip route add $route via $ip dev vpn0 done fi fi } ipns() { # this contains the generic routing information for the vpn # each call to ipn has the following parameters: # ipn [ ...] # the second line (ipn 2) means: # the second node (doom in the config file) has the ip address 10.0.0.5, # which is the gateway for the 10.0/28 network and three additional ip # addresses ipn 1 10.0.0.20 ipn 2 10.0.0.5 10.0.0.0/28 #200.100.162.92 200.100.162.93 100.99.218.222 ipn 3 10.0.0.17 ipn 4 10.0.0.18 ipn 5 10.0.0.19 10.3.0.0/16 ipn 6 10.0.0.21 10.0.2.0/26 #200.100.162.17 ipn 7 10.0.0.22 10.1.2.0/24 # wappla, off ipn 8 10.0.0.23 # stefan, off ipn 9 10.0.0.24 10.13.0.0/16 ipn 10 10.0.0.25 ipn 11 10.0.0.26 ipn 12 10.0.0.27 10.0.2.64/26 ipn 13 10.0.0.28 10.0.3.0/24 ipn 14 10.0.0.29 10.1.1.0/24 # fwkw, off # mind the gateway ip gap ipn 15 10.9.0.30 10.0.4.0/24 ipn 16 10.9.0.31 ipn 17 10.9.0.32 10.42.0.0/16 ipn 18 10.9.0.33 ipn 19 10.9.0.34 #ipn 20 10.9.0.35 } if [ "$1" == "--fw" ]; then FW=1 ipns else exec >/var/log/vpe.if-up 2>&1 set -x [ $NODENAME = "ruth" ] && ip link set $IFNAME down # hack # first set the link up and initialize the interface ip # address. ip link set $IFNAME address $MAC ip link set $IFNAME mtu $MTU up ADDR_ONLY=1 ipns # set addr only # now initialize the main vpn routes (10.0/8) # the second route is a hack to to reach some funnily-connected # machines. ip route add 10.0.0.0/8 dev $IFNAME ip route add 10.0.0.0/27 dev $IFNAME ipns # set the interface routes # now for something completely different, ehr, something not # easily doable with ipn, namely some extra specific highly complicated # and non-regular setups for some machines. if [ $NODENAME = doom ]; then ip addr add 200.100.162.92 dev $IFNAME ip route add 200.100.0.0/16 via 10.0.0.17 dev $IFNAME ip route flush table 101 ip route add table 101 default src 200.100.162.92 via 10.0.0.17 dev $IFNAME ip addr add 100.99.218.222 dev $IFNAME ip route add 100.99.218.192/27 via 10.0.0.19 dev $IFNAME ip route flush table 103 ip route add table 103 default src 100.99.218.222 via 10.0.0.19 elif [ $NODENAME = marco ]; then ip addr add 200.100.162.17 dev $IFNAME for addr in 79 89 90 91 92 93 94 95; do ip route add 200.100.162.$addr dev ppp0 done ip route add 200.100.76.0/23 dev ppp0 ip route add src 200.100.162.17 200.100.0.0/16 via 10.0.0.17 dev $IFNAME elif [ $NODENAME = ruth ]; then ip route add 200.100.162.17 via 10.0.0.21 dev vpn0 ip route add 200.100.162.92 via 10.0.0.5 dev vpn0 ip route add 200.100.162.93 via 10.0.0.5 dev vpn0 fi # and this is the second part of the 10.0/27 hack. don't ask. [ $NODENAME != fwkw ] && ip route add 10.0.0.0/24 via 10.0.0.29 dev $IFNAME fi gvpe-3.0/doc/complex-example/node-up0000644000000000000000000000157710002074751014351 00000000000000#!/bin/sh # Some environment variables will be set (in addition the ones # set in if-up, too): # # DESTNODE=doom # others nodename # DESTID=5 # others node id # DESTIP=188.13.66.8 # others ip # DESTPORT=407 # others port # STATE=up/down # node-up gets UP, node-down script gets DOWN if [ $STATE = up ]; then { echo update delete $DESTNODE.lowttl.example.com. a echo update delete $DESTNODE-last.lowttl.example.com. a echo update add $DESTNODE.lowttl.example.com. 1 in a $DESTIP echo update add $DESTNODE-last.lowttl.example.com. 1 in a $DESTIP echo } | nsupdate -d -k $CONFBASE:marc.example.net. else { echo update delete $DESTNODE.lowttl.example.com. a echo update delete $DESTNODE-last.lowttl.example.com. a echo update add $DESTNODE-last.lowttl.example.com. 1 in a $DESTIP echo } | nsupdate -d -k $CONFBASE:marc.example.net. fi gvpe-3.0/doc/complex-example/gvpe.conf0000644000000000000000000000560510002074751014663 00000000000000# sample configfile # the config file must be exactly(!) the same on all nodes rekey = 54321 # the rekeying interval keepalive = 300 # the keepalive interval on ruth keepalive = 120 # ruth is important and demands lower keepalives on surfer keepalive = 40 mtu = 1492 # the mtu (minimum mtu of attached host) ifname = vpn0 # the tunnel interface name to use ifpersist = no # the tun device should be persistent inherit-tos = yes # should tunnel packets inherit tos flags? compress = yes # wether compression should be used (NYI) connect = ondemand # connect to this host always/never or ondemand router-priority = 1 # route for everybody - if necessary loglevel = notice # info logs connects, notice only important messages on mobil loglevel = info on doom loglevel = info on ruth loglevel = info udp-port = 407 # the udp port to use for sending/receiving packets tcp-port = 443 # the tcp port to listen for connections (we use https over proxy) ip-proto = 50 # (ab)use the ipsec protocol as rawip icmp-type = 0 # (ab)use echo replies for tunneling enable-udp = yes # udp is spoken almost everywhere enable-tcp = no # tcp is not spoken everywhere enable-rawip = no # rawip is not spoken everywhere enable-icmp = no # most hosts don't bother to icmp # every "node =" introduces a new node in the network # the options following it don't set defaults but are # node-specific. # marc@lap node = mobil # marc@home node = doom enable-rawip = yes enable-tcp = yes # marc@uni node = ruth enable-rawip = yes enable-tcp = yes enable-icmp = yes hostname = 200.100.162.95 connect = always router-priority = 30 on ruth node-up = node-up on ruth node-down = node-up # marc@mu node = frank enable-rawip = yes hostname = 44.88.167.250 router-priority = 20 connect = always # nethype node = rain enable-rawip = yes hostname = 145.253.105.130 router-priority = 10 connect = always # marco@home node = marco enable-rawip = yes # stefan@ka node = wappla connect = never # stefan@lap node = stefan udp-port = 408 connect = never # paul@wg node = n8geil on ruth enable-icmp = yes on n8geil enable-icmp = yes enable-udp = no # paul@lap node = syrr # paul@lu node = donomos # marco@hn node = core # elmex@home node = elmex enable-rawip = yes hostname = 100.251.143.181 # stefan@kwc.at node = fwkw connect = never on stefan connect = always on wappla connect = always hostname = 182.73.81.146 # elmex@home node = jungfrau enable-rawip = yes # uni main router node = surfer enable-rawip = yes enable-tcp = no enable-icmp = yes hostname = 200.100.162.79 connect = always router-priority = 40 # jkneer@marvin node = marvin enable-rawip = yes enable-udp = no # jkneer@entrophy node = entrophy enable-udp = no enable-tcp = yes # mr. primitive node = voyager enable-udp = no enable-tcp = no on voyager enable-tcp = yes on voyager enable-udp = yes # v-server (barbados.dn-systems.de) #node = vserver #enable-udp = yes #hostname = 193.108.181.74 gvpe-3.0/doc/Makefile.in0000644000000000000000000004040213011103322012000 00000000000000# Makefile.in generated by automake 1.7.9 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # 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@ 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) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_triplet = @host@ # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' # to install before applying any user-specified name transformations. transform = s/ginstall/install/; @program_transform_name@ 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@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_TUNTAP = @HAVE_TUNTAP@ IFSUBTYPE = @IFSUBTYPE@ IFTYPE = @IFTYPE@ INCLUDES = @INCLUDES@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DAEMON = @LDFLAGS_DAEMON@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LINUX_IF_TUN_H = @LINUX_IF_TUN_H@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ POSUB = @POSUB@ RANLIB = @RANLIB@ ROHC_FALSE = @ROHC_FALSE@ ROHC_TRUE = @ROHC_TRUE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ info_TEXINFOS = gvpe.texi man_MANS = gvpe.5 gvpe.8 gvpectrl.8 gvpe.conf.5 gvpe.protocol.7 gvpe.osdep.5 PERL = @PERL@ MAINTAINERCLEANFILES = gvpe.texi gvpe.5 gvpe.8 gvpectrl.8 gvpe.conf.5 gvpe.protocol.7 gvpe.osdep.5 EXTRA_DIST = $(man_MANS) gvpe.texi \ Makefile.maint pod2texi \ gvpe.texi.pod gvpe.5.pod gvpe.8.pod gvpectrl.8.pod gvpe.conf.5.pod gvpe.protocol.7.pod gvpe.osdep.5.pod \ complex-example/README complex-example/if-up complex-example/node-up complex-example/gvpe.conf subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = am__TEXINFO_TEX_DIR = $(srcdir) INFO_DEPS = DVIS = PDFS = PSS = TEXINFOS = gvpe.texi NROFF = nroff MANS = $(man_MANS) DIST_COMMON = $(srcdir)/Makefile.in Makefile.am texinfo.tex all: all-am .SUFFIXES: .SUFFIXES: .dvi .ps $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) TEXI2DVI = texi2dvi TEXI2PDF = $(TEXI2DVI) --pdf --batch DVIPS = dvips .dvi.ps: $(DVIPS) -o $@ $< uninstall-info-am: $(PRE_UNINSTALL) @if (install-info --version && \ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile"; \ install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile; \ done; \ else :; fi @$(NORMAL_UNINSTALL) @list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ (if cd $(DESTDIR)$(infodir); then \ echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ else :; fi); \ done dist-info: $(INFO_DEPS) list='$(INFO_DEPS)'; \ for base in $$list; do \ if test -f $$base; then d=.; else d=$(srcdir); fi; \ for file in $$d/$$base*; do \ relfile=`expr "$$file" : "$$d/\(.*\)"`; \ test -f $(distdir)/$$relfile || \ cp -p $$file $(distdir)/$$relfile; \ done; \ done mostlyclean-aminfo: -rm -f maintainer-clean-aminfo: @list='$(INFO_DEPS)'; for i in $$list; do \ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ done man5dir = $(mandir)/man5 install-man5: $(man5_MANS) $(man_MANS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(man5dir) @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \ done uninstall-man5: @$(NORMAL_UNINSTALL) @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \ rm -f $(DESTDIR)$(man5dir)/$$inst; \ done man7dir = $(mandir)/man7 install-man7: $(man7_MANS) $(man_MANS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(man7dir) @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.7*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 7*) ;; \ *) ext='7' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst; \ done uninstall-man7: @$(NORMAL_UNINSTALL) @list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.7*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 7*) ;; \ *) ext='7' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man7dir)/$$inst"; \ rm -f $(DESTDIR)$(man7dir)/$$inst; \ done man8dir = $(mandir)/man8 install-man8: $(man8_MANS) $(man_MANS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(man8dir) @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ done uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ rm -f $(DESTDIR)$(man8dir)/$$inst; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/complex-example @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"; \ $(mkinstalldirs) "$(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 $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-info check-am: all-am check: check-am all-am: Makefile $(INFO_DEPS) $(MANS) installdirs: $(mkinstalldirs) $(DESTDIR)$(infodir) $(DESTDIR)$(man5dir) $(DESTDIR)$(man7dir) $(DESTDIR)$(man8dir) 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: 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." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: $(DVIS) info: info-am info-am: $(INFO_DEPS) install-data-am: install-info-am install-man install-exec-am: install-info: install-info-am install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(infodir) @list='$(INFO_DEPS)'; \ for file in $$list; do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ if test -f $$ifile; then \ relfile=`echo "$$ifile" | sed 's|^.*/||'`; \ echo " $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile"; \ $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if (install-info --version && \ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile";\ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile || :;\ done; \ else : ; fi install-man: install-man5 install-man7 install-man8 installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-aminfo \ maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-aminfo mostlyclean-generic pdf: pdf-am pdf-am: $(PDFS) ps: ps-am ps-am: $(PSS) uninstall-am: uninstall-info-am uninstall-man uninstall-man: uninstall-man5 uninstall-man7 uninstall-man8 .PHONY: all all-am check check-am clean clean-generic dist-info \ distclean distclean-generic distdir dvi dvi-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-man5 install-man7 install-man8 install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-info-am uninstall-man \ uninstall-man5 uninstall-man7 uninstall-man8 # For additional rules usually of interest only to the maintainer, # see GNUmakefile and Makefile.maint. # 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: gvpe-3.0/doc/Makefile.am0000644000000000000000000000162411046631516012013 00000000000000## Process this file with automake to get Makefile.in info_TEXINFOS = gvpe.texi man_MANS = gvpe.5 gvpe.8 gvpectrl.8 gvpe.conf.5 gvpe.protocol.7 gvpe.osdep.5 PERL = @PERL@ MAINTAINERCLEANFILES = gvpe.texi gvpe.5 gvpe.8 gvpectrl.8 gvpe.conf.5 gvpe.protocol.7 gvpe.osdep.5 EXTRA_DIST = $(man_MANS) gvpe.texi \ Makefile.maint pod2texi \ gvpe.texi.pod gvpe.5.pod gvpe.8.pod gvpectrl.8.pod gvpe.conf.5.pod gvpe.protocol.7.pod gvpe.osdep.5.pod \ complex-example/README complex-example/if-up complex-example/node-up complex-example/gvpe.conf # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' # to install before applying any user-specified name transformations. transform = s/ginstall/install/; @program_transform_name@ # For additional rules usually of interest only to the maintainer, # see GNUmakefile and Makefile.maint. gvpe-3.0/doc/texinfo.tex0000644000000000000000000066100112011645431012150 00000000000000% texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{2003-10-06.08} % % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. % % This texinfo.tex 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, or (at % your option) any later version. % % This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % (and all CTAN mirrors, see http://www.ctan.org), % and /home/gd/gnu/doc/texinfo.tex on the GNU machines. % % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. % % The texinfo.tex in any given Texinfo distribution could well be out % of date, so if that's what you're using, please check. % % Send bug reports to bug-texinfo@gnu.org. Please include including a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For a simple % manual foo.texi, however, you can get away with this: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever; this makes foo.ps. % The extra TeX runs get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. % % It is possible to adapt texinfo.tex for other languages, to some % extent. You can get the existing language-specific files from the % full Texinfo distribution. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} \message{Basics,} \chardef\other=12 % We never want plain's \outer definition of \+ in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax % Save some plain tex macros whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent \let\ptexnoindent=\noindent \let\ptexlbrace=\{ \let\ptexless=< \let\ptexplus=+ \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi \ifx\putwordof\undefined \gdef\putwordof{of}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi % \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi % \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % In some macros, we cannot use the `\? notation---the left quote is % in some cases the escape char. \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dotChar = `\. \chardef\equalChar = `\= \chardef\exclamChar= `\! \chardef\questChar = `\? \chardef\semiChar = `\; \chardef\spaceChar = `\ % \chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} % True if #1 is the empty string, i.e., called like `\ifempty{}'. % \def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% \def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% % Hyphenation fixes. \hyphenation{ap-pen-dix} \hyphenation{eshell} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{time-stamp} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make % some effort to order the tracing commands to reduce output in the log % file; cf. trace.sty in LaTeX. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \def\loggingall{% \tracingstats2 \tracingpages1 \tracinglostchars2 % 2 gives us more in etex \tracingparagraphs1 \tracingoutput1 \tracingmacros2 \tracingrestores1 \showboxbreadth\maxdimen \showboxdepth\maxdimen \ifx\eTeXversion\undefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 \tracingnesting2 \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex \errorcontextlines\maxdimen }% % add check for \lastpenalty to plain's definitions. If the last thing % we did was a \nobreak, we don't want to insert more space. % \def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount \removelastskip\penalty-50\smallskip\fi\fi} \def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount \removelastskip\penalty-100\medskip\fi\fi} \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfmkdest{\the\pageno}\fi % \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \normalturnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce \{ and \} commands for indices, % and @{ and @} for the aux file. \catcode`\{ = \other \catcode`\} = \other \catcode`\[ = 1 \catcode`\] = 2 \catcode`\! = 0 \catcode`\\ = \other !gdef!lbracecmd[\{]% !gdef!rbracecmd[\}]% !gdef!lbraceatcmd[@{]% !gdef!rbraceatcmd[@}]% !endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % % Another complication is that the group might be very large. This can % cause the glue on the previous page to be unduly stretched, because it % does not have much material. In this case, it's better to add an % explicit \vfill so that the extra space is at the bottom. The % threshold for doing this is if the group is more than \vfilllimit % percent of a page (\vfilllimit can be changed inside of @tex). % \newbox\groupbox \def\vfilllimit{0.7} % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. % \dimen0 is the vertical size of the group's box. \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox % \dimen2 is how much space is left on the page (more or less). \dimen2 = \pageheight \advance\dimen2 by -\pagetotal % if the group doesn't fit on the current page, and it's a big big % group, force a page break. \ifdim \dimen0 > \dimen2 \ifdim \pagetotal < \vfilllimit\pageheight \page \fi \fi \copy\groupbox \endgroup % End the \group. }% % \setbox\groupbox = \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % If the @need value is less than one line space, it's useless. \dimen0 = #1\mil \dimen2 = \ht\strutbox \advance\dimen2 by \dp\strutbox \ifdim\dimen0 > \dimen2 % % Do a \strut just to make the height of this box be normal, so the % normal leading is inserted relative to the preceding line. % And a page break here is fine. \vtop to #1\mil{\strut\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak \fi } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page. % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion % class. WHICH is `l' or `r'. % \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} % \def\doinmargin#1#2{\strut\vadjust{% \nobreak \kern-\strutdepth \vtop to \strutdepth{% \baselineskip=\strutdepth \vss % if you have multiple lines of stuff to put here, you'll need to % make the vbox yourself of the appropriate size. \ifx#1l% \llap{\ignorespaces #2\hskip\inmarginspacing}% \else \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% \fi \null }% }} \def\inleftmargin{\doinmargin l} \def\inrightmargin{\doinmargin r} % % @inmargin{TEXT [, RIGHT-TEXT]} % (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; % else use TEXT for both). % \def\inmargin#1{\parseinmargin #1,,\finish} \def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \def\lefttext{#1}% have both texts \def\righttext{#2}% \else \def\lefttext{#1}% have only one text \def\righttext{#1}% \fi % \ifodd\pageno \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin \else \def\temp{\inleftmargin\lefttext}% \fi \temp } % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \let\value=\expandablevalue \input\thisfile \endgroup} \def\thisfile{} % @center line % outputs that line, centered. % \def\center{\parsearg\docenter} \def\docenter#1{{% \ifhmode \hfil\break \fi \advance\hsize by -\leftskip \advance\hsize by -\rightskip \line{\hfil \ignorespaces#1\unskip \hfil}% \ifhmode \break \fi }} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} \let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. % NCHARS can also be the word `asis' or `none'. % We cannot feasibly implement @paragraphindent asis, though. % \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \defaultparindent = 0pt \else \defaultparindent = #1em \fi \fi \parindent = \defaultparindent } % @exampleindent NCHARS % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \lispnarrowing = 0pt \else \lispnarrowing = #1em \fi \fi } % @firstparagraphindent WORD % If WORD is `none', then suppress indentation of the first paragraph % after a section heading. If WORD is `insert', then do indent at such % paragraphs. % % The paragraph indentation is suppressed or not by calling % \suppressfirstparagraphindent, which the sectioning commands do. % We switch the definition of this back and forth according to WORD. % By default, we suppress indentation. % \def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} \newdimen\currentparindent % \def\insertword{insert} % \def\firstparagraphindent{\parsearg\dofirstparagraphindent} \def\dofirstparagraphindent#1{% \def\temp{#1}% \ifx\temp\noneword \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent \else\ifx\temp\insertword \let\suppressfirstparagraphindent = \relax \else \errhelp = \EMsimple \errmessage{Unknown @firstparagraphindent option `\temp'}% \fi\fi } % Here is how we actually suppress indentation. Redefine \everypar to % \kern backwards by \parindent, and then reset itself to empty. % % We also make \indent itself not actually do anything until the next % paragraph. % \gdef\dosuppressfirstparagraphindent{% \gdef\indent{% \restorefirstparagraphindent \indent }% \gdef\noindent{% \restorefirstparagraphindent \noindent }% \global\everypar = {% \kern -\parindent \restorefirstparagraphindent }% } \gdef\restorefirstparagraphindent{% \global \let \indent = \ptexindent \global \let \noindent = \ptexnoindent \global \everypar = {}% } % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math outputs its argument in math mode. % We don't use $'s directly in the definition of \math because we need % to set catcodes according to plain TeX first, to allow for subscripts, % superscripts, special math chars, etc. % \let\implicitmath = $%$ font-lock fix % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make % _ within @math be active (mathcode "8000), and distinguish by seeing % if the current family is \slfam, which is what @var uses. % {\catcode\underChar = \active \gdef\mathunderscore{% \catcode\underChar=\active \def_{\ifnum\fam=\slfam \_\else\sb\fi}% }} % % Another complication: we want \\ (and @\) to output a \ character. % FYI, plain.tex uses \\ as a temporary control sequence (why?), but % this is not advertised and we don't care. Texinfo does not % otherwise define @\. % % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% \tex \mathcode`\_="8000 \mathunderscore \let\\ = \mathbackslash \mathactive \implicitmath\finishmath} \def\finishmath#1{#1\implicitmath\Etex} % Some active characters (such as <) are spaced differently in math. % We have to reset their definitions in case the @math was an % argument to a command which set the catcodes (such as @item or @section). % { \catcode`^ = \active \catcode`< = \active \catcode`> = \active \catcode`+ = \active \gdef\mathactive{% \let^ = \ptexhat \let< = \ptexless \let> = \ptexgtr \let+ = \ptexplus } } % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % Called from \setfilename. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{pdf,} % adobe `portable' document format \newcount\tempnum \newcount\lnkcount \newtoks\filename \newcount\filenamelength \newcount\pgn \newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD \newbox\boxA \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest \ifx\pdfoutput\undefined \pdffalse \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\linkcolor = \relax \let\pdfmakeoutlines = \relax \else \pdftrue \pdfoutput = 1 \input pdfcolor \pdfcatalog{/PageMode /UseOutlines}% \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% % without \immediate, pdftex seg faults when the same image is % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) \ifnum\pdftexversion < 14 \immediate\pdfimage \else \immediate\pdfximage \fi \ifx\empty\imagewidth\else width \imagewidth \fi \ifx\empty\imageheight\else height \imageheight \fi \ifnum\pdftexversion<13 #1.pdf% \else {#1.pdf}% \fi \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} \def\pdfmkpgn#1{#1} \let\linkcolor = \Blue % was Cyan, but that seems light? \def\endlink{\Black\pdfendlink} % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax \advance\tempnum by 1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} % % #1 is the section text. #2 is the pdf expression for the number % of subentries (or empty, for subsubsections). #3 is the node % text, which might be empty if this toc entry had no % corresponding node. #4 is the page number. % \def\dopdfoutline#1#2#3#4{% % Generate a link to the node text if that exists; else, use the % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worthwhile, since most documents are normally structured. \def\pdfoutlinedest{#3}% \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi % \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}% } % \def\pdfmakeoutlines{% \openin 1 \jobname.toc \ifeof 1\else\begingroup \closein 1 % Thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % % Read toc silently, to get counts of subentries for \pdfoutline. \def\numchapentry##1##2##3##4{\def\thischapnum{##2}}% \def\numsecentry##1##2##3##4{% \def\thissecnum{##2}% \advancenumber{chap\thischapnum}}% \def\numsubsecentry##1##2##3##4{% \def\thissubsecnum{##2}% \advancenumber{sec\thissecnum}}% \def\numsubsubsecentry##1##2##3##4{\advancenumber{subsec\thissubsecnum}}% % % use \def rather than \let here because we redefine \chapentry et % al. a second time, below. \def\appentry{\numchapentry}% \def\appsecentry{\numsecentry}% \def\appsubsecentry{\numsubsecentry}% \def\appsubsubsecentry{\numsubsubsecentry}% \def\unnchapentry{\numchapentry}% \def\unnsecentry{\numsecentry}% \def\unnsubsecentry{\numsubsecentry}% \def\unnsubsubsecentry{\numsubsubsecentry}% \input \jobname.toc % % Read toc second time, this time actually producing the outlines. % The `-' means take the \expnumber as the absolute number of % subentries, which we calculated on our first read of the .toc above. % % We use the node names as the destinations. \def\numchapentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% \def\numsecentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% \def\numsubsecentry##1##2##3##4{% \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% \def\numsubsubsecentry##1##2##3##4{% count is always zero \dopdfoutline{##1}{}{##3}{##4}}% % % Make special characters normal for writing to the pdf file. \indexnofonts \turnoffactive \input \jobname.toc \endgroup\fi } % \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% \linkcolor #1% \advance\lnkcount by 1% \endlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% \let\value=\expandablevalue \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% % #1 \endgroup} \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} \def\maketoks{% \expandafter\poptoks\the\toksA|ENDTOKS| \ifx\first0\adn0 \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 \else \ifnum0=\countA\else\makelink\fi \ifx\first.\let\next=\done\else \let\next=\maketoks \addtokens{\toksB}{\the\toksD} \ifx\first,\addtokens{\toksB}{\space}\fi \fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next} \def\makelink{\addtokens{\toksB}% {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} \def\pdflink#1{% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} \linkcolor #1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % \ifx\pdfoutput \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Default leading. \newdimen\textleading \textleading = 13.2pt % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \newcount\mainmagstep \ifx\bigger\relax % not really supported. \mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \mainmagstep=\magstephalf \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you may want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10 % (in Bob's opinion). \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} \setfont\smalltt\ttshape{9}{1000} \setfont\smallbf\bfshape{10}{900} \setfont\smallit\itshape{9}{1000} \setfont\smallsl\slshape{9}{1000} \setfont\smallsf\sfshape{9}{1000} \setfont\smallsc\scshape{10}{900} \setfont\smallttsl\ttslshape{10}{900} \font\smalli=cmmi9 \font\smallsy=cmsy9 % Fonts for small examples (8pt). \setfont\smallerrm\rmshape{8}{1000} \setfont\smallertt\ttshape{8}{1000} \setfont\smallerbf\bfshape{10}{800} \setfont\smallerit\itshape{8}{1000} \setfont\smallersl\slshape{8}{1000} \setfont\smallersf\sfshape{8}{1000} \setfont\smallersc\scshape{10}{800} \setfont\smallerttsl\ttslshape{10}{800} \font\smalleri=cmmi8 \font\smallersy=cmsy8 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} \def\authortt{\sectt} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts except % in the main text, we don't bother to reset \scriptfont and % \scriptscriptfont (which would also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf \textfont\ttfam=\tentt \textfont\sffam=\tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts \setleading{\textleading}} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\smallfonts{% \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy \let\tenttsl=\smallttsl \resetmathfonts \setleading{10.5pt}} \def\smallerfonts{% \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy \let\tenttsl=\smallerttsl \resetmathfonts \setleading{9.5pt}} % Set the fonts to use with the @small... environments. \let\smallexamplefonts = \smallfonts % About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample % can fit this many characters: % 8.5x11=86 smallbook=72 a4=90 a5=69 % If we use \smallerfonts (8pt), then we can fit this many characters: % 8.5x11=90+ smallbook=80 a4=90+ a5=77 % For me, subjectively, the few extra characters that fit aren't worth % the additional smallness of 8pt. So I'm making the default 9pt. % % By the way, for comparison, here's what fits with @example (10pt): % 8.5x11=71 smallbook=60 a4=75 a5=58 % % I wish we used A4 paper on this side of the Atlantic. % % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} \setfont\shortconttt\ttshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else \ptexslash\fi\fi\fi} \def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } % Set sfcode to normal for the chars that usually have another value. % Can't use plain's \frenchspacing because it uses the `\x notation, and % sometimes \x has an active definition that messes things up. % \catcode`@=11 \def\frenchspacing{% \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m } \catcode`@=\other \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \font\keysy=cmsy9 \def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) % will therefore expand the active definition of _, which is us % (inside @code that is), therefore an endless loop. \ifusingtt{\ifmmode \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. \else\normalunderscore \fi \discretionary{}{}{}}% {\_}% } \def\codex #1{\tclose{#1}\endgroup} % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple \errmessage{Unknown @kbdinputstyle option `\arg'}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is `distinct.' \kbdinputstyle distinct \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\code % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url % itself. First (mandatory) arg is the url. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#1,#2,#3,#4\finish{\begingroup \unsepspaces \pdfurl{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url \fi \else \code{#1}% only url given, so show it \fi \fi \endlink \endgroup} % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} \ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{\begingroup \unsepspaces \pdfurl{mailto:#1}% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi \endlink \endgroup} \else \let\email=\uref \fi % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} % @registeredsymbol - R in a circle. For now, only works in text size; % we'd have to redo the font mechanism to change the \scriptstyle and % \scriptscriptstyle font sizes to make it look right in headings. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% }$% } \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines \let\tt=\authortt}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % Need this before the \...aftertitlepage checks so that if they are % in effect the toc pages will come out with page numbers. \HEADINGSon % % If they want short, they certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). \ifx\today\undefined \def\today{% \number\day\space \ifcase\month \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec \fi \space\number\year} \fi % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. (Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue.) However, if what follows is an environment % such as @example, there will be no \parskip glue; then % the negative vskip we just would cause the example and the item to % crash together. So we use this bizarre value of 10001 as a signal % to \aboveenvbreak to insert \parskip glue after all. % (Possibly there are other commands that could be followed by % @example which need the same treatment, but not section titles; or % maybe section titles are the only special case and they should be % penalty 10001...) \penalty 10001 \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. \noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey#1#2{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin \advance\leftskip by \itemindent \exdentamount=\itemindent \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi \let\item=\itemizeitem } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a % separator; typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % @multitable ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item=\crcrwithfootnotes % A \tab used to include \hskip1sp. But then the space in a template % line is not enough. That is bad. So let's go back to just & until % we encounter the problem it was intended to solve again. --karl, % nathan@acm.org, 20apr99. \let\tab=&% \let\startfootins=\startsavedfootnote \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{% \global\setpercentfalse \crcrwithfootnotes\crcr \egroup\egroup }% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut \else %% FIXME: what is \box0 supposed to be? \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} % In case a @footnote appears inside an alignment, save the footnote % text to a box and make the \insert when a row of the table is % finished. Otherwise, the insertion is lost, it never migrates to the % main vertical list. --kasal, 22jan03. % \newbox\savedfootnotes % % \dotable \let's \startfootins to this, so that \dofootnote will call % it instead of starting the insertion right away. \def\startsavedfootnote{% \global\setbox\savedfootnotes = \vbox\bgroup \unvbox\savedfootnotes } \def\crcrwithfootnotes{% \crcr \ifvoid\savedfootnotes \else \noalign{\insert\footins{\box\savedfootnotes}}% \fi } \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax %\let\begin=\relax %\let\bye=\relax \let\centerchap=\relax \let\chapter=\relax \let\contents=\relax \let\section=\relax \let\smallbook=\relax \let\subsec=\relax \let\subsection=\relax \let\subsubsec=\relax \let\subsubsection=\relax \let\titlepage=\relax \let\top=\relax \let\unnumbered=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax } % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} \def\documentdescriptionword{documentdescription} \def\documentdescription{\doignore{documentdescription}} \def\html{\doignore{html}} \def\ifhtml{\doignore{ifhtml}} \def\ifinfo{\doignore{ifinfo}} \def\ifnottex{\doignore{ifnottex}} \def\ifplaintext{\doignore{ifplaintext}} \def\ifxml{\doignore{ifxml}} \def\ignore{\doignore{ignore}} \def\menu{\doignore{menu}} \def\xml{\doignore{xml}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1', keeping track of nested conditionals. % % A count to remember the depth of nesting. \newcount\doignorecount \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode\spaceChar = 10 % % Ignore braces, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % Count number of #1's that we've seen. \doignorecount = 0 % % Swallow text until we reach the matching `@end #1'. \expandafter \dodoignore \csname#1\endcsname {#1}% } { \catcode`@=11 % We want to use \ST@P which cannot appear in texinfo source. \obeylines % % \gdef\dodoignore#1#2{% % #1 contains, e.g., \ifinfo, a.k.a. @ifinfo. % #2 contains the string `ifinfo'. % % Define a command to find the next `@end #2', which must be on a line % by itself. \long\def\doignoretext##1^^M\end #2{\doignoretextyyy##1^^M#1\ST@P}% % And this command to find another #1 command, at the beginning of a % line. (Otherwise, we would consider a line `@c @ifset', for % example, to count as an @ifset for nesting.) \long\def\doignoretextyyy##1^^M#1##2\ST@P{\doignoreyyy{##2}\ST@P}% % % And now expand that command. \obeylines % \doignoretext ^^M% }% } \def\doignoreyyy#1{% \def\temp{#1}% \ifx\temp\empty % Nothing found. \let\next\doignoretextzzz \else % Found a nested condition, ... \advance\doignorecount by 1 \let\next\doignoretextyyy % ..., look for another. % If we're here, #1 ends with ^^M\ifinfo (for example). \fi \next #1% the token \ST@P is present just after this macro. } % We have to swallow the remaining "\ST@P". % \def\doignoretextzzz#1{% \ifnum\doignorecount = 0 % We have just found the outermost @end. \let\next\enddoignore \else % Still inside a nested condition. \advance\doignorecount by -1 \let\next\doignoretext % Look for the next @end. \fi \next } % Finish off ignored text. \def\enddoignore{\endgroup\ignorespaces} % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=\other \catcode`\_=\other \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. The command has to be fully expandable (if the variable % is set), since the result winds up in the index file. This means that % if the variable's value contains other Texinfo commands, it's almost % certain it will fail (although perhaps we could fix that with % sufficient work to do a one-level expansion on the result, instead of % complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \message{Variable `#1', used in @value, is not set.}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\doifset} \def\doifset#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifsetfail \else \let\next=\ifsetsucceed \fi \next } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\doignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\doifclear} \def\doifclear#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifclearsucceed \else \let\next=\ifclearfail \fi \next } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\doignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we % read the text following, through the first @end iftex (etc.). Make % `@end iftex' (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} \defineunmatchedend{ifnotplaintext} % True conditional. Since \set globally defines its variables, we can % just start and end a group (to keep the @end definition undefined at % the outer level). % \def\conditionalsucceed#1{\begingroup \expandafter\def\csname E#1\endcsname{\endgroup}% } % @defininfoenclose. \let\definfoenclose=\comment \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} % \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. % \def\defcodeindex{\parsearg\newcodeindex} % \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}}% } % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. % \def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} \def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), % #3 the target index (bar). \def\dosynindex#1#2#3{% % Only do \closeout if we haven't already done it, else we'll end up % closing the target index. \expandafter \ifx\csname donesynindex#2\endcsname \undefined % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \expandafter\closeout\csname#2indfile\endcsname \expandafter\let\csname\donesynindex#2\endcsname = 1 \fi % redefine \fooindfile: \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname \expandafter\let\csname#2indfile\endcsname=\temp % redefine \fooindex: \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} % Take care of Texinfo commands that can appear in an index entry. % Since there are some commands we want to expand, and others we don't, % we have to laboriously prevent expansion for those that we don't. % \def\indexdummies{% \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace % % \definedummyword defines \#1 as \realbackslash #1\space, thus % effectively preventing its expansion. This is used only for control % words, not control letters, because the \space would be incorrect % for control characters, but is needed to separate the control word % from whatever follows. % % For control letters, we have \definedummyletter, which omits the % space. % % These can be used both for control words that take an argument and % those that do not. If it is followed by {arg} in the input, then % that will dutifully get written to the index (or wherever). % \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% }% % % Do the redefinitions. \commondummies } % For the aux file, @ is the escape character. So we want to redefine % everything using @ instead of \realbackslash. When everything uses % @, this will be simpler. % \def\atdummies{% \def\@{@@}% \def\ {@ }% \let\{ = \lbraceatcmd \let\} = \rbraceatcmd % % (See comments in \indexdummies.) \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{@##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{@##1}% }% % % Do the redefinitions. \commondummies } % Called from \indexdummies and \atdummies. \definedummyword and % \definedummyletter must be defined first. % \def\commondummies{% % \normalturnoffactive % % Control letters and accents. \definedummyletter{_}% \definedummyletter{,}% \definedummyletter{"}% \definedummyletter{`}% \definedummyletter{'}% \definedummyletter{^}% \definedummyletter{~}% \definedummyletter{=}% \definedummyword{u}% \definedummyword{v}% \definedummyword{H}% \definedummyword{dotaccent}% \definedummyword{ringaccent}% \definedummyword{tieaccent}% \definedummyword{ubaraccent}% \definedummyword{udotaccent}% \definedummyword{dotless}% % % Other non-English letters. \definedummyword{AA}% \definedummyword{AE}% \definedummyword{L}% \definedummyword{OE}% \definedummyword{O}% \definedummyword{aa}% \definedummyword{ae}% \definedummyword{l}% \definedummyword{oe}% \definedummyword{o}% \definedummyword{ss}% % % Although these internal commands shouldn't show up, sometimes they do. \definedummyword{bf}% \definedummyword{gtr}% \definedummyword{hat}% \definedummyword{less}% \definedummyword{sf}% \definedummyword{sl}% \definedummyword{tclose}% \definedummyword{tt}% % % Texinfo font commands. \definedummyword{b}% \definedummyword{i}% \definedummyword{r}% \definedummyword{sc}% \definedummyword{t}% % \definedummyword{TeX}% \definedummyword{acronym}% \definedummyword{cite}% \definedummyword{code}% \definedummyword{command}% \definedummyword{dfn}% \definedummyword{dots}% \definedummyword{emph}% \definedummyword{env}% \definedummyword{file}% \definedummyword{kbd}% \definedummyword{key}% \definedummyword{math}% \definedummyword{option}% \definedummyword{samp}% \definedummyword{strong}% \definedummyword{uref}% \definedummyword{url}% \definedummyword{var}% \definedummyword{verb}% \definedummyword{w}% % % Assorted special characters. \definedummyword{bullet}% \definedummyword{copyright}% \definedummyword{dots}% \definedummyword{enddots}% \definedummyword{equiv}% \definedummyword{error}% \definedummyword{expansion}% \definedummyword{minus}% \definedummyword{pounds}% \definedummyword{point}% \definedummyword{print}% \definedummyword{result}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % % Normal spaces, not active ones. \unsepspaces % % No macro expansion. \turnoffmacros } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string % would be for a given command (usually its argument). % \def\indexdummytex{TeX} \def\indexdummydots{...} % \def\indexnofonts{% \def\ { }% \def\@{@}% % how to handle braces? \def\_{\normalunderscore}% % \let\,=\asis \let\"=\asis \let\`=\asis \let\'=\asis \let\^=\asis \let\~=\asis \let\==\asis \let\u=\asis \let\v=\asis \let\H=\asis \let\dotaccent=\asis \let\ringaccent=\asis \let\tieaccent=\asis \let\ubaraccent=\asis \let\udotaccent=\asis \let\dotless=\asis % % Other non-English letters. \def\AA{AA}% \def\AE{AE}% \def\L{L}% \def\OE{OE}% \def\O{O}% \def\aa{aa}% \def\ae{ae}% \def\l{l}% \def\oe{oe}% \def\o{o}% \def\ss{ss}% \def\exclamdown{!}% \def\questiondown{?}% % % Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |, etc. % Likewise with the other plain tex font commands. %\let\tt=\asis % % Texinfo font commands. \let\b=\asis \let\i=\asis \let\r=\asis \let\sc=\asis \let\t=\asis % \let\TeX=\indexdummytex \let\acronym=\asis \let\cite=\asis \let\code=\asis \let\command=\asis \let\dfn=\asis \let\dots=\indexdummydots \let\emph=\asis \let\env=\asis \let\file=\asis \let\kbd=\asis \let\key=\asis \let\math=\asis \let\option=\asis \let\samp=\asis \let\strong=\asis \let\uref=\asis \let\url=\asis \let\var=\asis \let\verb=\asis \let\w=\asis } \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}{}} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % \empty if called from \doind, as we usually are. The main exception % is with defuns, which call us directly. % \def\dosubind#1#2#3{% \iflinks {% % Store the main index entry text (including the third arg). \toks0 = {#2}% % If third arg is present, precede it with space. \def\thirdarg{#3}% \ifx\thirdarg\empty \else \toks0 = \expandafter{\the\toks0 \space #3}% \fi % \edef\writeto{\csname#1indfile\endcsname}% % \ifvmode \dosubindsanitize \else \dosubindwrite \fi }% \fi } % Write the entry to the index file: % \def\dosubindwrite{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% \fi % % Remember, we are within a group. \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % Process the index entry with all font commands turned off, to % get the string to sort by. {\indexnofonts \edef\temp{\the\toks0}% need full expansion \xdef\indexsorttmp{\temp}% }% % % Set up the complete index entry, with both the sort key and % the original text, including any font commands. We write % three arguments to \entry to the .?? file (four in the % subentry case), texindex reduces to two when writing the .??s % sorted result. \edef\temp{% \write\writeto{% \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% }% \temp } % Take care of unwanted page breaks: % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write will make \lastskip zero. The result is that sequences % like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % \def\dosubindsanitize{% % \lastskip and \lastpenalty cannot both be nonzero simultaneously. \skip0 = \lastskip \count255 = \lastpenalty % % If \lastskip is nonzero, that means the last item was a % skip. And since a skip is discardable, that means this % -\skip0 glue we're inserting is preceded by a % non-discardable item, therefore it is not a potential % breakpoint, therefore no \nobreak needed. \ifdim\lastskip = 0pt \else \vskip-\skip0 \fi % \dosubindwrite % \ifdim\skip0 = 0pt % if \lastskip was zero, perhaps the last item was a % penalty, and perhaps it was >=10000, e.g., a \nobreak. % In that case, we want to re-insert the penalty; since we % just inserted a non-discardable item, any following glue % (such as a \parskip) would be a breakpoint. For example: % @deffn deffn-whatever % @vindex index-whatever % Description. % would allow a break between the index-whatever whatsit % and the "Description." paragraph. \ifnum\count255>9999 \nobreak \fi \else % On the other hand, if we had a nonzero \lastskip, % this make-up glue would be preceded by a non-discardable item % (the whatsit from the \write), so we must insert a \nobreak. \nobreak\vskip\skip0 \fi } % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \everypar = {}% don't want the \kern\-parindent from indentation suppression. \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing columns. \vskip 0pt plus1pt % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else \ #2% The page number ends the paragraph. \fi \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary#1#2{{% \parfillskip=0in \parskip=0in \hangindent=1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else #2 \fi \par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case we just ship out what is in \partialpage with the normal % output routine. Generally, \partialpage will be empty when this % runs and this will be a no-op. See the indexspread.tex test case. \ifvoid\partialpage \else \onepageout{\pagecontents\partialpage}% \fi % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE \kern-\topskip \kern\baselineskip }% }% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } % % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \def\pagesofar{% \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } % % All done with double columns. \def\enddoublecolumns{% \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \endgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } % % Called at the end of the double column material. \def\balancecolumns{% \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Chapters, sections, etc. % \unnumberedno is an oxymoron, of course. But we count the unnumbered % sections so that we can refer to them unambiguously in the pdf % outlines by their "section number". We avoid collisions with chapter % numbers by starting them at 10000. (If a document ever has 10000 % chapters, we're in trouble anyway, I'm sure.) \newcount\unnumberedno \unnumberedno = 10000 \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ % % \def\appendixletter{\char\the\appendixno} % We do the following ugly conditional instead of the above simple % construct for the sake of pdftex, which needs the actual % letter in the expansion, not just typeset. % \def\appendixletter{% \ifnum\appendixno=`A A% \else\ifnum\appendixno=`B B% \else\ifnum\appendixno=`C C% \else\ifnum\appendixno=`D D% \else\ifnum\appendixno=`E E% \else\ifnum\appendixno=`F F% \else\ifnum\appendixno=`G G% \else\ifnum\appendixno=`H H% \else\ifnum\appendixno=`I I% \else\ifnum\appendixno=`J J% \else\ifnum\appendixno=`K K% \else\ifnum\appendixno=`L L% \else\ifnum\appendixno=`M M% \else\ifnum\appendixno=`N N% \else\ifnum\appendixno=`O O% \else\ifnum\appendixno=`P P% \else\ifnum\appendixno=`Q Q% \else\ifnum\appendixno=`R R% \else\ifnum\appendixno=`S S% \else\ifnum\appendixno=`T T% \else\ifnum\appendixno=`U U% \else\ifnum\appendixno=`V V% \else\ifnum\appendixno=`W W% \else\ifnum\appendixno=`X X% \else\ifnum\appendixno=`Y Y% \else\ifnum\appendixno=`Z Z% % The \the is necessary, despite appearances, because \appendixletter is % expanded while writing the .toc file. \char\appendixno is not % expandable, thus it is written literally, thus all appendixes come out % with the same letter (or @) in the toc without it. \else\char\the\appendixno \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. % However, they are not reliable, because we don't use marks. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2}% \or \seczzz{#2}% \or \numberedsubseczzz{#2}% \or \numberedsubsubseczzz{#2}% \else \ifnum \absseclevel<0 \chapterzzz{#2}% \else \numberedsubsubseczzz{#2}% \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2}% \or \appendixsectionzzz{#2}% \or \appendixsubseczzz{#2}% \or \appendixsubsubseczzz{#2}% \else \ifnum \absseclevel<0 \appendixzzz{#2}% \else \appendixsubsubseczzz{#2}% \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2}% \or \unnumberedseczzz{#2}% \or \unnumberedsubseczzz{#2}% \or \unnumberedsubsubseczzz{#2}% \else \ifnum \absseclevel<0 \unnumberedzzz{#2}% \else \unnumberedsubsubseczzz{#2}% \fi \fi \suppressfirstparagraphindent } % @chapter, @appendix, @unnumbered. % \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy#1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz#1{% \secno=0 \subsecno=0 \subsubsecno=0 \advance\chapno by 1 \message{\putwordChapter\space \the\chapno}% % % Write the actual heading. \chapmacro{#1}{Ynumbered}{\the\chapno}% % % So @section and the like are numbered underneath this chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy#1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz#1{% \secno=0 \subsecno=0 \subsubsecno=0 \advance\appendixno by 1 \def\appendixnum{\putwordAppendix\space \appendixletter}% \message{\appendixnum}% \chapmacro{#1}{Yappendix}{\appendixletter}% \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy#1{{\unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy#1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz#1{% \secno=0 \subsecno=0 \subsubsecno=0 \advance\unnumberedno by 1 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}\message{(\the\toks0)}% % \chapmacro{#1}{Ynothing}{\the\unnumberedno}% % \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy#1{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \subsecno=0 \subsubsecno=0 \advance\secno by 1 \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy#1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz#1{% \subsecno=0 \subsubsecno=0 \advance\secno by 1 \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy#1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz#1{% \subsecno=0 \subsubsecno=0 \advance\secno by 1 \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy#1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz#1{% \subsubsecno=0 \advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy#1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz#1{% \subsubsecno=0 \advance\subsecno by 1 \sectionheading{#1}{subsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno}% } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy#1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz#1{% \subsubsecno=0 \advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynothing}% {\the\unnumberedno.\the\secno.\the\subsecno}% } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy#1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz#1{% \advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynumbered}% {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy#1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz#1{% \advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy#1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz#1{% \advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynothing}% {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they are now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \let\section = \numberedsec \let\subsection = \numberedsubsec \let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz } \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}% \bigskip \par\penalty 200\relax \suppressfirstparagraphindent } % @heading, @subheading, @subsubheading. \def\heading{\parsearg\doheading} \def\subheading{\parsearg\dosubheading} \def\subsubheading{\parsearg\dosubsubheading} \def\doheading#1{\sectionheading{#1}{sec}{Yomitfromtoc}{} \suppressfirstparagraphindent} \def\dosubheading#1{\sectionheading{#1}{subsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} \def\dosubsubheading#1{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{% \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{% \global\let\chapmacro=\chfplain \global\let\centerchapmacro=\centerchfplain} % Normal chapter opening. % % #1 is the text, #2 is the section type (Ynumbered, Ynothing, % Yappendix, Yomitfromtoc), #3 the chapter number. % % To test against our argument. \def\Ynothingkeyword{Ynothing} \def\Yomitfromtockeyword{Yomitfromtoc} \def\Yappendixkeyword{Yappendix} % \def\chfplain#1#2#3{% \pchapsepmacro {% \chapfonts \rm % % Have to define \thissection before calling \donoderef, because the % xref code eventually uses it, as \Ytitle. On the other hand, it % has to be called after \pchapsepmacro, or the headline will change % too soon. \gdef\thissection{#1}% \gdef\thischaptername{#1}% % % Only insert the separating space if we have a chapter/appendix % number, and don't print the unnumbered ``number''. \def\temptype{#2}% \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unnchap}% \def\thischapter{#1}% \else\ifx\temptype\Yomitfromtockeyword \setbox0 = \hbox{}% contents like unnumbered, but no toc entry \def\toctype{omit}% \xdef\thischapter{}% \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% \def\toctype{app}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. And we don't % use \thissection because that changes with each section. % \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \else \setbox0 = \hbox{#3\enspace}% \def\toctype{numchap}% \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \fi\fi\fi % % Write the toc entry for this chapter. Must come before the % \donoderef, because we include the current node name in the toc % entry, and \donoderef resets it to empty. \writetocentry{\toctype}{#1}{#3}% % % For pdftex, we have to write out the node definition (aka, make % the pdfdest) after any page break, but before the actual text has % been typeset. If the destination for the pdf outline is after the % text, then jumping from the outline may wind up with the text not % being visible, for instance under high magnification. \donoderef{#2}% % % Typeset the actual heading. \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{Ynothing}{}% }} \CHAPFplain % The default % I don't think this chapter style is supported any more, so I'm not % updating it with the new noderef stuff. We'll see. --karl, 11aug03. % \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{% \global\let\chapmacro=\chfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. These macros combine the section number parts and % call the generic \sectionheading to do the printing. % \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip{-1000}} % Subsection titles. \newskip\subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} % Subsubsection titles. \def\subsubsecheadingskip{\subsecheadingskip} \def\subsubsecheadingbreak{\subsecheadingbreak} % Print any size, any type, section title. % % #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is % the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the % section number. % \def\sectionheading#1#2#3#4{% {% % Switch to the right set of fonts. \csname #2fonts\endcsname \rm % % Insert space above the heading. \csname #2headingbreak\endcsname % % Only insert the space after the number if we have a section number. \def\sectionlevel{#2}% \def\temptype{#3}% % \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unn}% \gdef\thissection{#1}% \else\ifx\temptype\Yomitfromtockeyword % for @headings -- no section number, don't include in toc, % and don't redefine \thissection. \setbox0 = \hbox{}% \def\toctype{omit}% \let\sectionlevel=\empty \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{#4\enspace}% \def\toctype{app}% \gdef\thissection{#1}% \else \setbox0 = \hbox{#4\enspace}% \def\toctype{num}% \gdef\thissection{#1}% \fi\fi\fi % % Write the toc entry (before \donoderef). See comments in \chfplain. \writetocentry{\toctype\sectionlevel}{#1}{#4}% % % Write the node reference (= pdf destination for pdftex). % Again, see comments in \chfplain. \donoderef{#3}% % % Output the actual section heading. \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent=\wd0 % zero if no section number \unhbox0 #1}% }% % Add extra space after the heading -- half of whatever came above it. % Don't allow stretch, though. \kern .5 \csname #2headingskip\endcsname % % Do not let the kern be a potential breakpoint, as it would be if it % was followed by glue. \nobreak % % We'll almost certainly start a paragraph next, so don't let that % glue accumulate. (Not a breakpoint because it's preceded by a % discardable item.) \vskip-\parskip % % This \nobreak is purely so the last item on the list is a \penalty % of 10000. This is so other code, for instance \parsebodycommon, can % check for and avoid allowing breakpoints. Otherwise, it would % insert a valid breakpoint between: % @section sec-whatever % @deffn def-whatever \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. % % Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} % We append the current node name (if any) and page number as additional % arguments for the \{chap,sec,...}entry macros which will eventually % read this. The node name is used in the pdf outlines as the % destination to jump to. % % We open the .toc file for writing here instead of at @setfilename (or % any other fixed time) so that @contents can be anywhere in the document. % But if #1 is `omit', then we don't do anything. This is used for the % table of contents chapter openings themselves. % \newif\iftocfileopened \def\omitkeyword{omit}% % \def\writetocentry#1#2#3{% \edef\writetoctype{#1}% \ifx\writetoctype\omitkeyword \else \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi % \iflinks \toks0 = {#2}% \toks2 = \expandafter{\lastnode}% \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}% {\the\toks2}{\noexpand\folio}}}% \temp \fi \fi % % Tell \shipout to create a pdf destination on each page, if we're % writing pdf. These are used in the table of contents. We can't % just write one on every page because the title pages are numbered % 1 and 2 (the page numbers aren't printed), and so are the first % two pages of the document. Thus, we'd have two destinations named % `1', and two named `2'. \ifpdf \global\pdfmakepagedesttrue \fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Prepare to read what we've written to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \def\thischapter{}% \chapmacro{#1}{Yomitfromtoc}{}% % \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\numchapentry = \shortchapentry \let\appentry = \shortchapentry \let\unnchapentry = \shortunnchapentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \let\tt=\shortconttt \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\numsecentry##1##2##3##4{} \let\appsecentry = \numsecentry \let\unnsecentry = \numsecentry \let\numsubsecentry = \numsecentry \let\appsubsecentry = \numsecentry \let\unnsubsecentry = \numsecentry \let\numsubsubsecentry = \numsecentry \let\appsubsubsecentry = \numsecentry \let\unnsubsubsecentry = \numsecentry \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } \let\shortcontents = \summarycontents % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `A' for an appendix, or `3' for a chapter. % \def\shortchaplabel#1{% % This space should be enough, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % But use \hss just in case. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) % % We'd like to right-justify chapter numbers, but that looks strange % with appendix letters. And right-justifying numbers and % left-justifying letters looks strange when there is less than 10 % chapters. Have to read the whole toc once to know how many chapters % there are before deciding ... \hbox to 1em{#1\hss}% } % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3#4{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% } % Appendices, in the main contents. % Need the word Appendix, and a fixed-size box. % \def\appendixbox#1{% % We use M since it's probably the widest letter. \setbox0 = \hbox{\putwordAppendix{} M}% \hbox to \wd0{\putwordAppendix{} #1\hss}} % \def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} % Unnumbered chapters. \def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} \def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} % Sections. \def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} \let\appsecentry=\numsecentry \def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. \def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} \let\appsubsecentry=\numsubsecentry \def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} % And subsubsections. \def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} \let\appsubsubsecentry=\numsubsubsecentry \def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 2pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \def\subsecentryfonts{\textfonts} \def\subsubsecentryfonts{\textfonts} \message{environments,} % @foo ... @end foo. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % The @error{} command. % Adapted from the TeXbook's \boxit. % \newbox\errorbox % {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} % \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie \catcode `\%=14 \catcode `\+=\other \catcode `\"=\other \catcode `\==\other \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\indent=\ptexindent \let\noindent=\ptexnoindent \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @end lisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @end lisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% % =10000 instead of <10000 because of a special case in \itemzzz, q.v. \ifnum \lastpenalty=10000 \else \advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip % it's not a good place to break if the last penalty was \nobreak % or better ... \ifnum\lastpenalty>10000 \else \penalty-50 \fi \vskip\envskipamount \fi \fi }} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \def\cartouche{% \par % can't be in the midst of a paragraph. \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \smallexamplefonts \lisp } \let\smallexample = \smalllisp % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % % @smalldisplay: @display plus smaller fonts. % \def\smalldisplay{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \smallexamplefonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % % @smallformat: @format plus smaller fonts. % \def\smallformat{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \smallexamplefonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, % we need the curly braces so that makeinfo sees the @verb command, eg: % `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org % % [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. % % [Knuth] p.344; only we need to do the other characters Texinfo sets % active too. Otherwise, they get lost as the first character on a % verbatim line. \def\dospecials{% \do\ \do\\\do\{\do\}\do\$\do\&% \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% \do\<\do\>\do\|\do\@\do+\do\"% } % % [Knuth] p. 380 \def\uncatcodespecials{% \def\do##1{\catcode`##1=12}\dospecials} % % [Knuth] pp. 380,381,391 % Disable Spanish ligatures ?` and !` of \tt font \begingroup \catcode`\`=\active\gdef`{\relax\lq} \endgroup % % Setup for the @verb command. % % Eight spaces for a tab \begingroup \catcode`\^^I=\active \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} \endgroup % \def\setupverb{% \tt % easiest (and conventionally used) font for verbatim \def\par{\leavevmode\endgraf}% \catcode`\`=\active \tabeightspaces % Respect line breaks, % print special symbols as themselves, and % make each space count % must do in this order: \obeylines \uncatcodespecials \sepspaces } % Setup for the @verbatim environment % % Real tab expansion \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % \def\starttabbox{\setbox0=\hbox\bgroup} \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup \dimen0=\wd0 % the width so far, or since the previous tab \divide\dimen0 by\tabw \multiply\dimen0 by\tabw % compute previous multiple of \tabw \advance\dimen0 by\tabw % advance to next multiple of \tabw \wd0=\dimen0 \box0 \starttabbox }% } \endgroup \def\setupverbatim{% % Easiest (and conventionally used) font for verbatim \tt \def\par{\leavevmode\egroup\box0\endgraf}% \catcode`\`=\active \tabexpand % Respect line breaks, % print special symbols as themselves, and % make each space count % must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } % Do the @verb magic: verbatim text is quoted by unique % delimiter characters. Before first delimiter expect a % right brace, after last delimiter expect closing brace: % % \def\doverb'{'#1'}'{#1} % % [Knuth] p. 382; only eat outer {} \begingroup \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] \endgroup % \def\verb{\begingroup\setupverb\doverb} % % % Do the @verbatim magic: define the macro \doverbatim so that % the (first) argument ends when '@end verbatim' is reached, ie: % % \def\doverbatim#1@end verbatim{#1} % % For Texinfo it's a lot easier than for LaTeX, % because texinfo's \verbatim doesn't stop at '\end{verbatim}': % we need not redefine '\', '{' and '}'. % % Inspired by LaTeX's verbatim command set [latex.ltx] %% Include LaTeX hack for completeness -- never know %% \begingroup %% \catcode`|=0 \catcode`[=1 %% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active %% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ %% #1|endgroup|def|Everbatim[]|end[verbatim]] %% |endgroup % \begingroup \catcode`\ =\active \obeylines % % ignore everything up to the first ^^M, that's the newline at the end % of the @verbatim input line itself. Otherwise we get an extra blank % line in the output. \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% \endgroup % \def\verbatim{% \def\Everbatim{\nonfillfinish\endgroup}% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim\doverbatim } % @verbatiminclude FILE - insert text of file in verbatim environment. % % Allow normal characters that we make active in the argument (a file name). \def\verbatiminclude{% \begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\doverbatiminclude } \def\setupverbatiminclude{% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim } % \def\doverbatiminclude#1{% % Restore active chars for included file. \endgroup \begingroup \let\value=\expandablevalue \def\thisfile{#1}% \expandafter\expandafter\setupverbatiminclude\input\thisfile \endgroup \nonfillfinish \endgroup } % @copying ... @end copying. % Save the text away for @insertcopying later. Many commands won't be % allowed in this context, but that's ok. % % We save the uninterpreted tokens, rather than creating a box. % Saving the text in a box would be much easier, but then all the % typesetting commands (@smallbook, font changes, etc.) have to be done % beforehand -- and a) we want @copying to be done first in the source % file; b) letting users define the frontmatter in as flexible order as % possible is very desirable. % \def\copying{\begingroup % Define a command to swallow text until we reach `@end copying'. % \ is the escape char in this texinfo.tex file, so it is the % delimiter for the command; @ will be the escape char when we read % it, but that doesn't matter. \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% % % We must preserve ^^M's in the input file; see \insertcopying below. \catcode`\^^M = \active \docopying } % What we do to finish off the copying text. % \def\enddocopying{\endgroup\ignorespaces} % @insertcopying. Here we must play games with ^^M's. On the one hand, % we need them to delimit commands such as `@end quotation', so they % must be active. On the other hand, we certainly don't want every % end-of-line to be a \par, as would happen with the normal active % definition of ^^M. On the third hand, two ^^M's in a row should still % generate a \par. % % Our approach is to make ^^M insert a space and a penalty1 normally; % then it can also check if \lastpenalty=1. If it does, then manually % do \par. % % This messes up the normal definitions of @c[omment], so we redefine % it. Similarly for @ignore. (These commands are used in the gcc % manual for man page generation.) % % Seems pretty fragile, most line-oriented commands will presumably % fail, but for the limited use of getting the copying text (which % should be quite simple) inserted, we can hope it's ok. % {\catcode`\^^M=\active % \gdef\insertcopying{\begingroup % \parindent = 0pt % looks wrong on title page \def^^M{% \ifnum \lastpenalty=1 % \par % \else % \space \penalty 1 % \fi % }% % % Fix @c[omment] for catcode 13 ^^M's. \def\c##1^^M{\ignorespaces}% \let\comment = \c % % % Don't bother jumping through all the hoops that \doignore does, it % would be very hard since the catcodes are already set. \long\def\ignore##1\end ignore{\ignorespaces}% % \copyingtext % \endgroup}% } \message{defuns,} % @defun etc. \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % We want ()&[] to print specially on the defun line. % \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active } % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = \active \global\let& = \ampnr } % \defname, which formats the name of the @def (not the args). % #1 is the function name. % #2 is the type of definition, such as "Function". % \def\defname#1#2{% % How we'll output the type name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \ifempty{#2}% \def\defnametype{}% \else \def\defnametype{[\rm #2]}% \fi % % Get the values of \leftskip and \rightskip as they were outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent % % Figure out values for the paragraph shape. \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Output arg 2 ("Function" or some such) but stuck inside a box of % width 0 so it does not interfere with linebreaking. \noindent % {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \dimen3 = 0pt % was -1.25pc \rlap{\rightline{\defnametype\kern\dimen3}}% }% % % Allow all lines to be underfull without complaint: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % output function name % \defunargs will be called next to output the arguments, if any. } % Common pieces to start any @def... % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence (which our caller defines). % #3 is the control sequence to process the header, such as \defunheader. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % If there are two @def commands in a row, we'll have a \nobreak, % which is there to keep the function description together with its % header. But if there's nothing but headers, we need to allow a % break somewhere. Check for penalty 10002 (inserted by % \defargscommonending) instead of 10000, since the sectioning % commands insert a \penalty10000, and we don't want to allow a break % between a section heading and a defun. \ifnum\lastpenalty=10002 \penalty2000 \fi % % Similarly, after a section heading, do not allow a break. % But do insert the glue. \ifnum\lastpenalty<10000 \medbreak \else \medskip % preceded by discardable penalty, so not a breakpoint \fi % % Define the \E... end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } % Common part of the \...x definitions. % \def\defxbodycommon{% % As with \parsebodycommon above, allow line break if we have multiple % x headers in a row. It's not a great place, though. \ifnum\lastpenalty=10002 \penalty2000 \fi % \begingroup\obeylines } % Process body of @defun, @deffn, @defmac, etc. % \def\defparsebody#1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \activeparens \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines\activeparens \spacesplit#3% } % #1, #2, #3 are the common arguments (see \parsebodycommon above). % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% \begingroup\obeylines\activeparens % The \empty here prevents misinterpretation of a construct such as % @deffn {whatever} {Enharmonic comma} % See comments at \deftpparsebody, although in our case we don't have % to remove the \empty afterwards, since it is empty. \spacesplit{#3{#4}}\empty } % Used for @deftypemethod and @deftypeivar. % #1, #2, #3 are the common arguments (see \defparsebody). % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#4}{#5}}% } % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 ##3 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}{#6}}% } % For @defop. \def\defopparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}}% } % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. % \def\defvarparsebody #1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines \spacesplit#3% } % @defopvar. \def\defopvarparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \spacesplit{#3{##2}}}% \begingroup\obeylines \spacesplit{#3{#5}}% } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% % Split up #2 (the rest of the input line) at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. % {\obeylines % \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% \ifx\relax #3% #1{#2}{}% \else % #1{#2}{#3#4}% \fi}% } % Define @defun. % This is called to end the arguments processing for all the @def... commands. % \def\defargscommonending{% \interlinepenalty = 10000 \advance\rightskip by 0pt plus 1fil \endgraf \nobreak\vskip -\parskip \penalty 10002 % signal to \parsebodycommon and \defxbodycommon. } % This expands the args and terminates the paragraph they comprise. % \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \defargscommonending } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \defargscommonending } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$.$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$.$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry \begingroup \defname{#2}{\defoptype\ \putwordon\ #1}% \defunargs{#3}% \endgroup } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry \begingroup \defname{#2}{\defcvtype\ \putwordof\ #1}% \defvarargs{#3}% \endgroup } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \defargscommonending } % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% \defargscommonending \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} \defargscommonending \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\endcsname \csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \. % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. \def\macrobodyctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\{=\other \catcode`\}=\other \catcode`\@=\other \catcode`\^^M=\other \usembodybackslash} \def\macroargctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\@=\other \catcode`\\=\other} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0% \else \expandafter\parsemargdef \argl;% \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% \else \expandafter\ifx\csname \the\macname\endcsname \relax \else \errmessage{Macro name \the\macname\space already defined}\fi \global\cslet{macsave.\the\macname}{\the\macname}% \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\dounmacro} \def\dounmacro#1{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% % Remove the macro name from \macrolist: \begingroup \expandafter\let\csname#1\endcsname \relax \let\do\unmacrodo \xdef\macrolist{\macrolist}% \endgroup \else \errmessage{Macro #1 not defined}% \fi } % Called by \do from \dounmacro on each macro. The idea is to omit any % macro definitions that have been changed to \relax. % \def\unmacrodo#1{% \ifx#1\relax % remove this \else \noexpand\do \noexpand #1% \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname #1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.blah for each blah % in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \expandafter\noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \fi \fi} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. \def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{\ignoreactivespaces \edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% \expandafter\noexpand\csname#2\endcsname}% \expandafter\endgroup\next} \message{cross references,} \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's only job in TeX is to define \lastnode, which is used in % cross-references. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx #1,\finishnodeparse} \def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\empty % Write a cross-reference definition for the current node. #1 is the % type (Ynumbered, Yappendix, Ynothing). % \def\donoderef#1{% \ifx\lastnode\empty\else \expandafter\expandafter\expandafter\setref{\lastnode}{#1}% \global\let\lastnode=\empty \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister % \gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % anchor), namely NAME-title (the corresponding @chapter/etc. name), % NAME-pg (the page number), and NAME-snt (section number and type). % Called from \foonoderef. % % We have to set dummies so commands such as @code in a section title % aren't expanded. It would be nicer not to expand the titles in the % first place, but that is hard to do. % % Likewise, use \turnoffactive so that punctuation chars such as underscore % and backslash work in node names. % \def\setref#1#2{{% \atdummies \pdfmkdest{#1}% % \iflinks \turnoffactive \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% \fi }} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifpdf \leavevmode \getfilename{#4}% {\turnoffactive \otherbackslash \ifnum\filenamelength>0 \startlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1}% \else \startlink attr{/Border [0 0 0]}% goto name{\pdfmkpgn{#1}}% \fi }% \linkcolor \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\turnoffactive \otherbackslash % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % output the `[mynode]' via a macro. \xrefprintnodename\printednodename % % But we always want a comma and a space: ,\space % % output the `page 3'. \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, % since not square brackets don't work in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} % \dosetq is called from \setref to do the actual \write (\iflinks). % \def\dosetq#1#2{% \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \next } % \internalsetq{foo}{page} expands into % CHARACTERS @xrdef{foo}{...expansion of \page...} \def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq. % \def\Ypagenumber{\noexpand\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Yomitfromtoc{} \def\Ynumbered{% \ifnum\secno=0 \putwordChapter@tie \the\chapno \else \ifnum\subsecno=0 \putwordSection@tie \the\chapno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie \the\chapno.\the\secno.\the\subsecno \else \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } \def\Yappendix{% \ifnum\secno=0 \putwordAppendix@tie @char\the\appendixno{}% \else \ifnum\subsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno \else \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Pre-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. % \def\refx#1#2{% {% \indexnofonts \otherbackslash \expandafter\global\expandafter\let\expandafter\thisrefX \csname X#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \thisrefX \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\^=\other % % Special characters. Should be turned off anyway, but... \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`\%=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\\=\other % % @ is our escape character in .aux files. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent \let\noindent=\ptexnoindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \dofootnote }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % % The start of the footnote looks usually like this: \gdef\startfootins{\insert\footins\bgroup} % % ... but this macro is redefined inside @multitable. % \gdef\dofootnote{% \startfootins % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \hsize=\pagewidth \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % \smallfonts \rm % % Because we use hanging indentation in footnotes, a @noindent appears % to exdent this text, so make it be a no-op. makeinfo does not use % hanging indentation so @noindent can still be needed within footnote % text after an @example or the like (not that this is good style). \let\noindent = \relax % % Hang the footnote text off the number. Use \everypar in case the % footnote extends for more than one paragraph. \everypar = {\hang}% \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } }%end \catcode `\@=11 % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 % Do not bother showing banner with epsf.tex v2.7k (available in % doc/epsf.tex and on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. % #6 is just the usual extra ignored arg for parsing this stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names % If the image is by itself, center it. \ifvmode \imagevmodetrue \nobreak\bigskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space % above and below. \nobreak\vskip\parskip \nobreak \line\bgroup\hss \fi % % Output the image. \ifpdf \dopdfimage{#1}{#2}{#3}% \else % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \epsfbox{#1.eps}% \fi % \ifimagevmode \hss \egroup \bigbreak \fi % space after the image \endgroup} \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. We call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = .15\hsize \fi } % Parameters in order: 1) textheight; 2) textwidth; 3) voffset; % 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8) % physical page width. % % We also call \setleading{\textleading}, so the caller should define % \textleading. The caller should also set \parskip. % \def\internalpagesizes#1#2#3#4#5#6#7#8{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \ifpdf \pdfpageheight #7\relax \pdfpagewidth #8\relax \fi % \setleading{\textleading} % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % If page is nothing but text, make it come out even. \internalpagesizes{46\baselineskip}{6in}% {\voffset}{.25in}% {\bindingoffset}{36pt}% {11in}{8.5in}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \textleading = 12pt % \internalpagesizes{7.5in}{5in}% {\voffset}{.25in}% {\bindingoffset}{16pt}% {9.25in}{7in}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % Double-side printing via postscript on Laserjet 4050 % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. % To change the settings for a different printer or situation, adjust % \normaloffset until the front-side and back-side texts align. Then % do the same for \bindingoffset. You can set these for testing in % your texinfo source file like this: % @tex % \global\normaloffset = -6mm % \global\bindingoffset = 10mm % @end tex \internalpagesizes{51\baselineskip}{160mm} {\voffset}{\hoffset}% {\bindingoffset}{44pt}% {297mm}{210mm}% % \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = 5mm }} % Use @afivepaper to print on European A5 paper. % From romildo@urano.iceb.ufop.br, 2 July 2000. % He also recommends making @example and @lisp be small. \def\afivepaper{{\globaldefs = 1 \parskip = 2pt plus 1pt minus 0.1pt \textleading = 12.5pt % \internalpagesizes{160mm}{120mm}% {\voffset}{\hoffset}% {\bindingoffset}{8pt}% {210mm}{148mm}% % \lispnarrowing = 0.2in \tolerance = 800 \hfuzz = 1.2pt \contentsrightmargin = 0pt \defbodyindent = 2mm \tableindent = 12mm }} % A specific text layout, 24x15cm overall, intended for A4 paper. \def\afourlatex{{\globaldefs = 1 \afourpaper \internalpagesizes{237mm}{150mm}% {\voffset}{4.6mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% % % Must explicitly reset to 0 because we call \afourpaper. \globaldefs = 0 }} % Use @afourwide to print on A4 paper in landscape format. \def\afourwide{{\globaldefs = 1 \afourpaper \internalpagesizes{241mm}{165mm}% {\voffset}{-2.95mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% \globaldefs = 0 }} % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{\textleading}% % \dimen0 = #1 \advance\dimen0 by \voffset % \dimen2 = \hsize \advance\dimen2 by \normaloffset % \internalpagesizes{#1}{\hsize}% {\voffset}{\normaloffset}% {\bindingoffset}{44pt}% {\dimen0}{\dimen2}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$}%$ font-lock fix % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} % Same as above, but check for italic font. Actually this also catches % non-italic slanted fonts since it is impossible to distinguish them from % italic fonts. But since this is only used by $ and it uses \sl anyway % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx outputs one backslash character in current font, % as in \char`\\. \global\chardef\rawbackslashxx=`\\ % \rawbackslash defines an active \ to do \rawbackslashxx. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx} @gdef@otherbackslash{@let\=@realbackslash} } % \realbackslash is an actual character `\' with catcode other. {\catcode`\\=\other @gdef@realbackslash{\}} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{% @let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar %$ font-lock fix } % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. (Thus, \ is not expandable when this is in % effect.) % @def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{% @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active } % Say @foo, not \foo, in error messages. @escapechar = `@@ % These look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: gvpe-3.0/doc/gvpe.texi0000644000000000000000000024105313011103357011604 00000000000000\input texinfo @c -*-texinfo-*- @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c %**start of header @finalout @setfilename gvpe.info @settitle GNU Virtual Private Ethernet Manual @setchapternewpage odd @c %**end of header @ifinfo @dircategory Networking tools @direntry * gvpe: (gvpe). The GNU VPE Manual. @end direntry This is the info manual for vpe, the Virtual Private Ethernet daemon. Copyright @copyright{} 2003-2008 Marc Lehmann . Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. @end ifinfo @titlepage @title gvpe Manual @author Marc Lehmann @page @vskip 0pt plus 1filll @cindex copyright Copyright @copyright{} 2003-2008 Marc Lehmann . Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. @end titlepage @contents @node Top,Overview,,(dir) @chapter Introduction This is the documentation for the GNU Virtual Private Ethernet suite. @refill The GNU Virtual Private Ethernet suite implements a virtual (uses udp, tcp, rawip and other protocols for tunneling), private (encrypted, authenticated) ethernet (mac-based, broadcast-based network) that is shared among multiple nodes, in effect implementing an ethernet bus over public networks. @refill @menu * Overview:: Introduction to and Tutorial for GVPE (gvpe(5)) * OS Dependencies:: OS-Dependent Installation and Configuration Notes (gvpe.osdep(5)) * gvpe.conf:: The main configuration file (gvpe.conf(5)) * gvpectrl:: Configuration/Control Program Reference (gvpectrl(8)) * gvpe:: The GVPE Daemon (gvpe(8)) * gvpe.protocol:: The GVPE Transport and VPN Protocols (gvpe.protocol(7)) * Simple Example:: A simple yet realistic Example * Complex Example:: A non-trivial Example * Index:: Keyword and Concept index @end menu @node Overview,OS Dependencies,Top,Top @chapter Overview @section NAME GNU-VPE - Overview of the GNU Virtual Private Ethernet suite. @refill @section DESCRIPTION GVPE is a suite designed to provide a virtual private network for multiple nodes over an untrusted network. This document first gives an introduction to VPNs in general and then describes the specific implementation of GVPE. @refill @subsection WHAT IS A VPN? VPN is an acronym, it stands for: @refill @itemize @item Virtual Virtual means that no physical network is created (of course), but a network is @emph{emulated} by creating multiple tunnels between the member nodes by encapsulating and sending data over another transport network. @refill Usually the emulated network is a normal IP or Ethernet, and the transport network is the Internet. However, using a VPN system like GVPE to connect nodes over other untrusted networks such as Wireless LAN is not uncommon. @refill @item Private Private means that non-participating nodes cannot decode ("sniff)" nor inject ("spoof") packets. This means that nodes can be connected over untrusted networks such as the public Internet without fear of being eavesdropped while at the same time being able to trust data sent by other nodes. @refill In the case of GVPE, even participating nodes cannot sniff packets send to other nodes or spoof packets as if sent from other nodes, so communications between any two nodes is private to those two nodes. @refill @item Network Network means that more than two parties can participate in the network, so for instance it's possible to connect multiple branches of a company into a single network. Many so-called "VPN" solutions only create point-to-point tunnels, which in turn can be used to build larger networks. @refill GVPE provides a true multi-point network in which any number of nodes (at least a few dozen in practise, the theoretical limit is 4095 nodes) can participate. @refill @end itemize @subsection GVPE DESIGN GOALS @itemize @item SIMPLE DESIGN Cipher, HMAC algorithms and other key parameters must be selected at compile time - this makes it possible to only link in algorithms you actually need. It also makes the crypto part of the source very transparent and easy to inspect, and last not least this makes it possible to hardcode the layout of all packets into the binary. GVPE goes a step further and internally reserves blocks of the same length for all packets, which virtually removes all possibilities of buffer overflows, as there is only a single type of buffer and it's always of fixed length. @refill @item EASY TO SETUP A few lines of config (the config file is shared unmodified between all hosts) and generating an RSA key-pair on each node suffices to make it work. @refill @item MAC-BASED SECURITY Since every host has it's own private key, other hosts cannot spoof traffic from this host. That makes it possible to filter packet by MAC address, e.g. to ensure that packets from a specific IP address come, in fact, from a specific host that is associated with that IP and not from another host. @refill @end itemize @section PROGRAMS Gvpe comes with two programs: one daemon (@t{gvpe}) and one control program (@t{gvpectrl}). @refill @itemize @item gvpectrl This program is used to generate the keys, check and give an overview of of the configuration and to control the daemon (restarting etc.). @refill @item gvpe This is the daemon used to establish and maintain connections to the other network nodes. It should be run on the gateway of each VPN subnet. @refill @end itemize @section COMPILETIME CONFIGURATION Please have a look at the @t{gvpe.osdep(5)} manpage for platform-specific information. @refill Gvpe hardcodes most encryption parameters. While this reduces flexibility, it makes the program much simpler and helps making buffer overflows impossible under most circumstances. @refill Here are a few recipes for compiling your gvpe, showing the extremes (fast, small, insecure OR slow, large, more secure), between which you should choose: @refill @subsection AS LOW PACKET OVERHEAD AS POSSIBLE @example ./configure --enable-hmac-length=4 --enable-rand-length=0 @end example Minimize the header overhead of VPN packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a HMAC length of 4 makes collision attacks almost trivial. @refill @subsection MINIMIZE CPU TIME REQUIRED @example ./configure --enable-cipher=bf --enable-digest=md4 @end example Use the fastest cipher and digest algorithms currently available in gvpe. MD4 has been broken and is quite insecure, though, so using another digest algorithm is recommended. @refill @subsection MAXIMIZE SECURITY @example ./configure --enable-hmac-length=16 --enable-rand-length=12 --enable-digest=ripemd610 @end example This uses a 16 byte HMAC checksum to authenticate packets (I guess 8-12 would also be pretty secure ;) and will additionally prefix each packet with 12 bytes of random data. @refill In general, remember that AES-128 seems to be as secure but faster than AES-192 or AES-256, more randomness helps against sniffing and a longer HMAC helps against spoofing. MD4 is a fast digest, SHA1, RIPEMD160, SHA256 are consecutively better, and Blowfish is a fast cipher (and also quite secure). @refill @section HOW TO SET UP A SIMPLE VPN In this section I will describe how to get a simple VPN consisting of three hosts up and running. @refill @subsection STEP 1: configuration First you have to create a daemon configuration file and put it into the configuration directory. This is usually @t{/etc/gvpe}, depending on how you configured gvpe, and can be overwritten using the @t{-c} command line switch. @refill Put the following lines into @t{/etc/gvpe/gvpe.conf}: @refill @example udp-port = 50000 # the external port to listen on (configure your firewall) mtu = 1400 # minimum MTU of all outgoing interfaces on all hosts ifname = vpn0 # the local network device name node = first # just a nickname hostname = first.example.net # the DNS name or IP address of the host node = second hostname = 133.55.82.9 node = third hostname = third.example.net @end example The only other file necessary is the @t{if-up} script that initializes the virtual ethernet interface on the local host. Put the following lines into @t{/etc/gvpe/if-up} and make it executable (@t{chmod 755 /etc/gvpe/if-up}): @refill @example #!/bin/sh ip link set $IFNAME address $MAC mtu $MTU up [ $NODENAME = first ] && ip addr add 10.0.1.1 dev $IFNAME [ $NODENAME = second ] && ip addr add 10.0.2.1 dev $IFNAME [ $NODENAME = third ] && ip addr add 10.0.3.1 dev $IFNAME ip route add 10.0.0.0/16 dev $IFNAME @end example This script will give each node a different IP address in the @t{10.0/16} network. The internal network (if gvpe runs on a router) should then be set to a subset of that network, e.g. @t{10.0.1.0/24} on node @t{first}, @t{10.0.2.0/24} on node @t{second}, and so on. @refill By enabling routing on the gateway host that runs @t{gvpe} all nodes will be able to reach the other nodes. You can, of course, also use proxy ARP or other means of pseudo-bridging, or (best) full routing - the choice is yours. @refill @subsection STEP 2: create the RSA key pair for each node Next you have to generate the RSA keys for the nodes. While you can set up GVPE so you can generate all keys on a single host and centrally distribute all keys, it is safer to generate the key for each node on the node, so that the secret/private key does not have to be copied over the network. @refill To do so, run the following command to generate a key pair: @refill @example gvpectrl -c /etc/gvpe -g nodekey @end example This will create two files, @file{nodekey} and @file{nodekey.privkey}. The former should be copied to @file{/etc/gvpe/pubkey/@emph{nodename}} on the host where your config file is (you will have to create the @file{pubkey} directory first): @refill @example scp nodekey confighost:/etc/gvpe/pubkey/nodename @end example The private key @file{nodekey.privkey} should be moved to @file{/etc/gvpe/hostkey}: @refill @example mkdir -p /etc/gvpe mv nodekey.privkey /etc/gvpe/hostkey @end example @subsection STEP 3: distribute the config files to all nodes Now distribute the config files and public keys to the other nodes. @refill The example uses rsync-over-ssh to copy the config file and all the public keys: @refill @example rsync -avzessh /etc/gvpe first.example.net:/etc/. --exclude hostkey rsync -avzessh /etc/gvpe 133.55.82.9:/etc/. --exclude hostkey rsync -avzessh /etc/gvpe third.example.net:/etc/. --exclude hostkey @end example You should now check the configuration by issuing the command @t{gvpectrl -c /etc/gvpe -s} on each node and verify it's output. @refill @subsection STEP 4: starting gvpe You should then start gvpe on each node by issuing a command like: @refill @example gvpe -D -l info first # first is the nodename @end example This will make the gvpe daemon stay in foreground. You should then see "connection established" messages. If you don't see them check your firewall and routing (use tcpdump ;). @refill If this works you should check your networking setup by pinging various endpoints. @refill To make gvpe run more permanently you can either run it as a daemon (by starting it without the @t{-D} switch), or, much better, from your inittab or equivalent. I use a line like this on all my systems: @refill @example t1:2345:respawn:/opt/gvpe/sbin/gvpe -D -L first >/dev/null 2>&1 @end example @subsection STEP 5: enjoy ... and play around. Sending a -HUP (@t{gvpectrl -kHUP}) to the daemon will make it try to connect to all other nodes again. If you run it from inittab @t{gvpectrl -k} (or simply @t{killall gvpe}) will kill the daemon, start it again, making it read it's configuration files again. @refill To run the GVPE daemon permanently from your SysV init, you can add it to your @file{inittab}, e.g.: @refill @example t1:2345:respawn:/bin/sh -c "exec nice -n-20 /path/to/gvpe -D node >/var/log/gvpe.log 2>&1" @end example For systems using systemd, you can use a unit file similar to this one: @refill @example [Unit] Description=gvpe After=network.target Before=remote-fs.target [Service] ExecStart=/path/to/gvpe -D node KillMode=process Restart=always [Install] WantedBy=multi-user.target @end example @section COPYRIGHTS AND LICENSES GVPE itself is distributed under the GENERAL PUBLIC LICENSE (see the file COPYING that should be part of your distribution). @refill In some configurations it uses modified versions of the tinc vpn suite, which is also available under the GENERAL PUBLIC LICENSE. @refill @node OS Dependencies,gvpe.conf,Overview,Top @chapter OS Dependencies @section NAME gvpe.osdep - os dependent information @refill @section DESCRIPTION This file tries to capture OS-dependent configuration or build issues, quirks and platform limitations, as known. @refill @section TUN vs. TAP interface Most operating systems nowadays support something called a @emph{tunnel}-device, which makes it possible to divert IPv4 (and often other protocols, too) into a user space daemon like @t{gvpe}. This is being referred to as a TUN-device. @refill This is fine for point-to-point tunnels, but for a virtual ethernet, an additional ethernet header is needed. This functionality (called a TAP device here) is only provided by a subset of the configurations. @refill On platforms only supporting a TUN-device, gvpe will invoke it's magical ethernet emulation package, which currently only handles ARP requests for the IPv4 protocol (but more could be added, bu the tincd network drivers might need to be modified for this to work). This means that on those platforms, only IPv4 will be supported. @refill Also, since there is no way (currently) to tell gvpe which IP subnets are found on a specific host, you will either need to hardwire the MAC address for TUN-style hosts on all networks (and avoid ARP altogether, which is possible), or you need to send a packet from these hosts into the vpn network to tell gvpe the local interface address. @refill @section Interface Initialisation Unless otherwise notes, the network interface will be initialized with the expected MAC address and correct MTU value. With most interface drivers, this is done by running @t{/sbin/ifconfig}, so make sure that this command exists. @refill @section Interface Types @subsection native/linux TAP-device; already part of the kernel (only 2.4+ supported, but see tincd/linux). This is the configuration tested best, as gvpe is being developed on this platform. @refill @t{ifname} should be set to the name of the network device. @refill To hardwire ARP addresses, use iproute2 (@t{arp} can do it, too): @refill @example MAC=fe:fd:80:00:00:$(printf "%02x" $NODEID) ip neighbour add 10.11.12.13 lladdr $MAC nud permanent dev $IFNAME @end example @subsection tincd/linux TAP-device; already part of the kernel (2.2 only). See @t{native/linux} for more info. @refill @t{ifname} should be set to the path of a tap device, e.g. @t{/dev/tap0}. The interface will be named accordingly. @refill @subsection native/cygwin TAP-device; The TAP device to be used must either be the CIPE driver (@t{http://cipe-win32.sourceforge.net/}), or (highly recommended) the newer TAP-Win32 driver bundled with openvpn (http://openvpn.sf.net/). Just download and run the openvpn installer. The only option you need to select is the TAP driver. @refill @t{ifname} should be set to the name of the device, found in the registry at (no kidding :): @refill @example HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\@{4D36E972-E325-11CE-BFC1-08002BE10318@}\\Connection\Name @end example The MAC address is dynamically being patched into packets and ARP-requests, so only IPv4 works with ARP on this platform. @refill @subsection tincd/bsd TAP-device, maybe; migth work for many bsd variants. @refill This driver is a newer version of the @t{tincd/*bsd} drivers. It @emph{might} provide a TAP device, or might not work at all. You might try this interface type first, and, if it doesn't work, try one of the OS-specific drivers. @refill @subsection tincd/freebsd TAP-device; part of the kernel (since 4.x, maybe earlier). @refill @t{ifname} should be set to the path of a tap device, e.g. @t{/dev/tap0}. The interface will be named accordingly. @refill These commands might be helpful examples: @refill @example ifconfig $IFNAME 10.0.0.$NODEID route add -net 10.0.0.0 -netmask 255.255.255.0 -interface $IFNAME 10.0.0.$NODEID @end example @subsection tincd/netbsd TUN-device; The interface is a point-to-point device. To initialize it, you currently need to configure it as a point-to-point device, giving it an address on your vpn (the exact address doesn't matter), like this: @refill @example ifconfig $IFNAME mtu $MTU up ifconfig $IFNAME 10.11.12.13 10.55.66.77 route add -net 10.0.0.0 10.55.66.77 255.0.0.0 ping -c1 10.55.66.77 # ping once to tell gvpe your gw ip @end example The ping is required to tell the ARP emulator inside GVPE the local IP address. @refill @t{ifname} should be set to the path of a tun device, e.g. @t{/dev/tun0}. The interface will be named accordingly. @refill @subsection tincd/openbsd TUN-device; already part of the kernel. See @t{tincd/netbsd} for more information. @refill @subsection native/darwin TAP-device; @refill The necessary kernel extension can be found here: @refill @example http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ @end example There are two drivers, the one to use is the "tap" driver. It driver must be loaded before use, read the docs on how to install it as a startup item. @refill @t{ifname} should be set to the path of a tap device, e.g. @t{/dev/tap0}. The interface will be named accordingly. @refill These commands might be helpful examples: @refill @example ifconfig $IFNAME 10.0.0.$NODEID route add -net 10.0.0.0 -interface $IFNAME 255.255.255.0 @end example @subsection tincd/darwin TUN-device; See @t{tincd/netbsd} for more information. @t{native/darwin} is preferable. @refill The necessary kernel extension can be found here: @refill @example http://chrisp.de/en/projects/tunnel.html @end example @t{ifname} should be set to the path of a tun device, e.g. @t{/dev/tun0}. The interface will be named accordingly. @refill The driver must be loaded before use: @refill @example kmodload tunnel @end example @subsection tincd/solaris TUN-device; already part of the kernel(?), or available here: @refill @example http://vtun.sourceforge.net/tun/ @end example Some precompiled tun drivers might be available here: @refill @example http://www.monkey.org/~dugsong/fragroute/ @end example The interface MAC and MTU are @emph{NOT} set up for you. Please try it out and send me an @t{ifconfig} command invocation that does that. @refill See @t{tincd/netbsd} for more information. @refill Completely untested so far. @refill @subsection tincd/mingw TAP-device; see @t{native/cygwin} for more information. @refill The setup is likely to be similar to @t{native/cygwin}. @refill Completely untested so far. @refill @subsection tincd/raw_socket TAP-device; purpose unknown and untested, probably binds itself on an existing ethernet device (given by @t{ifname}). It must be down prior to running the command, and GVPE will try to set it's MAC address and MTU to the "correct" values. @refill Completely untested so far. @refill @subsection tincd/uml_socket TAP-device; purpose unknown and untested, probably creates a UNIX datagram socket (path given by @t{ifname}) and reads and writes raw packets, so might be useful in other than UML contexts. @refill No network interface is created, and the MAC and MTU must be set as appropriate on the other side of the socket. GVPE will exit if the MAC address doesn't match what it expects. @refill Completely untested so far. @refill @subsection tincd/cygwin Known to be broken, use @t{native/cygwin} instead. @refill @node gvpe.conf,gvpectrl,OS Dependencies,Top @chapter gvpe.conf @section NAME gvpe.conf - configuration file for the GNU VPE daemon @refill @section SYNOPSIS @example # global options for all nodes udp-port = 407 mtu = 1492 ifname = vpn0 # first node is named branch1 and is at 1.2.3.4 node = branch1 hostname = 1.2.3.4 # second node uses dns to resolve the address node = branch2 hostname = www.example.net udp-port = 500 # this host uses a different udp-port # third node has no fixed ip address node = branch3 connect = ondemand @end example @section DESCRIPTION The gvpe config file consists of a series of lines that contain @t{variable = value} pairs. Empty lines are ignored. Comments start with a @t{#} and extend to the end of the line. They can be used on their own lines, or after any directives. Whitespace is allowed around the @t{=} sign or after values, but not within the variable names or values themselves. @refill All settings are applied "in order", that is, later settings of the same variable overwrite earlier ones. @refill The only exceptions to the above are the following directives: @refill @itemize @item node nodename Introduces a node section. The nodename is used to select the right configuration section and is the same string as is passed as an argument to the gvpe daemon. @refill Multiple @t{node} statements with the same node name are supported and will be merged together. @refill @item global This statement switches back to the global section, which is mainly useful if you want to include a second config file, e..g for local customisations. To do that, simply include this at the very end of your config file: @refill @example global include local.conf @end example @item on nodename ... @item on !nodename ... You can prefix any configuration directive with @t{on} and a nodename. GVPE will will only "execute" it on the named node, or (if the nodename starts with @t{!}) on all nodes except the named one. @refill Example: set the MTU to @t{1450} everywhere, @t{loglevel} to @t{noise} on @t{branch1}, and @t{connect} to @t{ondemand} everywhere but on branch2. @refill @example mtu = 1450 on branch1 loglevel = noise on !branch2 connect = ondemand @end example @item include relative-or-absolute-path Reads the specified file (the path must not contain whitespace or @t{=} characters) and evaluate all config directives in it as if they were spelled out in place of the @t{include} directive. @refill The path is a printf format string, that is, you must escape any @t{%} by doubling it, and you can have a single @t{%s} inside, which will be replaced by the current nodename. @refill Relative paths are interpreted relative to the GVPE config directory. @refill Example: include the file @file{local.conf} in the config directory on every node. @refill @example include local.conf @end example Example: include a file @file{conf/}nodename@file{.conf} @refill @example include conf/%s.conf @end example @end itemize @section ANATOMY OF A CONFIG FILE Usually, a config file starts with a few global settings (like the UDP port to listen on), followed by node-specific sections that begin with a @t{node = nickname} line. @refill Every node that is part of the network must have a section that starts with @t{node = nickname}. The number and order of the nodes is important and must be the same on all nodes. It is not uncommon for node sections to be completely empty - if the default values are right. @refill Node-specific settings can be used at any time. If used before the first node section they will set the default values for all following nodes. @refill @section CONFIG VARIABLES @subsection GLOBAL SETTINGS Global settings will affect the behaviour of the running gvpe daemon, that is, they are in some sense node-specific (config files can set different values on different nodes using @t{on}), but will affect the behaviour of the gvpe daemon and all connections it creates. @refill @itemize @item chroot = path or / @cindex chroot Tells GVPE to chroot(2) to the specified path after reading all necessary files, binding to sockets and running the @t{if-up} script, but before running @t{node-up} or any other scripts. @refill The special path @file{/} instructs GVPE to create (and remove) an empty temporary directory to use as new root. This is most secure, but makes it impossible to use any scripts other than the @t{if-up} one. @refill @item chuid = numerical-uid @cindex chuid @item chgid = numerical-gid @cindex chgid These two options tell GVPE to change to the given user and/or group id after reading all necessary files, binding to sockets and running the @t{if-up} script. @refill Other scripts, such as @t{node-up}, are run with the new user id or group id. @refill @item chuser = username @cindex chuser Alternative to @t{chuid} and @t{chgid}: Sets both @t{chuid} and @t{chgid} to the user and (primary) group ids of the specified user (for example, @t{nobody}). @refill @item dns-forw-host = hostname/ip @cindex dns-forw-host The DNS server to forward DNS requests to for the DNS tunnel protocol (default: @t{127.0.0.1}, changing it is highly recommended). @refill @item dns-forw-port = port-number @cindex dns-forw-port The port where the @t{dns-forw-host} is to be contacted (default: @t{53}, which is fine in most cases). @refill @item dns-case-preserving = yes|true|on | no|false|off @cindex dns-case-preserving Sets whether the DNS transport forwarding server preserves case (DNS servers have to, but some access systems are even more broken than others) (default: true). @refill Normally, when the forwarding server changes the case of domain names then GVPE will automatically set this to false. @refill @item dns-max-outstanding = integer-number-of-requests @cindex dns-max-outstanding The maximum number of outstanding DNS transport requests (default: @t{100}). GVPE will never issue more requests then the given limit without receiving replies. In heavily overloaded situations it might help to set this to a low number (e.g. @t{3} or even @t{1}) to limit the number of parallel requests. @refill The default should be working OK for most links. @refill @item dns-overlap-factor = float @cindex dns-overlap-factor The DNS transport uses the minimum request latency (@strong{min_latency}) seen during a connection as it's timing base. This factor (default: @t{0.5}, must be > 0) is multiplied by @strong{min_latency} to get the maximum sending rate (= minimum send interval), i.e. a factor of @t{1} means that a new request might be generated every @strong{min_latency} seconds, which means on average there should only ever be one outstanding request. A factor of @t{0.5} means that GVPE will send requests twice as often as the minimum latency measured. @refill For congested or picky DNS forwarders you could use a value nearer to or exceeding @t{1}. @refill The default should be working OK for most links. @refill @item dns-send-interval = send-interval-in-seconds @cindex dns-send-interval The minimum send interval (= maximum rate) that the DNS transport will use to send new DNS requests. GVPE will not exceed this rate even when the latency is very low. The default is @t{0.01}, which means GVPE will not send more than 100 DNS requests per connection per second. For high-bandwidth links you could go lower, e.g. to @t{0.001} or so. For congested or rate-limited links, you might want to go higher, say @t{0.1}, @t{0.2} or even higher. @refill The default should be working OK for most links. @refill @item dns-timeout-factor = float @cindex dns-timeout-factor Factor to multiply the @t{min_latency} (see @t{dns-overlap-factor}) by to get request timeouts. The default of @t{8} means that the DNS transport will resend the request when no reply has been received for longer than eight times the minimum (= expected) latency, assuming the request or reply has been lost. @refill For congested links a higher value might be necessary (e.g. @t{30}). If the link is very stable lower values (e.g. @t{2}) might work nicely. Values near or below @t{1} makes no sense whatsoever. @refill The default should be working OK for most links but will result in low throughput if packet loss is high. @refill @item if-up = relative-or-absolute-path @cindex if-up Sets the path of a script that should be called immediately after the network interface is initialized (but not necessarily up). The following environment variables are passed to it (the values are just examples). @refill Variables that have the same value on all nodes: @refill @itemize @item CONFBASE=/etc/gvpe @cindex CONFBASE The configuration base directory. @refill @item IFNAME=vpn0 @cindex IFNAME The network interface to initialize. @refill @item IFTYPE=native # or tincd @cindex IFTYPE @item IFSUBTYPE=linux # or freebsd, darwin etc.. @cindex IFSUBTYPE The interface type (@t{native} or @t{tincd}) and the subtype (usually the OS name in lowercase) that this GVPE was configured for. Can be used to select the correct syntax to use for network-related commands. @refill @item MTU=1436 @cindex MTU The MTU to set the interface to. You can use lower values (if done consistently on all nodes), but this is usually either inefficient or simply ineffective. @refill @item NODES=5 @cindex NODES The number of nodes in this GVPE network. @refill @end itemize Variables that are node-specific and with values pertaining to the node running this GVPE: @refill @itemize @item IFUPDATA=string @cindex IFUPDATA The value of the configuration directive @t{if-up-data}. @refill @item MAC=fe:fd:80:00:00:01 @cindex MAC The MAC address the network interface has to use. @refill Might be used to initialize interfaces on platforms where GVPE does not do this automatically. Please see the @t{gvpe.osdep(5)} man page for platform-specific information. @refill @item NODENAME=branch1 @cindex NODENAME The nickname of the node. @refill @item NODEID=1 @cindex NODEID The numerical node ID of the node running this instance of GVPE. The first node mentioned in the config file gets ID 1, the second ID 2 and so on. @refill @end itemize In addition, all node-specific variables (except @t{NODEID}) will be available with a postfix of @t{_nodeid}, which contains the value for that node, e.g. the @t{MAC_1} variable contains the MAC address of node #1, while the @t{NODENAME_22} variable contains the name of node #22. @refill Here is a simple if-up script: @refill @example #!/bin/sh ip link set $IFNAME up [ $NODENAME = branch1 ] && ip addr add 10.0.0.1 dev $IFNAME [ $NODENAME = branch2 ] && ip addr add 10.1.0.1 dev $IFNAME ip route add 10.0.0.0/8 dev $IFNAME @end example More complicated examples (using routing to reduce ARP traffic) can be found in the @file{etc/} subdirectory of the distribution. @refill @item ifname = devname @cindex ifname Sets the tun interface name to the given name. The default is OS-specific and most probably something like @t{tun0}. @refill @item ifpersist = yes|true|on | no|false|off @cindex ifpersist Should the tun/tap device be made persistent, that is, should the device stay up even when gvpe exits? Some versions of the tunnel device have problems sending packets when gvpe is restarted in persistent mode, so if the connections can be established but you cannot send packets from the local node, try to set this to @t{off} and do an ifconfig down on the device. @refill @item ip-proto = numerical-ip-protocol @cindex ip-proto Sets the protocol number to be used for the rawip protocol. This is a global option because all nodes must use the same protocol, and since there are no port numbers, you cannot easily run more than one gvpe instance using the same protocol, nor can you share the protocol with other programs. @refill The default is 47 (GRE), which has a good chance of tunneling through firewalls (but note that gvpe's rawip protocol is not GRE compatible). Other common choices are 50 (IPSEC, ESP), 51 (IPSEC, AH), 4 (IPIP tunnels) or 98 (ENCAP, rfc1241). @refill Many versions of Linux seem to have a bug that causes them to reorder packets for some ip protocols (GRE, ESP) but not for others (AH), so choose wisely (that is, use 51, AH). @refill @item http-proxy-host = hostname/ip @cindex http-proxy-host The @t{http-proxy-*} family of options are only available if gvpe was compiled with the @t{--enable-http-proxy} option and enable tunneling of tcp connections through a http proxy server. @refill @t{http-proxy-host} and @t{http-proxy-port} should specify the hostname and port number of the proxy server. See @t{http-proxy-loginpw} if your proxy requires authentication. @refill Please note that gvpe will still try to resolve all hostnames in the configuration file, so if you are behind a proxy without access to a DNS server better use numerical IP addresses. @refill To make best use of this option disable all protocols except TCP in your config file and make sure your routers (or all other nodes) are listening on a port that the proxy allows (443, https, is a common choice). @refill If you have a router, connecting to it will suffice. Otherwise TCP must be enabled on all nodes. @refill Example: @refill @example http-proxy-host = proxy.example.com http-proxy-port = 3128 # 8080 is another common choice http-proxy-auth = schmorp:grumbeere @end example @item http-proxy-port = proxy-tcp-port @cindex http-proxy-port The port where your proxy server listens. @refill @item http-proxy-auth = login:password @cindex http-proxy-auth The optional login and password used to authenticate to the proxy server, separated by a literal colon (@t{:}). Only basic authentication is currently supported. @refill @item keepalive = seconds @cindex keepalive Sets the keepalive probe interval in seconds (default: @t{60}). After this many seconds of inactivity the daemon will start to send keepalive probe every 3 seconds until it receives a reply from the other end. If no reply is received within 15 seconds, the peer is considered unreachable and the connection is closed. @refill @item loglevel = noise|trace|debug|info|notice|warn|error|critical @cindex loglevel Set the logging level. Connection established messages are logged at level @t{info}, notable errors are logged with @t{error}. Default is @t{info}. @refill @item mtu = bytes @cindex mtu Sets the maximum MTU that should be used on outgoing packets (basically the MTU of the outgoing interface) The daemon will automatically calculate maximum overhead (e.g. UDP header size, encryption blocksize...) and pass this information to the @t{if-up} script. @refill Recommended values are 1500 (ethernet), 1492 (pppoe), 1472 (pptp). @refill This value must be the minimum of the MTU values of all nodes. @refill @item nfmark = integer @cindex nfmark This advanced option, when set to a nonzero value (default: @t{0}), tries to set the netfilter mark (or fwmark) value on all sockets gvpe uses to send packets. @refill This can be used to make gvpe use a different set of routing rules. For example, on GNU/Linux, the @t{if-up} could set @t{nfmark} to 1000 and then put all routing rules into table @t{99} and then use an ip rule to make gvpe traffic avoid that routing table, in effect routing normal traffic via gvpe and gvpe traffic via the normal system routing tables: @refill @example ip rule add not fwmark 1000 lookup 99 @end example @item node-up = relative-or-absolute-path @cindex node-up Sets a command (default: none) that should be called whenever a connection is established (even on rekeying operations). Note that node-up/down scripts will be run asynchronously, but execution is serialised, so there will only ever be one such script running. @refill In addition to all the variables passed to @t{if-up} scripts, the following environment variables will be set (values are just examples): @refill @itemize @item DESTNODE=branch2 @cindex DESTNODE The name of the remote node. @refill @item DESTID=2 @cindex DESTID The node id of the remote node. @refill @item DESTSI=rawip/88.99.77.55:0 @cindex DESTSI The "socket info" of the target node, protocol dependent but usually in the format protocol/ip:port. @refill @item DESTIP=188.13.66.8 @cindex DESTIP The numerical IP address of the remote node (gvpe accepts connections from everywhere, as long as the other node can authenticate itself). @refill @item DESTPORT=655 # deprecated @cindex DESTPORT The protocol port used by the other side, if applicable. @refill @item STATE=up @cindex STATE Node-up scripts get called with STATE=up, node-change scripts get called with STATE=change and node-down scripts get called with STATE=down. @refill @end itemize Here is a nontrivial example that uses nsupdate to update the name => ip mapping in some DNS zone: @refill @example #!/bin/sh @{ echo update delete $DESTNODE.lowttl.example.net. a echo update add $DESTNODE.lowttl.example.net. 1 in a $DESTIP echo @} | nsupdate -d -k $CONFBASE:key.example.net. @end example @item node-change = relative-or-absolute-path @cindex node-change Same as @t{node-change}, but gets called whenever something about a connection changes (such as the source IP address). @refill @item node-down = relative-or-absolute-path @cindex node-down Same as @t{node-up}, but gets called whenever a connection is lost. @refill @item pid-file = path @cindex pid-file The path to the pid file to check and create (default: @t{LOCALSTATEDIR/run/gvpe.pid}). The first @t{%s} is replaced by the nodename - any other use of @t{%} must be written as @t{%%}. @refill @item private-key = relative-path-to-key @cindex private-key Sets the path (relative to the config directory) to the private key (default: @t{hostkey}). This is a printf format string so every @t{%} must be doubled. A single @t{%s} is replaced by the hostname, so you could use paths like @t{hostkeys/%s} to be able to share the same config directory between nodes. @refill Since only the private key file of the current node is used and the private key file should be kept secret per-node to avoid spoofing, it is not recommended to use this feature this way though. @refill @item rekey = seconds @cindex rekey Sets the rekeying interval in seconds (default: @t{3607}). Connections are reestablished every @t{rekey} seconds, making them use a new encryption key. @refill @item seed-device = path @cindex seed-device The random device used to initially and regularly seed the random number generator (default: @file{/dev/urandom}). Randomness is of paramount importance to the security of the algorithms used in gvpe. @refill On program start and every seed-interval, gvpe will read 64 octets. @refill Setting this path to the empty string will disable this functionality completely (the underlying crypto library will likely look for entropy sources on it's own though, so not all is lost). @refill @item seed-interval = seconds @cindex seed-interval The number of seconds between reseeds of the random number generator (default: @t{3613}). A value of @t{0} disables this regular reseeding. @refill @item serial = string @cindex serial The configuration serial number. This can be any string up to 16 bytes length. Only when the serial matches on both sides of a conenction will the connection succeed. This is @emph{not} a security mechanism and eay to spoof, this mechanism exists to alert users that their config is outdated. @refill It's recommended to specify this is a date string such as @t{2013-05-05} or @t{20121205084417}. @refill The exact algorithm is as this: if a connection request is received form a node with an identical serial, then it succeeds normally. @refill If the remote serial is lower than the local serial, it is ignored. @refill If the remote serial is higher than the local serial, a warning message is logged. @refill @end itemize @subsection NODE SPECIFIC SETTINGS The following settings are node-specific, that is, every node can have different settings, even within the same gvpe instance. Settings that are set before the first node section set the defaults, settings that are set within a node section only apply to the given node. @refill @itemize @item allow-direct = nodename @cindex allow-direct Allow direct connections to this node. See @t{deny-direct} for more info. @refill @item compress = yes|true|on | no|false|off @cindex compress For the current node, this specified whether it will accept compressed packets, and for all other nodes, this specifies whether to try to compress data packets sent to this node (default: @t{yes}). Compression is really cheap even on slow computers, has no size overhead at all and will only be used when the other side supports compression, so enabling this is often a good idea. @refill @item connect = ondemand | never | always | disabled @cindex connect Sets the connect mode (default: @t{always}). It can be @t{always} (always try to establish and keep a connection to the given node), @t{never} (never initiate a connection to the given host, but accept connections), @t{ondemand} (try to establish a connection when there are outstanding packets in the queue and take it down after the keepalive interval) or @t{disabled} (node is bad, don't talk to it). @refill Routers will automatically be forced to @t{always} unless they are @t{disabled}, to ensure all nodes can talk to each other. @refill @item deny-direct = nodename | * @cindex deny-direct Deny direct connections to the specified node (or all nodes when @t{*} is given). Only one node can be specified, but you can use multiple @t{allow-direct} and @t{deny-direct} statements. This only makes sense in networks with routers, as routers are required for indirect connections. @refill Sometimes, a node cannot reach some other nodes for reasons of network connectivity. For example, a node behind a firewall that only allows connections to/from a single other node in the network. In this case one should specify @t{deny-direct = *} and @t{allow-direct = othernodename} (the other node @emph{must} be a router for this to work). @refill The algorithm to check whether a connection may be direct is as follows: @refill 1. Other node mentioned in an @t{allow-direct}? If yes, allow the connection. @refill 2. Other node mentioned in a @t{deny-direct}? If yes, deny direct connections. @refill 3. Allow the connection. @refill That is, @t{allow-direct} takes precedence over @t{deny-direct}. @refill The check is done in both directions, i.e. both nodes must allow a direct connection before one is attempted, so you only need to specify connect limitations on one node. @refill @item dns-domain = domain-suffix @cindex dns-domain The DNS domain suffix that points to the DNS tunnel server for this node. @refill The domain must point to a NS record that points to the @emph{dns-hostname}, i.e. @refill @example dns-domainname = tunnel.example.net dns-hostname = tunnel-server.example.net @end example Corresponds to the following DNS entries in the @t{example.net} domain: @refill @example tunnel.example.net. NS tunnel-server.example.net. tunnel-server.example.net. A 13.13.13.13 @end example @item dns-hostname = hostname/ip @cindex dns-hostname The address to bind the DNS tunnel socket to, similar to the @t{hostname}, but for the DNS tunnel protocol only. Default: @t{0.0.0.0}, but that might change. @refill @item dns-port = port-number @cindex dns-port The port to bind the DNS tunnel socket to. Must be @t{53} on DNS tunnel servers. @refill @item enable-dns = yes|true|on | no|false|off @cindex enable-dns See gvpe.protocol(7) for a description of the DNS transport protocol. Avoid this protocol if you can. @refill Enable the DNS tunneling protocol on this node, either as server or as client. Support for this transport protocol is only available when gvpe was compiled using the @t{--enable-dns} option. @refill @item enable-icmp = yes|true|on | no|false|off @cindex enable-icmp See gvpe.protocol(7) for a description of the ICMP transport protocol. @refill Enable the ICMP transport using ICMP packets of type @t{icmp-type} on this node. @refill @item enable-rawip = yes|true|on | no|false|off @cindex enable-rawip See gvpe.protocol(7) for a description of the RAW IP transport protocol. @refill Enable the RAW IPv4 transport using the @t{ip-proto} protocol (default: @t{no}). @refill @item enable-tcp = yes|true|on | no|false|off @cindex enable-tcp See gvpe.protocol(7) for a description of the TCP transport protocol. @refill Enable the TCPv4 transport using the @t{tcp-port} port (default: @t{no}). Support for this transport protocol is only available when gvpe was compiled using the @t{--enable-tcp} option. @refill @item enable-udp = yes|true|on | no|false|off @cindex enable-udp See gvpe.protocol(7) for a description of the UDP transport protocol. @refill Enable the UDPv4 transport using the @t{udp-port} port (default: @t{no}). @refill @item hostname = hostname | ip [can not be defaulted] @cindex hostname Forces the address of this node to be set to the given DNS hostname or IP address. It will be resolved before each connect request, so dyndns should work fine. If this setting is not specified and a router is available, then the router will be queried for the address of this node. Otherwise, the connection attempt will fail. @refill Note that DNS resolving is done synchronously, pausing the daemon. If that is an issue you need to specify IP addresses. @refill @item icmp-type = integer @cindex icmp-type Sets the type value to be used for outgoing (and incoming) packets sent via the ICMP transport. @refill The default is @t{0} (which is @t{echo-reply}, also known as "ping-reply"). Other useful values include @t{8} (@t{echo-request}, a.k.a. "ping") and @t{11} (@t{time-exceeded}), but any 8-bit value can be used. @refill @item if-up-data = value @cindex if-up-data The value specified using this directive will be passed to the @t{if-up} script in the environment variable @t{IFUPDATA}. @refill @item inherit-tos = yes|true|on | no|false|off @cindex inherit-tos Whether to inherit the TOS settings of packets sent to the tunnel when sending packets to this node (default: @t{yes}). If set to @t{yes} then outgoing tunnel packets will have the same TOS setting as the packets sent to the tunnel device, which is usually what you want. @refill @item low-power = yes|true|on | no|false|off @cindex low-power If true, designates a node as a low-power node. Low-power nodes use larger timeouts and try to reduce cpu time. Other nodes talking to a low-power node will also use larger timeouts, and will use less aggressive optimisations, in the hope of reducing load. Security is not compromised. @refill The typical low-power node would be a mobile phone, where wakeups and encryption can significantly increase power drain. @refill @item max-retry = positive-number @cindex max-retry The maximum interval in seconds (default: @t{3600}, one hour) between retries to establish a connection to this node. When a connection cannot be established, gvpe uses exponential back-off capped at this value. It's sometimes useful to set this to a much lower value (e.g. @t{120}) on connections to routers that usually are stable but sometimes are down, to assure quick reconnections even after longer downtimes. @refill @item max-ttl = seconds @cindex max-ttl Expire packets that couldn't be sent after this many seconds (default: @t{60}). Gvpe will normally queue packets for a node without an active connection, in the hope of establishing a connection soon. This value specifies the maximum lifetime a packet will stay in the queue, if a packet gets older, it will be thrown away. @refill @item max-queue = positive-number>=1 @cindex max-queue The maximum number of packets that will be queued (default: @t{512}) for this node. If more packets are sent then earlier packets will be expired. See @t{max-ttl}, above. @refill @item router-priority = 0 | 1 | positive-number>=2 @cindex router-priority Sets the router priority of the given node (default: @t{0}, disabled). @refill If some node tries to connect to another node but it doesn't have a hostname, it asks a router node for it's IP address. The router node chosen is the one with the highest priority larger than @t{1} that is currently reachable. This is called a @emph{mediated} connection, as the connection itself will still be direct, but it uses another node to mediate between the two nodes. @refill The value @t{0} disables routing, that means if the node receives a packet not for itself it will not forward it but instead drop it. @refill The special value @t{1} allows other hosts to route through the router host, but they will never route through it by default (i.e. the config file of another node needs to specify a router priority higher than one to choose such a node for routing). @refill The idea behind this is that some hosts can, if required, bump the @t{router-priority} setting to higher than @t{1} in their local config to route through specific hosts. If @t{router-priority} is @t{0}, then routing will be refused, so @t{1} serves as a "enable, but do not use by default" switch. @refill Nodes with @t{router-priority} set to @t{2} or higher will always be forced to @t{connect} = @t{always} (unless they are @t{disabled}). @refill @item tcp-port = port-number @cindex tcp-port Similar to @t{udp-port} (default: @t{655}), but sets the TCP port number. @refill @item udp-port = port-number @cindex udp-port Sets the port number used by the UDP protocol (default: @t{655}, not officially assigned by IANA!). @refill @end itemize @section CONFIG DIRECTORY LAYOUT The default (or recommended) directory layout for the config directory is: @refill @itemize @item gvpe.conf The config file. @refill @item if-up The if-up script @refill @item node-up, node-down If used the node up or node-down scripts. @refill @item hostkey The (default path of the) private key of the current host. @refill @item pubkey/nodename The public keys of the other nodes, one file per node. @refill @end itemize @node gvpectrl,gvpe,gvpe.conf,Top @chapter gvpectrl @section NAME @t{gvpectrl} - GNU Virtual Private Ethernet Control Program @refill @section SYNOPSIS @t{gvpectrl} [@strong{-ckgs}] [@strong{--config=}@emph{DIR}] [@strong{--generate-keys}] [@strong{--help}] [@strong{--kill}[@strong{=}@emph{SIGNAL}]] [@strong{--show-config}] [@strong{--version}] @refill @section DESCRIPTION This is the control program for the @t{gvpe}, the virtual private ethernet daemon. @refill @section OPTIONS @itemize @item @strong{-c}, @strong{--config=}@emph{DIR} Read configuration options from @emph{DIR}. @refill @item @strong{-g}, @strong{--generate-key=path} Generates a single RSA key-pair. The public key will be stored in @file{@emph{path}} while the private key will be stored in @file{@emph{path} .privkey}. Neither file must be non-empty for this to succeed. @refill The public key file @file{@emph{path}} is normally copied to @file{pubkey/nodename} in the config directory on all nodes, while the private key @file{@emph{path}.privkey} should be copied to the file @file{hostkey} on the node the key is for. @refill It's recommended to generate the keypair on the node where it will be used, so that the private key file does not have to travel over the network. @refill @item @strong{-G}, @strong{--generate-keys} Generate public/private RSA key-pairs for all nodes not having a key and exit. @refill Note that in normal configurations this will fail, as there cna only be one private key per host. To make this configuration work you need to specify separate keyfiles for hostkeys in your config file, e.g.: @refill @example private-key = hostkeys/%s @end example Such a configuration makes it easier to distribute a configuration centrally but requires private keys to be transported securely over the network. @refill @item @strong{-q}, @strong{--quiet} Suppresses messages the author finds nonessential for scripting purposes. @refill @item @strong{--help} Display short list of options. @refill @item @strong{--kill}[@strong{=}@emph{SIGNAL}] Attempt to kill a running @t{gvpectrl} (optionally with the specified @emph{SIGNAL} instead of @t{SIGTERM}) and exit. @refill @item @strong{--show-config} Show a summary of the configuration, and how gvpe interprets it. Can also be very useful when designing firewall scripts. @refill @item @strong{--version} Output version information and exit. @refill @end itemize @section BUGS If you find any bugs, report them to @t{gvpe@@schmorp.de}. @refill @node gvpe,gvpe.protocol,gvpectrl,Top @chapter gvpe @section NAME @t{gvpe} - GNU Virtual Private Ethernet Daemon @refill @section SYNOPSIS @t{gvpe} [@strong{-cDlL}] [@strong{--config=}@emph{DIR}] [@strong{--no-detach}] [@strong{-l=}@emph{LEVEL]}] [@strong{--kill}[@strong{=}@emph{SIGNAL}]] [@strong{--mlock}] [@strong{--help}] [@strong{--version}] @emph{NODENAME} [@emph{option...}] @refill @section DESCRIPTION See the gvpe(5) man page for an introduction to the gvpe suite. @refill This is the manual page for gvpe, the virtual private ethernet daemon. When started, @t{gvpe} will read it's configuration file to determine the network topology, and other configuration information, assuming the role of node @emph{NODENAME} @refill It will then create/connect to the tun/tap device and set up a socket for incoming connections. Then a @t{if-up} script will be executed to further configure the virtual network device. If that succeeds, it will detach from the controlling terminal and continue in the background, accepting and setting up connections to other gvpe daemons that are part of the same virtual private ethernet. @refill The optional arguments after the node name have to be of the form: @refill @example [I.]var=value @end example If the argument has a prefix of @t{nodename.} (i.e. @t{laptop.enable-dns=yes}) then it will be parsed after all the config directives for that node, if not, it is parsed before the first node directive in the config file, and can be used to set global options or default variables. @refill For example, to start @t{gvpe} in the foreground, with log-level @t{info} on the node @t{laptop}, with TCP enabled and HTTP-Proxy host and Port set, use this: @refill @example gvpe -D -l info laptop \ http-proxy-host=10.0.0.18 http-proxy-port=3128 \ laptop.enable-tcp=yes @end example @section OPTIONS @itemize @item @strong{-c}, @strong{--config=}@emph{DIR} Read configuration options from @emph{DIR} @refill @item @strong{-d}, @strong{--l=}@emph{LEVEL} Set logging level to @emph{LEVEL} (one of: noise, trace, debug, info, notice, warn, error, critical). @refill @item @strong{--help} Display short list of options. @refill @item @strong{-D}, @strong{--no-detach} Don't fork and detach but stay in foreground and log messages to stderr in addition to syslog. @refill @item @strong{-L}, @strong{--mlock} Lock @t{gvpe} into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. @refill @item @strong{--version} Output version information and exit. @refill @end itemize @section SIGNALS @itemize @item HUP Closes/resets all connections, resets the retry time and will start connecting again (it will NOT re-read the config file). This is useful e.g. in a @t{/etc/ppp/if-up} script. @refill @item TERM Closes/resets all connections and exits. @refill @item USR1 Dump current network status into the syslog (at loglevel @t{notice}, so make sure your loglevel allows this). @refill @end itemize @section FILES @itemize @item @t{/etc/gvpe/gvpe.conf} The configuration file for @t{gvpe}. @refill @item @t{/etc/gvpe/if-up} Script which is executed as soon as the virtual network device has been allocated. Purpose is to further configure that device. @refill @item @t{/etc/gvpe/node-up} Script which is executed whenever a node connects to this node. This can be used for example to run nsupdate. @refill @item @t{/etc/gvpe/node-down} Script which is executed whenever a connection to another node is lost. for example to run nsupdate. @refill @item @t{/etc/gvpe/pubkey/*} The directory containing the public keys for every node, one file per node with the name of the node. @refill @item @t{/etc/gvpe/hostkey} The file containing the private key of the node GVPE runs on. Unlike all the other files in the @file{/etc/gvpe} directory, this file usually differes for each node that GVPE runs on. @refill @item @t{/var/run/gvpe.pid} The PID of the currently running @t{gvpe} is stored in this file. @refill @end itemize @section BUGS The cryptography in gvpe has not been thoroughly checked by many people yet. Use it at your own risk! @refill If you find any bugs, report them to @t{gvpe@@schmorp.de}. @refill @node gvpe.protocol,Simple Example,gvpe,Top @chapter gvpe.protocol @section The GNU-VPE Protocols @section Overview GVPE can make use of a number of protocols. One of them is the GNU VPE protocol which is used to authenticate tunnels and send encrypted data packets. This protocol is described in more detail the second part of this document. @refill The first part of this document describes the transport protocols which are used by GVPE to send its data packets over the network. @refill @section PART 1: Transport protocols GVPE offers a wide range of transport protocols that can be used to interchange data between nodes. Protocols differ in their overhead, speed, reliability, and robustness. @refill The following sections describe each transport protocol in more detail. They are sorted by overhead/efficiency, the most efficient transport is listed first: @refill @subsection RAW IP This protocol is the best choice, performance-wise, as the minimum overhead per packet is only 38 bytes. @refill It works by sending the VPN payload using raw IP frames (using the protocol set by @t{ip-proto}). @refill Using raw IP frames has the drawback that many firewalls block "unknown" protocols, so this transport only works if you have full IP connectivity between nodes. @refill @subsection ICMP This protocol offers very low overhead (minimum 42 bytes), and can sometimes tunnel through firewalls when other protocols can not. @refill It works by prepending an ICMP header with type @t{icmp-type} and a code of @t{255}. The default @t{icmp-type} is @t{echo-reply}, so the resulting packets look like echo replies, which looks rather strange to network administrators. @refill This transport should only be used if other transports (i.e. raw IP) are not available or undesirable (due to their overhead). @refill @subsection UDP This is a good general choice for the transport protocol as UDP packets tunnel well through most firewalls and routers, and the overhead per packet is moderate (minimum 58 bytes). @refill It should be used if RAW IP is not available. @refill @subsection TCP This protocol is a very bad choice, as it not only has high overhead (more than 60 bytes), but the transport also retries on its own, which leads to congestion when the link has moderate packet loss (as both the TCP transport and the tunneled traffic will retry, increasing congestion more and more). It also has high latency and is quite inefficient. @refill It's only useful when tunneling through firewalls that block better protocols. If a node doesn't have direct internet access but a HTTP proxy that supports the CONNECT method it can be used to tunnel through a web proxy. For this to work, the @t{tcp-port} should be @t{443} (@t{https}), as most proxies do not allow connections to other ports. @refill It is an abuse of the usage a proxy was designed for, so make sure you are allowed to use it for GVPE. @refill This protocol also has server and client sides. If the @t{tcp-port} is set to zero, other nodes cannot connect to this node directly. If the @t{tcp-port} is non-zero, the node can act both as a client as well as a server. @refill @subsection DNS @strong{WARNING:} Parsing and generating DNS packets is rather tricky. The code almost certainly contains buffer overflows and other, likely exploitable, bugs. You have been warned. @refill This is the worst choice of transport protocol with respect to overhead (overhead can be 2-3 times higher than the transferred data), and latency (which can be many seconds). Some DNS servers might not be prepared to handle the traffic and drop or corrupt packets. The client also has to constantly poll the server for data, so the client will constantly create traffic even if it doesn't need to transport packets. @refill In addition, the same problems as the TCP transport also plague this protocol. @refill Its only use is to tunnel through firewalls that do not allow direct internet access. Similar to using a HTTP proxy (as the TCP transport does), it uses a local DNS server/forwarder (given by the @t{dns-forw-host} configuration value) as a proxy to send and receive data as a client, and an @t{NS} record pointing to the GVPE server (as given by the @t{dns-hostname} directive). @refill The only good side of this protocol is that it can tunnel through most firewalls mostly undetected, iff the local DNS server/forwarder is sane (which is true for most routers, wireless LAN gateways and nameservers). @refill Fine-tuning needs to be done by editing @t{src/vpn_dns.C} directly. @refill @section PART 2: The GNU VPE protocol This section, unfortunately, is not yet finished, although the protocol is stable (until bugs in the cryptography are found, which will likely completely change the following description). Nevertheless, it should give you some overview over the protocol. @refill @subsection Anatomy of a VPN packet The exact layout and field lengths of a VPN packet is determined at compile time and doesn't change. The same structure is used for all transport protocols, be it RAWIP or TCP. @refill @example +------+------+--------+------+ | HMAC | TYPE | SRCDST | DATA | +------+------+--------+------+ @end example The HMAC field is present in all packets, even if not used (e.g. in auth request packets), in which case it is set to all zeroes. The MAC itself is calculated over the TYPE, SRCDST and DATA fields in all cases. @refill The TYPE field is a single byte and determines the purpose of the packet (e.g. RESET, COMPRESSED/UNCOMPRESSED DATA, PING, AUTH REQUEST/RESPONSE, CONNECT REQUEST/INFO etc.). @refill SRCDST is a three byte field which contains the source and destination node IDs (12 bits each). @refill The DATA portion differs between each packet type, naturally, and is the only part that can be encrypted. Data packets contain more fields, as shown: @refill @example +------+------+--------+-------+------+ | HMAC | TYPE | SRCDST | SEQNO | DATA | +------+------+--------+-------+------+ @end example SEQNO is a 32-bit sequence number. It is negotiated at every connection initialization and starts at some random 31 bit value. GVPE currently uses a sliding window of 512 packets/sequence numbers to detect reordering, duplication and replay attacks. @refill The encryption is done on SEQNO+DATA in CTR mode with IV generated from the seqno (for AES: seqno || seqno || seqno || (u32)0), which ensures uniqueness for a given key. @refill @subsection The authentication/key exchange protocol Before nodes can exchange packets, they need to establish authenticity of the other side and a key. Every node has a private RSA key and the public RSA keys of all other nodes. @refill When a node wants to establish a connection to another node, it sends an RSA-OEAP-encrypted challenge and an ECDH (curve25519) key. The other node replies with its own ECDH key and a HKDF of the challenge and both ECDH keys to prove its identity. @refill The remote node enganges in exactly the same protocol. When both nodes have exchanged their challenge and verified the response, they calculate a cipher key and a HMAC key and start exchanging data packets. @refill In detail, the challenge consist of: @refill @example RSA-OAEP (SEQNO MAC CIPHER SALT EXTRA-AUTH) ECDH1 @end example That is, it encrypts (with the public key of the remote node) an initial sequence number for data packets, key material for the HMAC key, key material for the cipher key, a salt used by the HKDF (as shown later) and some extra random bytes that are unused except for authentication. It also sends the public key of a curve25519 exchange. @refill The remote node decrypts the RSA data, generates its own ECDH key (ECDH2), and replies with: @refill @example HKDF-Expand (HKDF-Extract (ECDH2, RSA), ECDH1, AUTH_DIGEST_SIZE) ECDH2 @end example That is, it extracts from the decrypted RSA challenge, using its ECDH key as salt, and then expands using the requesting node's ECDH1 key. The resulting hash is returned as a proof that the node could decrypt the RSA challenge data, together with the ECDH key. @refill After both nodes have done this to each other, they calculate the shared ECDH secret, cipher and HMAC keys for the session (each node generates two cipher and HMAC keys, one for sending and one for receiving). @refill The HMAC key for sending is generated as follow: @refill @example HMAC_KEY = HKDF-Expand (HKDF-Extract (REMOTE_SALT, MAC ECDH_SECRET), info, HMAC_MD_SIZE) @end example It extracts from MAC and ECDH_SECRET using the @emph{remote} SALT, then expands using a static info string. @refill The cipher key is generated in the same way, except using the CIPHER part of the original challenge. @refill The result of this process is to authenticate each node to the other node, while exchanging keys using both RSA and ECDH, the latter providing perfect forward secrecy. @refill The protocol has been overdesigned where this was possible without increasing implementation complexity, in an attempt to protect against implementation or protocol failures. For example, if the ECDH challenge was found to be flawed, perfect forward secrecy would be lost, but the data would likely still be protected. Likewise, standard algorithms and implementations are used where possible. @refill @subsection Retrying When there is no response to an auth request, the node will send auth requests in bursts with an exponential back-off. After some time it will resort to PING packets, which are very small (8 bytes + protocol header) and lightweight (no RSA operations required). A node that receives ping requests from an unconnected peer will respond by trying to create a connection. @refill In addition to the exponential back-off, there is a global rate-limit on a per-IP base. It allows long bursts but will limit total packet rate to something like one control packet every ten seconds, to avoid accidental floods due to protocol problems (like a RSA key file mismatch between two nodes). @refill The intervals between retries are limited by the @t{max-retry} configuration value. A node with @t{connect} = @t{always} will always retry, a node with @t{connect} = @t{ondemand} will only try (and re-try) to connect as long as there are packets in the queue, usually this limits the retry period to @t{max-ttl} seconds. @refill Sending packets over the VPN will reset the retry intervals as well, which means as long as somebody is trying to send packets to a given node, GVPE will try to connect every few seconds. @refill @subsection Routing and Protocol translation The GVPE routing algorithm is easy: there isn't much routing to speak of: When routing packets to another node, GVPE tries the following options, in order: @refill @itemize @item If the two nodes should be able to reach each other directly (common protocol, port known), then GVPE will send the packet directly to the other node. @item If this isn't possible (e.g. because the node doesn't have a @t{hostname} or known port), but the nodes speak a common protocol and a router is available, then GVPE will ask a router to "mediate" between both nodes (see below). @item If a direct connection isn't possible (no common protocols) or forbidden (@t{deny-direct}) and there are any routers, then GVPE will try to send packets to the router with the highest priority that is connected already @emph{and} is able (as specified by the config file) to connect directly to the target node. @item If no such router exists, then GVPE will simply send the packet to the node with the highest priority available. @item Failing all that, the packet will be dropped. @end itemize A host can usually declare itself unreachable directly by setting its port number(s) to zero. It can declare other hosts as unreachable by using a config-file that disables all protocols for these other hosts. Another option is to disable all protocols on that host in the other config files. @refill If two hosts cannot connect to each other because their IP address(es) are not known (such as dial-up hosts), one side will send a @emph{mediated} connection request to a router (routers must be configured to act as routers!), which will send both the originating and the destination host a connection info request with protocol information and IP address of the other host (if known). Both hosts will then try to establish a direct connection to the other peer, which is usually possible even when both hosts are behind a NAT gateway. @refill Routing via other nodes works because the SRCDST field is not encrypted, so the router can just forward the packet to the destination host. Since each host uses its own private key, the router will not be able to decrypt or encrypt packets, it will just act as a simple router and protocol translator. @refill @node Simple Example,Complex Example,gvpe.protocol,Top @chapter Simple Example In this example, gvpe is used to implement a simple, UDP-based ethernet on three hosts. @refill The config file (@t{gvpe.conf}) is the same on all hosts: @refill @example enable-udp = yes # use UDP udp-port = 407 # use this UDP port mtu = 1492 # handy for TDSL ifname = vpn0 # I prefer vpn0 over e.g. tap0 node = huffy # arbitrary node name hostname = 1.2.3.4 # ip address if this host node = welshy hostname = www.example.net # resolve at connection time node = wheelery # no hostname, will be determinded dynamically using router1 or router2 @end example @t{gvpe} will execute the @t{if-up} script on every hosts, which, for linux, could look like this for all three hosts: @refill @example ifconfig $IFNAME hw ether $MAC mtu $MTU ifconfig $IFNAME 10.0.0.$NODE route add -net 10.0.0.0 netmask 255.0.0.0 dev $IFNAME @end example The @t{10.0.0.$NODE} resolves to @t{10.0.0.1} on @t{huffy}, @t{10.0.0.2} on @t{welshy} and so on. Other schemes, such as @t{10.$NODE.0.1} might be useful, too. @refill After generating the keys (gvpectrl) and starting the daemon (@t{gvpe -D -l info }@emph{NODENAME} for test purposes) the three hosts should be able to ping each other. @refill If you have an internal @t{10.x.x.x} network (with a tighter netmask then @t{255.0.0.0}, e.g. @t{10.1.0.0} on @t{huffy}, @t{10.2.0.0} on @t{welshy} and so on), you can now enable ip-forwarding and proxy-arp (or set the hosts as default gateway), and your three hosts should forward traffic from each network to each other. @refill @node Complex Example,complex/gvpe.conf,Simple Example,Top @chapter Complex Example These files are configuration files for "our" internal network. It is highly non-trivial, so don't use this configuration as the basis of your network unless you know what you are doing. It features: around 30 hosts, many of them have additional networks behind them and use an assortment of different tunneling protocols. The vpn is fully routed, no arp is used at all. The public IP addresses of connecting nodes are automatically registered via dns on the node ruth, using a node-up/node-down script. And last not least: the if-up script can generate information to be used in firewall rules (IP-net/MAC-address pairs) so ensure packet integrity so you can use your iptables etc. firewall to filter by IP address only. @menu * complex/gvpe.conf:: An example gvpe configuration * complex/if-up:: A fully-routing if-up config * complex/node-up:: A node-up/node-down script utilizing dynds @end menu @node complex/gvpe.conf,complex/if-up,Complex Example,Complex Example @chapter complex/gvpe.conf @example # sample configfile # the config file must be exactly(!) the same on all nodes rekey = 54321 # the rekeying interval keepalive = 300 # the keepalive interval on ruth keepalive = 120 # ruth is important and demands lower keepalives on surfer keepalive = 40 mtu = 1492 # the mtu (minimum mtu of attached host) ifname = vpn0 # the tunnel interface name to use ifpersist = no # the tun device should be persistent inherit-tos = yes # should tunnel packets inherit tos flags? compress = yes # wether compression should be used (NYI) connect = ondemand # connect to this host always/never or ondemand router-priority = 1 # route for everybody - if necessary loglevel = notice # info logs connects, notice only important messages on mobil loglevel = info on doom loglevel = info on ruth loglevel = info udp-port = 407 # the udp port to use for sending/receiving packets tcp-port = 443 # the tcp port to listen for connections (we use https over proxy) ip-proto = 50 # (ab)use the ipsec protocol as rawip icmp-type = 0 # (ab)use echo replies for tunneling enable-udp = yes # udp is spoken almost everywhere enable-tcp = no # tcp is not spoken everywhere enable-rawip = no # rawip is not spoken everywhere enable-icmp = no # most hosts don't bother to icmp # every "node =" introduces a new node in the network # the options following it don't set defaults but are # node-specific. # marc@@lap node = mobil # marc@@home node = doom enable-rawip = yes enable-tcp = yes # marc@@uni node = ruth enable-rawip = yes enable-tcp = yes enable-icmp = yes hostname = 200.100.162.95 connect = always router-priority = 30 on ruth node-up = node-up on ruth node-down = node-up # marc@@mu node = frank enable-rawip = yes hostname = 44.88.167.250 router-priority = 20 connect = always # nethype node = rain enable-rawip = yes hostname = 145.253.105.130 router-priority = 10 connect = always # marco@@home node = marco enable-rawip = yes # stefan@@ka node = wappla connect = never # stefan@@lap node = stefan udp-port = 408 connect = never # paul@@wg node = n8geil on ruth enable-icmp = yes on n8geil enable-icmp = yes enable-udp = no # paul@@lap node = syrr # paul@@lu node = donomos # marco@@hn node = core # elmex@@home node = elmex enable-rawip = yes hostname = 100.251.143.181 # stefan@@kwc.at node = fwkw connect = never on stefan connect = always on wappla connect = always hostname = 182.73.81.146 # elmex@@home node = jungfrau enable-rawip = yes # uni main router node = surfer enable-rawip = yes enable-tcp = no enable-icmp = yes hostname = 200.100.162.79 connect = always router-priority = 40 # jkneer@@marvin node = marvin enable-rawip = yes enable-udp = no # jkneer@@entrophy node = entrophy enable-udp = no enable-tcp = yes # mr. primitive node = voyager enable-udp = no enable-tcp = no on voyager enable-tcp = yes on voyager enable-udp = yes # v-server (barbados.dn-systems.de) #node = vserver #enable-udp = yes #hostname = 193.108.181.74 @end example @node complex/if-up,complex/node-up,complex/gvpe.conf,Complex Example @chapter complex/if-up @example #!/bin/bash # Some environment variables will be set: # # CONFBASE=/etc/vpe # the configuration directory prefix # IFNAME=vpn0 # the network interface (ifname) # MAC=fe:fd:80:00:00:01 # the mac-address to use for the interface # NODENAME=cerebro # the selected nodename (-n switch) # NODEID=1 # the numerical node id # MTU=1436 # the tunnel packet overhead (set mtu to 1500-$OVERHEAD) # this if-up script is rather full-featured, and is used to # generate a fully-routed (no arp traffic) vpn. the main portion # consists of "ipn" calls (see below). # some hosts require additional specific configuration, this is handled # using if statements near the end of the script. # with the --fw switch, outputs mac/net pairs for your firewall use: # if-up --fw | while read mac net; do # iptables -t filter -A INPUT -i vpn0 -p all -m mac --mac-source \! $mac -s $net -j DROP # done ipn() @{ local id="$1"; shift local mac=fe:fd:80:00:00:$(printf "%02x" $id) if [ -n "$FW" ]; then for net in "$@@"; do echo "$mac $net" done else local ip="$1"; shift if [ "$id" == $NODEID ]; then [ -n "$ADDR_ONLY" ] && ip addr add $ip broadcast 10.255.255.255 dev $IFNAME elif [ -z "$ADDR_ONLY" ]; then ip neighbour add $ip lladdr $mac nud permanent dev $IFNAME for route in "$@@"; do ip route add $route via $ip dev vpn0 done fi fi @} ipns() @{ # this contains the generic routing information for the vpn # each call to ipn has the following parameters: # ipn [ ...] # the second line (ipn 2) means: # the second node (doom in the config file) has the ip address 10.0.0.5, # which is the gateway for the 10.0/28 network and three additional ip # addresses ipn 1 10.0.0.20 ipn 2 10.0.0.5 10.0.0.0/28 #200.100.162.92 200.100.162.93 100.99.218.222 ipn 3 10.0.0.17 ipn 4 10.0.0.18 ipn 5 10.0.0.19 10.3.0.0/16 ipn 6 10.0.0.21 10.0.2.0/26 #200.100.162.17 ipn 7 10.0.0.22 10.1.2.0/24 # wappla, off ipn 8 10.0.0.23 # stefan, off ipn 9 10.0.0.24 10.13.0.0/16 ipn 10 10.0.0.25 ipn 11 10.0.0.26 ipn 12 10.0.0.27 10.0.2.64/26 ipn 13 10.0.0.28 10.0.3.0/24 ipn 14 10.0.0.29 10.1.1.0/24 # fwkw, off # mind the gateway ip gap ipn 15 10.9.0.30 10.0.4.0/24 ipn 16 10.9.0.31 ipn 17 10.9.0.32 10.42.0.0/16 ipn 18 10.9.0.33 ipn 19 10.9.0.34 #ipn 20 10.9.0.35 @} if [ "$1" == "--fw" ]; then FW=1 ipns else exec >/var/log/vpe.if-up 2>&1 set -x [ $NODENAME = "ruth" ] && ip link set $IFNAME down # hack # first set the link up and initialize the interface ip # address. ip link set $IFNAME address $MAC ip link set $IFNAME mtu $MTU up ADDR_ONLY=1 ipns # set addr only # now initialize the main vpn routes (10.0/8) # the second route is a hack to to reach some funnily-connected # machines. ip route add 10.0.0.0/8 dev $IFNAME ip route add 10.0.0.0/27 dev $IFNAME ipns # set the interface routes # now for something completely different, ehr, something not # easily doable with ipn, namely some extra specific highly complicated # and non-regular setups for some machines. if [ $NODENAME = doom ]; then ip addr add 200.100.162.92 dev $IFNAME ip route add 200.100.0.0/16 via 10.0.0.17 dev $IFNAME ip route flush table 101 ip route add table 101 default src 200.100.162.92 via 10.0.0.17 dev $IFNAME ip addr add 100.99.218.222 dev $IFNAME ip route add 100.99.218.192/27 via 10.0.0.19 dev $IFNAME ip route flush table 103 ip route add table 103 default src 100.99.218.222 via 10.0.0.19 elif [ $NODENAME = marco ]; then ip addr add 200.100.162.17 dev $IFNAME for addr in 79 89 90 91 92 93 94 95; do ip route add 200.100.162.$addr dev ppp0 done ip route add 200.100.76.0/23 dev ppp0 ip route add src 200.100.162.17 200.100.0.0/16 via 10.0.0.17 dev $IFNAME elif [ $NODENAME = ruth ]; then ip route add 200.100.162.17 via 10.0.0.21 dev vpn0 ip route add 200.100.162.92 via 10.0.0.5 dev vpn0 ip route add 200.100.162.93 via 10.0.0.5 dev vpn0 fi # and this is the second part of the 10.0/27 hack. don't ask. [ $NODENAME != fwkw ] && ip route add 10.0.0.0/24 via 10.0.0.29 dev $IFNAME fi @end example @node complex/node-up,Index,complex/if-up,Complex Example @chapter complex/node-up @example #!/bin/sh # Some environment variables will be set (in addition the ones # set in if-up, too): # # DESTNODE=doom # others nodename # DESTID=5 # others node id # DESTIP=188.13.66.8 # others ip # DESTPORT=407 # others port # STATE=up/down # node-up gets UP, node-down script gets DOWN if [ $STATE = up ]; then @{ echo update delete $DESTNODE.lowttl.example.com. a echo update delete $DESTNODE-last.lowttl.example.com. a echo update add $DESTNODE.lowttl.example.com. 1 in a $DESTIP echo update add $DESTNODE-last.lowttl.example.com. 1 in a $DESTIP echo @} | nsupdate -d -k $CONFBASE:marc.example.net. else @{ echo update delete $DESTNODE.lowttl.example.com. a echo update delete $DESTNODE-last.lowttl.example.com. a echo update add $DESTNODE-last.lowttl.example.com. 1 in a $DESTIP echo @} | nsupdate -d -k $CONFBASE:marc.example.net. fi @end example @node Index,,complex/node-up,Top @chapter Index @printindex cp @bye gvpe-3.0/doc/gvpe.50000644000000000000000000003757113006307537011021 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPE 5" .TH GVPE 5 "2016-11-02" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" GNU\-VPE \- Overview of the GNU Virtual Private Ethernet suite. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\s-1GVPE\s0 is a suite designed to provide a virtual private network for multiple nodes over an untrusted network. This document first gives an introduction to VPNs in general and then describes the specific implementation of \s-1GVPE.\s0 .SS "\s-1WHAT IS A VPN\s0?" .IX Subsection "WHAT IS A VPN?" \&\s-1VPN\s0 is an acronym, it stands for: .IP "Virtual" 4 .IX Item "Virtual" Virtual means that no physical network is created (of course), but a network is \fIemulated\fR by creating multiple tunnels between the member nodes by encapsulating and sending data over another transport network. .Sp Usually the emulated network is a normal \s-1IP\s0 or Ethernet, and the transport network is the Internet. However, using a \s-1VPN\s0 system like \s-1GVPE\s0 to connect nodes over other untrusted networks such as Wireless \s-1LAN\s0 is not uncommon. .IP "Private" 4 .IX Item "Private" Private means that non-participating nodes cannot decode (\*(L"sniff)\*(R" nor inject (\*(L"spoof\*(R") packets. This means that nodes can be connected over untrusted networks such as the public Internet without fear of being eavesdropped while at the same time being able to trust data sent by other nodes. .Sp In the case of \s-1GVPE,\s0 even participating nodes cannot sniff packets send to other nodes or spoof packets as if sent from other nodes, so communications between any two nodes is private to those two nodes. .IP "Network" 4 .IX Item "Network" Network means that more than two parties can participate in the network, so for instance it's possible to connect multiple branches of a company into a single network. Many so-called \*(L"\s-1VPN\*(R"\s0 solutions only create point-to-point tunnels, which in turn can be used to build larger networks. .Sp \&\s-1GVPE\s0 provides a true multi-point network in which any number of nodes (at least a few dozen in practise, the theoretical limit is 4095 nodes) can participate. .SS "\s-1GVPE DESIGN GOALS\s0" .IX Subsection "GVPE DESIGN GOALS" .IP "\s-1SIMPLE DESIGN\s0" 4 .IX Item "SIMPLE DESIGN" Cipher, \s-1HMAC\s0 algorithms and other key parameters must be selected at compile time \- this makes it possible to only link in algorithms you actually need. It also makes the crypto part of the source very transparent and easy to inspect, and last not least this makes it possible to hardcode the layout of all packets into the binary. \s-1GVPE\s0 goes a step further and internally reserves blocks of the same length for all packets, which virtually removes all possibilities of buffer overflows, as there is only a single type of buffer and it's always of fixed length. .IP "\s-1EASY TO SETUP\s0" 4 .IX Item "EASY TO SETUP" A few lines of config (the config file is shared unmodified between all hosts) and generating an \s-1RSA\s0 key-pair on each node suffices to make it work. .IP "MAC-BASED \s-1SECURITY\s0" 4 .IX Item "MAC-BASED SECURITY" Since every host has it's own private key, other hosts cannot spoof traffic from this host. That makes it possible to filter packet by \s-1MAC\s0 address, e.g. to ensure that packets from a specific \s-1IP\s0 address come, in fact, from a specific host that is associated with that \s-1IP\s0 and not from another host. .SH "PROGRAMS" .IX Header "PROGRAMS" Gvpe comes with two programs: one daemon (\f(CW\*(C`gvpe\*(C'\fR) and one control program (\f(CW\*(C`gvpectrl\*(C'\fR). .IP "gvpectrl" 4 .IX Item "gvpectrl" This program is used to generate the keys, check and give an overview of of the configuration and to control the daemon (restarting etc.). .IP "gvpe" 4 .IX Item "gvpe" This is the daemon used to establish and maintain connections to the other network nodes. It should be run on the gateway of each \s-1VPN\s0 subnet. .SH "COMPILETIME CONFIGURATION" .IX Header "COMPILETIME CONFIGURATION" Please have a look at the \f(CW\*(C`gvpe.osdep(5)\*(C'\fR manpage for platform-specific information. .PP Gvpe hardcodes most encryption parameters. While this reduces flexibility, it makes the program much simpler and helps making buffer overflows impossible under most circumstances. .PP Here are a few recipes for compiling your gvpe, showing the extremes (fast, small, insecure \s-1OR\s0 slow, large, more secure), between which you should choose: .SS "\s-1AS LOW PACKET OVERHEAD AS POSSIBLE\s0" .IX Subsection "AS LOW PACKET OVERHEAD AS POSSIBLE" .Vb 1 \& ./configure \-\-enable\-hmac\-length=4 \-\-enable\-rand\-length=0 .Ve .PP Minimize the header overhead of \s-1VPN\s0 packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a \s-1HMAC\s0 length of 4 makes collision attacks almost trivial. .SS "\s-1MINIMIZE CPU TIME REQUIRED\s0" .IX Subsection "MINIMIZE CPU TIME REQUIRED" .Vb 1 \& ./configure \-\-enable\-cipher=bf \-\-enable\-digest=md4 .Ve .PP Use the fastest cipher and digest algorithms currently available in gvpe. \s-1MD4\s0 has been broken and is quite insecure, though, so using another digest algorithm is recommended. .SS "\s-1MAXIMIZE SECURITY\s0" .IX Subsection "MAXIMIZE SECURITY" .Vb 1 \& ./configure \-\-enable\-hmac\-length=16 \-\-enable\-rand\-length=12 \-\-enable\-digest=ripemd610 .Ve .PP This uses a 16 byte \s-1HMAC\s0 checksum to authenticate packets (I guess 8\-12 would also be pretty secure ;) and will additionally prefix each packet with 12 bytes of random data. .PP In general, remember that \s-1AES\-128\s0 seems to be as secure but faster than \&\s-1AES\-192\s0 or \s-1AES\-256,\s0 more randomness helps against sniffing and a longer \&\s-1HMAC\s0 helps against spoofing. \s-1MD4\s0 is a fast digest, \s-1SHA1, RIPEMD160, SHA256\s0 are consecutively better, and Blowfish is a fast cipher (and also quite secure). .SH "HOW TO SET UP A SIMPLE VPN" .IX Header "HOW TO SET UP A SIMPLE VPN" In this section I will describe how to get a simple \s-1VPN\s0 consisting of three hosts up and running. .SS "\s-1STEP 1:\s0 configuration" .IX Subsection "STEP 1: configuration" First you have to create a daemon configuration file and put it into the configuration directory. This is usually \f(CW\*(C`/etc/gvpe\*(C'\fR, depending on how you configured gvpe, and can be overwritten using the \f(CW\*(C`\-c\*(C'\fR command line switch. .PP Put the following lines into \f(CW\*(C`/etc/gvpe/gvpe.conf\*(C'\fR: .PP .Vb 3 \& udp\-port = 50000 # the external port to listen on (configure your firewall) \& mtu = 1400 # minimum MTU of all outgoing interfaces on all hosts \& ifname = vpn0 # the local network device name \& \& node = first # just a nickname \& hostname = first.example.net # the DNS name or IP address of the host \& \& node = second \& hostname = 133.55.82.9 \& \& node = third \& hostname = third.example.net .Ve .PP The only other file necessary is the \f(CW\*(C`if\-up\*(C'\fR script that initializes the virtual ethernet interface on the local host. Put the following lines into \&\f(CW\*(C`/etc/gvpe/if\-up\*(C'\fR and make it executable (\f(CW\*(C`chmod 755 /etc/gvpe/if\-up\*(C'\fR): .PP .Vb 6 \& #!/bin/sh \& ip link set $IFNAME address $MAC mtu $MTU up \& [ $NODENAME = first ] && ip addr add 10.0.1.1 dev $IFNAME \& [ $NODENAME = second ] && ip addr add 10.0.2.1 dev $IFNAME \& [ $NODENAME = third ] && ip addr add 10.0.3.1 dev $IFNAME \& ip route add 10.0.0.0/16 dev $IFNAME .Ve .PP This script will give each node a different \s-1IP\s0 address in the \f(CW\*(C`10.0/16\*(C'\fR network. The internal network (if gvpe runs on a router) should then be set to a subset of that network, e.g. \f(CW\*(C`10.0.1.0/24\*(C'\fR on node \f(CW\*(C`first\*(C'\fR, \&\f(CW\*(C`10.0.2.0/24\*(C'\fR on node \f(CW\*(C`second\*(C'\fR, and so on. .PP By enabling routing on the gateway host that runs \f(CW\*(C`gvpe\*(C'\fR all nodes will be able to reach the other nodes. You can, of course, also use proxy \s-1ARP\s0 or other means of pseudo-bridging, or (best) full routing \- the choice is yours. .SS "\s-1STEP 2:\s0 create the \s-1RSA\s0 key pair for each node" .IX Subsection "STEP 2: create the RSA key pair for each node" Next you have to generate the \s-1RSA\s0 keys for the nodes. While you can set up \s-1GVPE\s0 so you can generate all keys on a single host and centrally distribute all keys, it is safer to generate the key for each node on the node, so that the secret/private key does not have to be copied over the network. .PP To do so, run the following command to generate a key pair: .PP .Vb 1 \& gvpectrl \-c /etc/gvpe \-g nodekey .Ve .PP This will create two files, \fInodekey\fR and \fInodekey.privkey\fR. The former should be copied to \fI/etc/gvpe/pubkey/\fInodename\fI\fR on the host where your config file is (you will have to create the \fIpubkey\fR directory first): .PP .Vb 1 \& scp nodekey confighost:/etc/gvpe/pubkey/nodename .Ve .PP The private key \fInodekey.privkey\fR should be moved to \fI/etc/gvpe/hostkey\fR: .PP .Vb 2 \& mkdir \-p /etc/gvpe \& mv nodekey.privkey /etc/gvpe/hostkey .Ve .SS "\s-1STEP 3:\s0 distribute the config files to all nodes" .IX Subsection "STEP 3: distribute the config files to all nodes" Now distribute the config files and public keys to the other nodes. .PP The example uses rsync-over-ssh to copy the config file and all the public keys: .PP .Vb 3 \& rsync \-avzessh /etc/gvpe first.example.net:/etc/. \-\-exclude hostkey \& rsync \-avzessh /etc/gvpe 133.55.82.9:/etc/. \-\-exclude hostkey \& rsync \-avzessh /etc/gvpe third.example.net:/etc/. \-\-exclude hostkey .Ve .PP You should now check the configuration by issuing the command \f(CW\*(C`gvpectrl \&\-c /etc/gvpe \-s\*(C'\fR on each node and verify it's output. .SS "\s-1STEP 4:\s0 starting gvpe" .IX Subsection "STEP 4: starting gvpe" You should then start gvpe on each node by issuing a command like: .PP .Vb 1 \& gvpe \-D \-l info first # first is the nodename .Ve .PP This will make the gvpe daemon stay in foreground. You should then see \&\*(L"connection established\*(R" messages. If you don't see them check your firewall and routing (use tcpdump ;). .PP If this works you should check your networking setup by pinging various endpoints. .PP To make gvpe run more permanently you can either run it as a daemon (by starting it without the \f(CW\*(C`\-D\*(C'\fR switch), or, much better, from your inittab or equivalent. I use a line like this on all my systems: .PP .Vb 1 \& t1:2345:respawn:/opt/gvpe/sbin/gvpe \-D \-L first >/dev/null 2>&1 .Ve .SS "\s-1STEP 5:\s0 enjoy" .IX Subsection "STEP 5: enjoy" \&... and play around. Sending a \-HUP (\f(CW\*(C`gvpectrl \-kHUP\*(C'\fR) to the daemon will make it try to connect to all other nodes again. If you run it from inittab \f(CW\*(C`gvpectrl \-k\*(C'\fR (or simply \f(CW\*(C`killall gvpe\*(C'\fR) will kill the daemon, start it again, making it read it's configuration files again. .PP To run the \s-1GVPE\s0 daemon permanently from your SysV init, you can add it to your \fIinittab\fR, e.g.: .PP .Vb 1 \& t1:2345:respawn:/bin/sh \-c "exec nice \-n\-20 /path/to/gvpe \-D node >/var/log/gvpe.log 2>&1" .Ve .PP For systems using systemd, you can use a unit file similar to this one: .PP .Vb 4 \& [Unit] \& Description=gvpe \& After=network.target \& Before=remote\-fs.target \& \& [Service] \& ExecStart=/path/to/gvpe \-D node \& KillMode=process \& Restart=always \& \& [Install] \& WantedBy=multi\-user.target .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIgvpe.osdep\fR\|(5) for OS-dependent information, \fIgvpe.conf\fR\|(5), \fIgvpectrl\fR\|(8), and for a description of the transports, protocol, and routing algorithm, \&\fIgvpe.protocol\fR\|(7). .PP The \s-1GVPE\s0 mailing list, at , or \&\f(CW\*(C`gvpe@lists.schmorp.de\*(C'\fR. .SH "AUTHOR" .IX Header "AUTHOR" Marc Lehmann .SH "COPYRIGHTS AND LICENSES" .IX Header "COPYRIGHTS AND LICENSES" \&\s-1GVPE\s0 itself is distributed under the \s-1GENERAL PUBLIC LICENSE \s0(see the file \&\s-1COPYING\s0 that should be part of your distribution). .PP In some configurations it uses modified versions of the tinc vpn suite, which is also available under the \s-1GENERAL PUBLIC LICENSE.\s0 gvpe-3.0/doc/gvpe.80000644000000000000000000002315613006307537011016 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPE 8" .TH GVPE 8 "2016-11-02" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" "gvpe" \- GNU Virtual Private Ethernet Daemon .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\f(CW\*(C`gvpe\*(C'\fR [\fB\-cDlL\fR] [\fB\-\-config=\fR\fI\s-1DIR\s0\fR] [\fB\-\-no\-detach\fR] [\fB\-l=\fR\fI\s-1LEVEL\s0]\fR] [\fB\-\-kill\fR[\fB=\fR\fI\s-1SIGNAL\s0\fR]] [\fB\-\-mlock\fR] [\fB\-\-help\fR] [\fB\-\-version\fR] \&\fI\s-1NODENAME\s0\fR [\fIoption...\fR] .SH "DESCRIPTION" .IX Header "DESCRIPTION" See the \fIgvpe\fR\|(5) man page for an introduction to the gvpe suite. .PP This is the manual page for gvpe, the virtual private ethernet daemon. When started, \f(CW\*(C`gvpe\*(C'\fR will read it's configuration file to determine the network topology, and other configuration information, assuming the role of node \fI\s-1NODENAME\s0\fR .PP It will then create/connect to the tun/tap device and set up a socket for incoming connections. Then a \f(CW\*(C`if\-up\*(C'\fR script will be executed to further configure the virtual network device. If that succeeds, it will detach from the controlling terminal and continue in the background, accepting and setting up connections to other gvpe daemons that are part of the same virtual private ethernet. .PP The optional arguments after the node name have to be of the form: .PP .Vb 1 \& [I.]var=value .Ve .PP If the argument has a prefix of \f(CW\*(C`nodename.\*(C'\fR (i.e. \f(CW\*(C`laptop.enable\-dns=yes\*(C'\fR) then it will be parsed after all the config directives for that node, if not, it is parsed before the first node directive in the config file, and can be used to set global options or default variables. .PP For example, to start \f(CW\*(C`gvpe\*(C'\fR in the foreground, with log-level \f(CW\*(C`info\*(C'\fR on the node \f(CW\*(C`laptop\*(C'\fR, with \s-1TCP\s0 enabled and HTTP-Proxy host and Port set, use this: .PP .Vb 3 \& gvpe \-D \-l info laptop \e \& http\-proxy\-host=10.0.0.18 http\-proxy\-port=3128 \e \& laptop.enable\-tcp=yes .Ve .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-c\fR, \fB\-\-config=\fR\fI\s-1DIR\s0\fR" 4 .IX Item "-c, --config=DIR" Read configuration options from \fI\s-1DIR\s0\fR .IP "\fB\-d\fR, \fB\-\-l=\fR\fI\s-1LEVEL\s0\fR" 4 .IX Item "-d, --l=LEVEL" Set logging level to \fI\s-1LEVEL\s0\fR (one of: noise, trace, debug, info, notice, warn, error, critical). .IP "\fB\-\-help\fR" 4 .IX Item "--help" Display short list of options. .IP "\fB\-D\fR, \fB\-\-no\-detach\fR" 4 .IX Item "-D, --no-detach" Don't fork and detach but stay in foreground and log messages to stderr in addition to syslog. .IP "\fB\-L\fR, \fB\-\-mlock\fR" 4 .IX Item "-L, --mlock" Lock \f(CW\*(C`gvpe\*(C'\fR into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. .IP "\fB\-\-version\fR" 4 .IX Item "--version" Output version information and exit. .SH "SIGNALS" .IX Header "SIGNALS" .IP "\s-1HUP\s0" 4 .IX Item "HUP" Closes/resets all connections, resets the retry time and will start connecting again (it will \s-1NOT\s0 re-read the config file). This is useful e.g. in a \&\f(CW\*(C`/etc/ppp/if\-up\*(C'\fR script. .IP "\s-1TERM\s0" 4 .IX Item "TERM" Closes/resets all connections and exits. .IP "\s-1USR1\s0" 4 .IX Item "USR1" Dump current network status into the syslog (at loglevel \f(CW\*(C`notice\*(C'\fR, so make sure your loglevel allows this). .SH "FILES" .IX Header "FILES" .ie n .IP "\*(C`/etc/gvpe/gvpe.conf\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/gvpe.conf\*(C'\fR" 4 .IX Item "/etc/gvpe/gvpe.conf" The configuration file for \f(CW\*(C`gvpe\*(C'\fR. .ie n .IP "\*(C`/etc/gvpe/if\-up\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/if\-up\*(C'\fR" 4 .IX Item "/etc/gvpe/if-up" Script which is executed as soon as the virtual network device has been allocated. Purpose is to further configure that device. .ie n .IP "\*(C`/etc/gvpe/node\-up\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/node\-up\*(C'\fR" 4 .IX Item "/etc/gvpe/node-up" Script which is executed whenever a node connects to this node. This can be used for example to run nsupdate. .ie n .IP "\*(C`/etc/gvpe/node\-down\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/node\-down\*(C'\fR" 4 .IX Item "/etc/gvpe/node-down" Script which is executed whenever a connection to another node is lost. for example to run nsupdate. .ie n .IP "\*(C`/etc/gvpe/pubkey/*\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/pubkey/*\*(C'\fR" 4 .IX Item "/etc/gvpe/pubkey/*" The directory containing the public keys for every node, one file per node with the name of the node. .ie n .IP "\*(C`/etc/gvpe/hostkey\*(C'" 4 .el .IP "\f(CW\*(C`/etc/gvpe/hostkey\*(C'\fR" 4 .IX Item "/etc/gvpe/hostkey" The file containing the private key of the node \s-1GVPE\s0 runs on. Unlike all the other files in the \fI/etc/gvpe\fR directory, this file usually differes for each node that \s-1GVPE\s0 runs on. .ie n .IP "\*(C`/var/run/gvpe.pid\*(C'" 4 .el .IP "\f(CW\*(C`/var/run/gvpe.pid\*(C'\fR" 4 .IX Item "/var/run/gvpe.pid" The \s-1PID\s0 of the currently running \f(CW\*(C`gvpe\*(C'\fR is stored in this file. .SH "BUGS" .IX Header "BUGS" The cryptography in gvpe has not been thoroughly checked by many people yet. Use it at your own risk! .PP If you find any bugs, report them to \f(CW\*(C`gvpe@schmorp.de\*(C'\fR. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIgvpe\fR\|(5) for an introduction, \fIgvpe.conf\fR\|(5), \fIgvpectrl\fR\|(8). .PP The \s-1GVPE\s0 mailing list, at or \&\f(CW\*(C`gvpe@lists.schmorp.de\*(C'\fR. .PP \&\s-1GVPE\s0 comes with \s-1ABSOLUTELY NO WARRANTY. \s0 This is free software, and you are welcome to redistribute it under certain conditions; see the file \s-1COPYING\s0 for details. .SH "AUTHOR" .IX Header "AUTHOR" Marc Lehmann \f(CW\*(C`\*(C'\fR. .PP And thanks to many others for their contributions to gvpe, especially the tincd authors, who inspired me to write this program (after scavenging their source code ;). gvpe-3.0/doc/gvpectrl.80000644000000000000000000001557113006307537011705 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPECTRL 8" .TH GVPECTRL 8 "2016-11-02" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" "gvpectrl" \- GNU Virtual Private Ethernet Control Program .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\f(CW\*(C`gvpectrl\*(C'\fR [\fB\-ckgs\fR] [\fB\-\-config=\fR\fI\s-1DIR\s0\fR] [\fB\-\-generate\-keys\fR] [\fB\-\-help\fR] [\fB\-\-kill\fR[\fB=\fR\fI\s-1SIGNAL\s0\fR]] [\fB\-\-show\-config\fR] [\fB\-\-version\fR] .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is the control program for the \f(CW\*(C`gvpe\*(C'\fR, the virtual private ethernet daemon. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-c\fR, \fB\-\-config=\fR\fI\s-1DIR\s0\fR" 4 .IX Item "-c, --config=DIR" Read configuration options from \fI\s-1DIR\s0\fR. .IP "\fB\-g\fR, \fB\-\-generate\-key=path\fR" 4 .IX Item "-g, --generate-key=path" Generates a single \s-1RSA\s0 key-pair. The public key will be stored in \fI\fIpath\fI\fR while the private key will be stored in \fI\fIpath\fI .privkey\fR. Neither file must be non-empty for this to succeed. .Sp The public key file \fI\fIpath\fI\fR is normally copied to \fIpubkey/nodename\fR in the config directory on all nodes, while the private key \fI\fIpath\fI.privkey\fR should be copied to the file \fIhostkey\fR on the node the key is for. .Sp It's recommended to generate the keypair on the node where it will be used, so that the private key file does not have to travel over the network. .IP "\fB\-G\fR, \fB\-\-generate\-keys\fR" 4 .IX Item "-G, --generate-keys" Generate public/private \s-1RSA\s0 key-pairs for all nodes not having a key and exit. .Sp Note that in normal configurations this will fail, as there cna only be one private key per host. To make this configuration work you need to specify separate keyfiles for hostkeys in your config file, e.g.: .Sp .Vb 1 \& private\-key = hostkeys/%s .Ve .Sp Such a configuration makes it easier to distribute a configuration centrally but requires private keys to be transported securely over the network. .IP "\fB\-q\fR, \fB\-\-quiet\fR" 4 .IX Item "-q, --quiet" Suppresses messages the author finds nonessential for scripting purposes. .IP "\fB\-\-help\fR" 4 .IX Item "--help" Display short list of options. .IP "\fB\-\-kill\fR[\fB=\fR\fI\s-1SIGNAL\s0\fR]" 4 .IX Item "--kill[=SIGNAL]" Attempt to kill a running \f(CW\*(C`gvpectrl\*(C'\fR (optionally with the specified \&\fI\s-1SIGNAL\s0\fR instead of \f(CW\*(C`SIGTERM\*(C'\fR) and exit. .IP "\fB\-\-show\-config\fR" 4 .IX Item "--show-config" Show a summary of the configuration, and how gvpe interprets it. Can also be very useful when designing firewall scripts. .IP "\fB\-\-version\fR" 4 .IX Item "--version" Output version information and exit. .SH "BUGS" .IX Header "BUGS" If you find any bugs, report them to \f(CW\*(C`gvpe@schmorp.de\*(C'\fR. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIgvpe\fR\|(5), \fIgvpe.conf\fR\|(5), \fIgvpe\fR\|(8). .PP \&\s-1GVPE\s0 comes with \s-1ABSOLUTELY NO WARRANTY. \s0 This is free software, and you are welcome to redistribute it under certain conditions; see the file \s-1COPYING\s0 for details. .SH "AUTHOR" .IX Header "AUTHOR" Marc Lehmann \f(CW\*(C`\*(C'\fR. gvpe-3.0/doc/gvpe.conf.50000644000000000000000000011143413006307537011734 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPE.CONF 5" .TH GVPE.CONF 5 "2016-11-02" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" gvpe.conf \- configuration file for the GNU VPE daemon .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& # global options for all nodes \& udp\-port = 407 \& mtu = 1492 \& ifname = vpn0 \& \& # first node is named branch1 and is at 1.2.3.4 \& node = branch1 \& hostname = 1.2.3.4 \& \& # second node uses dns to resolve the address \& node = branch2 \& hostname = www.example.net \& udp\-port = 500 # this host uses a different udp\-port \& \& # third node has no fixed ip address \& node = branch3 \& connect = ondemand .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The gvpe config file consists of a series of lines that contain \f(CW\*(C`variable = value\*(C'\fR pairs. Empty lines are ignored. Comments start with a \f(CW\*(C`#\*(C'\fR and extend to the end of the line. They can be used on their own lines, or after any directives. Whitespace is allowed around the \f(CW\*(C`=\*(C'\fR sign or after values, but not within the variable names or values themselves. .PP All settings are applied \*(L"in order\*(R", that is, later settings of the same variable overwrite earlier ones. .PP The only exceptions to the above are the following directives: .IP "node nodename" 4 .IX Item "node nodename" Introduces a node section. The nodename is used to select the right configuration section and is the same string as is passed as an argument to the gvpe daemon. .Sp Multiple \f(CW\*(C`node\*(C'\fR statements with the same node name are supported and will be merged together. .IP "global" 4 .IX Item "global" This statement switches back to the global section, which is mainly useful if you want to include a second config file, e..g for local customisations. To do that, simply include this at the very end of your config file: .Sp .Vb 2 \& global \& include local.conf .Ve .IP "on nodename ..." 4 .IX Item "on nodename ..." .PD 0 .IP "on !nodename ..." 4 .IX Item "on !nodename ..." .PD You can prefix any configuration directive with \f(CW\*(C`on\*(C'\fR and a nodename. \s-1GVPE\s0 will will only \*(L"execute\*(R" it on the named node, or (if the nodename starts with \f(CW\*(C`!\*(C'\fR) on all nodes except the named one. .Sp Example: set the \s-1MTU\s0 to \f(CW1450\fR everywhere, \f(CW\*(C`loglevel\*(C'\fR to \f(CW\*(C`noise\*(C'\fR on \&\f(CW\*(C`branch1\*(C'\fR, and \f(CW\*(C`connect\*(C'\fR to \f(CW\*(C`ondemand\*(C'\fR everywhere but on branch2. .Sp .Vb 3 \& mtu = 1450 \& on branch1 loglevel = noise \& on !branch2 connect = ondemand .Ve .IP "include relative-or-absolute-path" 4 .IX Item "include relative-or-absolute-path" Reads the specified file (the path must not contain whitespace or \f(CW\*(C`=\*(C'\fR characters) and evaluate all config directives in it as if they were spelled out in place of the \f(CW\*(C`include\*(C'\fR directive. .Sp The path is a printf format string, that is, you must escape any \f(CW\*(C`%\*(C'\fR by doubling it, and you can have a single \f(CW%s\fR inside, which will be replaced by the current nodename. .Sp Relative paths are interpreted relative to the \s-1GVPE\s0 config directory. .Sp Example: include the file \fIlocal.conf\fR in the config directory on every node. .Sp .Vb 1 \& include local.conf .Ve .Sp Example: include a file \fIconf/\fRnodename\fI.conf\fR .Sp .Vb 1 \& include conf/%s.conf .Ve .SH "ANATOMY OF A CONFIG FILE" .IX Header "ANATOMY OF A CONFIG FILE" Usually, a config file starts with a few global settings (like the \s-1UDP\s0 port to listen on), followed by node-specific sections that begin with a \&\f(CW\*(C`node = nickname\*(C'\fR line. .PP Every node that is part of the network must have a section that starts with \f(CW\*(C`node = nickname\*(C'\fR. The number and order of the nodes is important and must be the same on all nodes. It is not uncommon for node sections to be completely empty \- if the default values are right. .PP Node-specific settings can be used at any time. If used before the first node section they will set the default values for all following nodes. .SH "CONFIG VARIABLES" .IX Header "CONFIG VARIABLES" .SS "\s-1GLOBAL SETTINGS\s0" .IX Subsection "GLOBAL SETTINGS" Global settings will affect the behaviour of the running gvpe daemon, that is, they are in some sense node-specific (config files can set different values on different nodes using \f(CW\*(C`on\*(C'\fR), but will affect the behaviour of the gvpe daemon and all connections it creates. .IP "chroot = path or /" 4 .IX Item "chroot = path or /" Tells \s-1GVPE\s0 to \fIchroot\fR\|(2) to the specified path after reading all necessary files, binding to sockets and running the \f(CW\*(C`if\-up\*(C'\fR script, but before running \f(CW\*(C`node\-up\*(C'\fR or any other scripts. .Sp The special path \fI/\fR instructs \s-1GVPE\s0 to create (and remove) an empty temporary directory to use as new root. This is most secure, but makes it impossible to use any scripts other than the \f(CW\*(C`if\-up\*(C'\fR one. .IP "chuid = numerical-uid" 4 .IX Item "chuid = numerical-uid" .PD 0 .IP "chgid = numerical-gid" 4 .IX Item "chgid = numerical-gid" .PD These two options tell \s-1GVPE\s0 to change to the given user and/or group id after reading all necessary files, binding to sockets and running the \&\f(CW\*(C`if\-up\*(C'\fR script. .Sp Other scripts, such as \f(CW\*(C`node\-up\*(C'\fR, are run with the new user id or group id. .IP "chuser = username" 4 .IX Item "chuser = username" Alternative to \f(CW\*(C`chuid\*(C'\fR and \f(CW\*(C`chgid\*(C'\fR: Sets both \f(CW\*(C`chuid\*(C'\fR and \f(CW\*(C`chgid\*(C'\fR to the user and (primary) group ids of the specified user (for example, \&\f(CW\*(C`nobody\*(C'\fR). .IP "dns-forw-host = hostname/ip" 4 .IX Item "dns-forw-host = hostname/ip" The \s-1DNS\s0 server to forward \s-1DNS\s0 requests to for the \s-1DNS\s0 tunnel protocol (default: \f(CW127.0.0.1\fR, changing it is highly recommended). .IP "dns-forw-port = port-number" 4 .IX Item "dns-forw-port = port-number" The port where the \f(CW\*(C`dns\-forw\-host\*(C'\fR is to be contacted (default: \f(CW53\fR, which is fine in most cases). .IP "dns-case-preserving = yes|true|on | no|false|off" 4 .IX Item "dns-case-preserving = yes|true|on | no|false|off" Sets whether the \s-1DNS\s0 transport forwarding server preserves case (\s-1DNS\s0 servers have to, but some access systems are even more broken than others) (default: true). .Sp Normally, when the forwarding server changes the case of domain names then \&\s-1GVPE\s0 will automatically set this to false. .IP "dns-max-outstanding = integer-number-of-requests" 4 .IX Item "dns-max-outstanding = integer-number-of-requests" The maximum number of outstanding \s-1DNS\s0 transport requests (default: \f(CW100\fR). \s-1GVPE\s0 will never issue more requests then the given limit without receiving replies. In heavily overloaded situations it might help to set this to a low number (e.g. \f(CW3\fR or even \f(CW1\fR) to limit the number of parallel requests. .Sp The default should be working \s-1OK\s0 for most links. .IP "dns-overlap-factor = float" 4 .IX Item "dns-overlap-factor = float" The \s-1DNS\s0 transport uses the minimum request latency (\fBmin_latency\fR) seen during a connection as it's timing base. This factor (default: \f(CW0.5\fR, must be > 0) is multiplied by \fBmin_latency\fR to get the maximum sending rate (= minimum send interval), i.e. a factor of \f(CW1\fR means that a new request might be generated every \fBmin_latency\fR seconds, which means on average there should only ever be one outstanding request. A factor of \&\f(CW0.5\fR means that \s-1GVPE\s0 will send requests twice as often as the minimum latency measured. .Sp For congested or picky \s-1DNS\s0 forwarders you could use a value nearer to or exceeding \f(CW1\fR. .Sp The default should be working \s-1OK\s0 for most links. .IP "dns-send-interval = send-interval-in-seconds" 4 .IX Item "dns-send-interval = send-interval-in-seconds" The minimum send interval (= maximum rate) that the \s-1DNS\s0 transport will use to send new \s-1DNS\s0 requests. \s-1GVPE\s0 will not exceed this rate even when the latency is very low. The default is \f(CW0.01\fR, which means \s-1GVPE\s0 will not send more than 100 \s-1DNS\s0 requests per connection per second. For high-bandwidth links you could go lower, e.g. to \f(CW0.001\fR or so. For congested or rate-limited links, you might want to go higher, say \f(CW0.1\fR, \&\f(CW0.2\fR or even higher. .Sp The default should be working \s-1OK\s0 for most links. .IP "dns-timeout-factor = float" 4 .IX Item "dns-timeout-factor = float" Factor to multiply the \f(CW\*(C`min_latency\*(C'\fR (see \f(CW\*(C`dns\-overlap\-factor\*(C'\fR) by to get request timeouts. The default of \f(CW8\fR means that the \s-1DNS\s0 transport will resend the request when no reply has been received for longer than eight times the minimum (= expected) latency, assuming the request or reply has been lost. .Sp For congested links a higher value might be necessary (e.g. \f(CW30\fR). If the link is very stable lower values (e.g. \f(CW2\fR) might work nicely. Values near or below \f(CW1\fR makes no sense whatsoever. .Sp The default should be working \s-1OK\s0 for most links but will result in low throughput if packet loss is high. .IP "if-up = relative-or-absolute-path" 4 .IX Item "if-up = relative-or-absolute-path" Sets the path of a script that should be called immediately after the network interface is initialized (but not necessarily up). The following environment variables are passed to it (the values are just examples). .Sp Variables that have the same value on all nodes: .RS 4 .IP "CONFBASE=/etc/gvpe" 4 .IX Item "CONFBASE=/etc/gvpe" The configuration base directory. .IP "IFNAME=vpn0" 4 .IX Item "IFNAME=vpn0" The network interface to initialize. .IP "IFTYPE=native # or tincd" 4 .IX Item "IFTYPE=native # or tincd" .PD 0 .IP "IFSUBTYPE=linux # or freebsd, darwin etc.." 4 .IX Item "IFSUBTYPE=linux # or freebsd, darwin etc.." .PD The interface type (\f(CW\*(C`native\*(C'\fR or \f(CW\*(C`tincd\*(C'\fR) and the subtype (usually the \&\s-1OS\s0 name in lowercase) that this \s-1GVPE\s0 was configured for. Can be used to select the correct syntax to use for network-related commands. .IP "MTU=1436" 4 .IX Item "MTU=1436" The \s-1MTU\s0 to set the interface to. You can use lower values (if done consistently on all nodes), but this is usually either inefficient or simply ineffective. .IP "NODES=5" 4 .IX Item "NODES=5" The number of nodes in this \s-1GVPE\s0 network. .RE .RS 4 .Sp Variables that are node-specific and with values pertaining to the node running this \s-1GVPE:\s0 .IP "IFUPDATA=string" 4 .IX Item "IFUPDATA=string" The value of the configuration directive \f(CW\*(C`if\-up\-data\*(C'\fR. .IP "MAC=fe:fd:80:00:00:01" 4 .IX Item "MAC=fe:fd:80:00:00:01" The \s-1MAC\s0 address the network interface has to use. .Sp Might be used to initialize interfaces on platforms where \s-1GVPE\s0 does not do this automatically. Please see the \f(CW\*(C`gvpe.osdep(5)\*(C'\fR man page for platform-specific information. .IP "NODENAME=branch1" 4 .IX Item "NODENAME=branch1" The nickname of the node. .IP "NODEID=1" 4 .IX Item "NODEID=1" The numerical node \s-1ID\s0 of the node running this instance of \s-1GVPE.\s0 The first node mentioned in the config file gets \s-1ID 1,\s0 the second \s-1ID 2\s0 and so on. .RE .RS 4 .Sp In addition, all node-specific variables (except \f(CW\*(C`NODEID\*(C'\fR) will be available with a postfix of \f(CW\*(C`_nodeid\*(C'\fR, which contains the value for that node, e.g. the \f(CW\*(C`MAC_1\*(C'\fR variable contains the \s-1MAC\s0 address of node #1, while the \f(CW\*(C`NODENAME_22\*(C'\fR variable contains the name of node #22. .Sp Here is a simple if-up script: .Sp .Vb 5 \& #!/bin/sh \& ip link set $IFNAME up \& [ $NODENAME = branch1 ] && ip addr add 10.0.0.1 dev $IFNAME \& [ $NODENAME = branch2 ] && ip addr add 10.1.0.1 dev $IFNAME \& ip route add 10.0.0.0/8 dev $IFNAME .Ve .Sp More complicated examples (using routing to reduce \s-1ARP\s0 traffic) can be found in the \fIetc/\fR subdirectory of the distribution. .RE .IP "ifname = devname" 4 .IX Item "ifname = devname" Sets the tun interface name to the given name. The default is OS-specific and most probably something like \f(CW\*(C`tun0\*(C'\fR. .IP "ifpersist = yes|true|on | no|false|off" 4 .IX Item "ifpersist = yes|true|on | no|false|off" Should the tun/tap device be made persistent, that is, should the device stay up even when gvpe exits? Some versions of the tunnel device have problems sending packets when gvpe is restarted in persistent mode, so if the connections can be established but you cannot send packets from the local node, try to set this to \f(CW\*(C`off\*(C'\fR and do an ifconfig down on the device. .IP "ip-proto = numerical-ip-protocol" 4 .IX Item "ip-proto = numerical-ip-protocol" Sets the protocol number to be used for the rawip protocol. This is a global option because all nodes must use the same protocol, and since there are no port numbers, you cannot easily run more than one gvpe instance using the same protocol, nor can you share the protocol with other programs. .Sp The default is 47 (\s-1GRE\s0), which has a good chance of tunneling through firewalls (but note that gvpe's rawip protocol is not \s-1GRE\s0 compatible). Other common choices are 50 (\s-1IPSEC, ESP\s0), 51 (\s-1IPSEC, AH\s0), 4 (\s-1IPIP\s0 tunnels) or 98 (\s-1ENCAP,\s0 rfc1241). .Sp Many versions of Linux seem to have a bug that causes them to reorder packets for some ip protocols (\s-1GRE, ESP\s0) but not for others (\s-1AH\s0), so choose wisely (that is, use 51, \s-1AH\s0). .IP "http-proxy-host = hostname/ip" 4 .IX Item "http-proxy-host = hostname/ip" The \f(CW\*(C`http\-proxy\-*\*(C'\fR family of options are only available if gvpe was compiled with the \f(CW\*(C`\-\-enable\-http\-proxy\*(C'\fR option and enable tunneling of tcp connections through a http proxy server. .Sp \&\f(CW\*(C`http\-proxy\-host\*(C'\fR and \f(CW\*(C`http\-proxy\-port\*(C'\fR should specify the hostname and port number of the proxy server. See \f(CW\*(C`http\-proxy\-loginpw\*(C'\fR if your proxy requires authentication. .Sp Please note that gvpe will still try to resolve all hostnames in the configuration file, so if you are behind a proxy without access to a \s-1DNS\s0 server better use numerical \s-1IP\s0 addresses. .Sp To make best use of this option disable all protocols except \s-1TCP\s0 in your config file and make sure your routers (or all other nodes) are listening on a port that the proxy allows (443, https, is a common choice). .Sp If you have a router, connecting to it will suffice. Otherwise \s-1TCP\s0 must be enabled on all nodes. .Sp Example: .Sp .Vb 3 \& http\-proxy\-host = proxy.example.com \& http\-proxy\-port = 3128 # 8080 is another common choice \& http\-proxy\-auth = schmorp:grumbeere .Ve .IP "http-proxy-port = proxy-tcp-port" 4 .IX Item "http-proxy-port = proxy-tcp-port" The port where your proxy server listens. .IP "http-proxy-auth = login:password" 4 .IX Item "http-proxy-auth = login:password" The optional login and password used to authenticate to the proxy server, separated by a literal colon (\f(CW\*(C`:\*(C'\fR). Only basic authentication is currently supported. .IP "keepalive = seconds" 4 .IX Item "keepalive = seconds" Sets the keepalive probe interval in seconds (default: \f(CW60\fR). After this many seconds of inactivity the daemon will start to send keepalive probe every 3 seconds until it receives a reply from the other end. If no reply is received within 15 seconds, the peer is considered unreachable and the connection is closed. .IP "loglevel = noise|trace|debug|info|notice|warn|error|critical" 4 .IX Item "loglevel = noise|trace|debug|info|notice|warn|error|critical" Set the logging level. Connection established messages are logged at level \&\f(CW\*(C`info\*(C'\fR, notable errors are logged with \f(CW\*(C`error\*(C'\fR. Default is \f(CW\*(C`info\*(C'\fR. .IP "mtu = bytes" 4 .IX Item "mtu = bytes" Sets the maximum \s-1MTU\s0 that should be used on outgoing packets (basically the \s-1MTU\s0 of the outgoing interface) The daemon will automatically calculate maximum overhead (e.g. \s-1UDP\s0 header size, encryption blocksize...) and pass this information to the \f(CW\*(C`if\-up\*(C'\fR script. .Sp Recommended values are 1500 (ethernet), 1492 (pppoe), 1472 (pptp). .Sp This value must be the minimum of the \s-1MTU\s0 values of all nodes. .IP "nfmark = integer" 4 .IX Item "nfmark = integer" This advanced option, when set to a nonzero value (default: \f(CW0\fR), tries to set the netfilter mark (or fwmark) value on all sockets gvpe uses to send packets. .Sp This can be used to make gvpe use a different set of routing rules. For example, on GNU/Linux, the \f(CW\*(C`if\-up\*(C'\fR could set \f(CW\*(C`nfmark\*(C'\fR to 1000 and then put all routing rules into table \f(CW99\fR and then use an ip rule to make gvpe traffic avoid that routing table, in effect routing normal traffic via gvpe and gvpe traffic via the normal system routing tables: .Sp .Vb 1 \& ip rule add not fwmark 1000 lookup 99 .Ve .IP "node-up = relative-or-absolute-path" 4 .IX Item "node-up = relative-or-absolute-path" Sets a command (default: none) that should be called whenever a connection is established (even on rekeying operations). Note that node\-up/down scripts will be run asynchronously, but execution is serialised, so there will only ever be one such script running. .Sp In addition to all the variables passed to \f(CW\*(C`if\-up\*(C'\fR scripts, the following environment variables will be set (values are just examples): .RS 4 .IP "DESTNODE=branch2" 4 .IX Item "DESTNODE=branch2" The name of the remote node. .IP "DESTID=2" 4 .IX Item "DESTID=2" The node id of the remote node. .IP "DESTSI=rawip/88.99.77.55:0" 4 .IX Item "DESTSI=rawip/88.99.77.55:0" The \*(L"socket info\*(R" of the target node, protocol dependent but usually in the format protocol/ip:port. .IP "DESTIP=188.13.66.8" 4 .IX Item "DESTIP=188.13.66.8" The numerical \s-1IP\s0 address of the remote node (gvpe accepts connections from everywhere, as long as the other node can authenticate itself). .IP "DESTPORT=655 # deprecated" 4 .IX Item "DESTPORT=655 # deprecated" The protocol port used by the other side, if applicable. .IP "STATE=up" 4 .IX Item "STATE=up" Node-up scripts get called with STATE=up, node-change scripts get called with STATE=change and node-down scripts get called with STATE=down. .RE .RS 4 .Sp Here is a nontrivial example that uses nsupdate to update the name => ip mapping in some \s-1DNS\s0 zone: .Sp .Vb 6 \& #!/bin/sh \& { \& echo update delete $DESTNODE.lowttl.example.net. a \& echo update add $DESTNODE.lowttl.example.net. 1 in a $DESTIP \& echo \& } | nsupdate \-d \-k $CONFBASE:key.example.net. .Ve .RE .IP "node-change = relative-or-absolute-path" 4 .IX Item "node-change = relative-or-absolute-path" Same as \f(CW\*(C`node\-change\*(C'\fR, but gets called whenever something about a connection changes (such as the source \s-1IP\s0 address). .IP "node-down = relative-or-absolute-path" 4 .IX Item "node-down = relative-or-absolute-path" Same as \f(CW\*(C`node\-up\*(C'\fR, but gets called whenever a connection is lost. .IP "pid-file = path" 4 .IX Item "pid-file = path" The path to the pid file to check and create (default: \f(CW\*(C`LOCALSTATEDIR/run/gvpe.pid\*(C'\fR). The first \f(CW%s\fR is replaced by the nodename \- any other use of \f(CW\*(C`%\*(C'\fR must be written as \f(CW\*(C`%%\*(C'\fR. .IP "private-key = relative-path-to-key" 4 .IX Item "private-key = relative-path-to-key" Sets the path (relative to the config directory) to the private key (default: \f(CW\*(C`hostkey\*(C'\fR). This is a printf format string so every \f(CW\*(C`%\*(C'\fR must be doubled. A single \f(CW%s\fR is replaced by the hostname, so you could use paths like \f(CW\*(C`hostkeys/%s\*(C'\fR to be able to share the same config directory between nodes. .Sp Since only the private key file of the current node is used and the private key file should be kept secret per-node to avoid spoofing, it is not recommended to use this feature this way though. .IP "rekey = seconds" 4 .IX Item "rekey = seconds" Sets the rekeying interval in seconds (default: \f(CW3607\fR). Connections are reestablished every \f(CW\*(C`rekey\*(C'\fR seconds, making them use a new encryption key. .IP "seed-device = path" 4 .IX Item "seed-device = path" The random device used to initially and regularly seed the random number generator (default: \fI/dev/urandom\fR). Randomness is of paramount importance to the security of the algorithms used in gvpe. .Sp On program start and every seed-interval, gvpe will read 64 octets. .Sp Setting this path to the empty string will disable this functionality completely (the underlying crypto library will likely look for entropy sources on it's own though, so not all is lost). .IP "seed-interval = seconds" 4 .IX Item "seed-interval = seconds" The number of seconds between reseeds of the random number generator (default: \f(CW3613\fR). A value of \f(CW0\fR disables this regular reseeding. .IP "serial = string" 4 .IX Item "serial = string" The configuration serial number. This can be any string up to 16 bytes length. Only when the serial matches on both sides of a conenction will the connection succeed. This is \fInot\fR a security mechanism and eay to spoof, this mechanism exists to alert users that their config is outdated. .Sp It's recommended to specify this is a date string such as \f(CW\*(C`2013\-05\-05\*(C'\fR or \&\f(CW20121205084417\fR. .Sp The exact algorithm is as this: if a connection request is received form a node with an identical serial, then it succeeds normally. .Sp If the remote serial is lower than the local serial, it is ignored. .Sp If the remote serial is higher than the local serial, a warning message is logged. .SS "\s-1NODE SPECIFIC SETTINGS\s0" .IX Subsection "NODE SPECIFIC SETTINGS" The following settings are node-specific, that is, every node can have different settings, even within the same gvpe instance. Settings that are set before the first node section set the defaults, settings that are set within a node section only apply to the given node. .IP "allow-direct = nodename" 4 .IX Item "allow-direct = nodename" Allow direct connections to this node. See \f(CW\*(C`deny\-direct\*(C'\fR for more info. .IP "compress = yes|true|on | no|false|off" 4 .IX Item "compress = yes|true|on | no|false|off" For the current node, this specified whether it will accept compressed packets, and for all other nodes, this specifies whether to try to compress data packets sent to this node (default: \f(CW\*(C`yes\*(C'\fR). Compression is really cheap even on slow computers, has no size overhead at all and will only be used when the other side supports compression, so enabling this is often a good idea. .IP "connect = ondemand | never | always | disabled" 4 .IX Item "connect = ondemand | never | always | disabled" Sets the connect mode (default: \f(CW\*(C`always\*(C'\fR). It can be \f(CW\*(C`always\*(C'\fR (always try to establish and keep a connection to the given node), \f(CW\*(C`never\*(C'\fR (never initiate a connection to the given host, but accept connections), \&\f(CW\*(C`ondemand\*(C'\fR (try to establish a connection when there are outstanding packets in the queue and take it down after the keepalive interval) or \&\f(CW\*(C`disabled\*(C'\fR (node is bad, don't talk to it). .Sp Routers will automatically be forced to \f(CW\*(C`always\*(C'\fR unless they are \&\f(CW\*(C`disabled\*(C'\fR, to ensure all nodes can talk to each other. .IP "deny-direct = nodename | *" 4 .IX Item "deny-direct = nodename | *" Deny direct connections to the specified node (or all nodes when \f(CW\*(C`*\*(C'\fR is given). Only one node can be specified, but you can use multiple \&\f(CW\*(C`allow\-direct\*(C'\fR and \f(CW\*(C`deny\-direct\*(C'\fR statements. This only makes sense in networks with routers, as routers are required for indirect connections. .Sp Sometimes, a node cannot reach some other nodes for reasons of network connectivity. For example, a node behind a firewall that only allows connections to/from a single other node in the network. In this case one should specify \f(CW\*(C`deny\-direct = *\*(C'\fR and \f(CW\*(C`allow\-direct = othernodename\*(C'\fR (the other node \fImust\fR be a router for this to work). .Sp The algorithm to check whether a connection may be direct is as follows: .Sp 1. Other node mentioned in an \f(CW\*(C`allow\-direct\*(C'\fR? If yes, allow the connection. .Sp 2. Other node mentioned in a \f(CW\*(C`deny\-direct\*(C'\fR? If yes, deny direct connections. .Sp 3. Allow the connection. .Sp That is, \f(CW\*(C`allow\-direct\*(C'\fR takes precedence over \f(CW\*(C`deny\-direct\*(C'\fR. .Sp The check is done in both directions, i.e. both nodes must allow a direct connection before one is attempted, so you only need to specify connect limitations on one node. .IP "dns-domain = domain-suffix" 4 .IX Item "dns-domain = domain-suffix" The \s-1DNS\s0 domain suffix that points to the \s-1DNS\s0 tunnel server for this node. .Sp The domain must point to a \s-1NS\s0 record that points to the \fIdns-hostname\fR, i.e. .Sp .Vb 2 \& dns\-domainname = tunnel.example.net \& dns\-hostname = tunnel\-server.example.net .Ve .Sp Corresponds to the following \s-1DNS\s0 entries in the \f(CW\*(C`example.net\*(C'\fR domain: .Sp .Vb 2 \& tunnel.example.net. NS tunnel\-server.example.net. \& tunnel\-server.example.net. A 13.13.13.13 .Ve .IP "dns-hostname = hostname/ip" 4 .IX Item "dns-hostname = hostname/ip" The address to bind the \s-1DNS\s0 tunnel socket to, similar to the \f(CW\*(C`hostname\*(C'\fR, but for the \s-1DNS\s0 tunnel protocol only. Default: \f(CW0.0.0.0\fR, but that might change. .IP "dns-port = port-number" 4 .IX Item "dns-port = port-number" The port to bind the \s-1DNS\s0 tunnel socket to. Must be \f(CW53\fR on \s-1DNS\s0 tunnel servers. .IP "enable-dns = yes|true|on | no|false|off" 4 .IX Item "enable-dns = yes|true|on | no|false|off" See \fIgvpe.protocol\fR\|(7) for a description of the \s-1DNS\s0 transport protocol. Avoid this protocol if you can. .Sp Enable the \s-1DNS\s0 tunneling protocol on this node, either as server or as client. Support for this transport protocol is only available when gvpe was compiled using the \f(CW\*(C`\-\-enable\-dns\*(C'\fR option. .IP "enable-icmp = yes|true|on | no|false|off" 4 .IX Item "enable-icmp = yes|true|on | no|false|off" See \fIgvpe.protocol\fR\|(7) for a description of the \s-1ICMP\s0 transport protocol. .Sp Enable the \s-1ICMP\s0 transport using \s-1ICMP\s0 packets of type \f(CW\*(C`icmp\-type\*(C'\fR on this node. .IP "enable-rawip = yes|true|on | no|false|off" 4 .IX Item "enable-rawip = yes|true|on | no|false|off" See \fIgvpe.protocol\fR\|(7) for a description of the \s-1RAW IP\s0 transport protocol. .Sp Enable the \s-1RAW\s0 IPv4 transport using the \f(CW\*(C`ip\-proto\*(C'\fR protocol (default: \f(CW\*(C`no\*(C'\fR). .IP "enable-tcp = yes|true|on | no|false|off" 4 .IX Item "enable-tcp = yes|true|on | no|false|off" See \fIgvpe.protocol\fR\|(7) for a description of the \s-1TCP\s0 transport protocol. .Sp Enable the TCPv4 transport using the \f(CW\*(C`tcp\-port\*(C'\fR port (default: \f(CW\*(C`no\*(C'\fR). Support for this transport protocol is only available when gvpe was compiled using the \f(CW\*(C`\-\-enable\-tcp\*(C'\fR option. .IP "enable-udp = yes|true|on | no|false|off" 4 .IX Item "enable-udp = yes|true|on | no|false|off" See \fIgvpe.protocol\fR\|(7) for a description of the \s-1UDP\s0 transport protocol. .Sp Enable the UDPv4 transport using the \f(CW\*(C`udp\-port\*(C'\fR port (default: \f(CW\*(C`no\*(C'\fR). .IP "hostname = hostname | ip [can not be defaulted]" 4 .IX Item "hostname = hostname | ip [can not be defaulted]" Forces the address of this node to be set to the given \s-1DNS\s0 hostname or \s-1IP\s0 address. It will be resolved before each connect request, so dyndns should work fine. If this setting is not specified and a router is available, then the router will be queried for the address of this node. Otherwise, the connection attempt will fail. .Sp Note that \s-1DNS\s0 resolving is done synchronously, pausing the daemon. If that is an issue you need to specify \s-1IP\s0 addresses. .IP "icmp-type = integer" 4 .IX Item "icmp-type = integer" Sets the type value to be used for outgoing (and incoming) packets sent via the \s-1ICMP\s0 transport. .Sp The default is \f(CW0\fR (which is \f(CW\*(C`echo\-reply\*(C'\fR, also known as \&\*(L"ping-reply\*(R"). Other useful values include \f(CW8\fR (\f(CW\*(C`echo\-request\*(C'\fR, a.k.a. \&\*(L"ping\*(R") and \f(CW11\fR (\f(CW\*(C`time\-exceeded\*(C'\fR), but any 8\-bit value can be used. .IP "if-up-data = value" 4 .IX Item "if-up-data = value" The value specified using this directive will be passed to the \f(CW\*(C`if\-up\*(C'\fR script in the environment variable \f(CW\*(C`IFUPDATA\*(C'\fR. .IP "inherit-tos = yes|true|on | no|false|off" 4 .IX Item "inherit-tos = yes|true|on | no|false|off" Whether to inherit the \s-1TOS\s0 settings of packets sent to the tunnel when sending packets to this node (default: \f(CW\*(C`yes\*(C'\fR). If set to \f(CW\*(C`yes\*(C'\fR then outgoing tunnel packets will have the same \s-1TOS\s0 setting as the packets sent to the tunnel device, which is usually what you want. .IP "low-power = yes|true|on | no|false|off" 4 .IX Item "low-power = yes|true|on | no|false|off" If true, designates a node as a low-power node. Low-power nodes use larger timeouts and try to reduce cpu time. Other nodes talking to a low-power node will also use larger timeouts, and will use less aggressive optimisations, in the hope of reducing load. Security is not compromised. .Sp The typical low-power node would be a mobile phone, where wakeups and encryption can significantly increase power drain. .IP "max-retry = positive-number" 4 .IX Item "max-retry = positive-number" The maximum interval in seconds (default: \f(CW3600\fR, one hour) between retries to establish a connection to this node. When a connection cannot be established, gvpe uses exponential back-off capped at this value. It's sometimes useful to set this to a much lower value (e.g. \f(CW120\fR) on connections to routers that usually are stable but sometimes are down, to assure quick reconnections even after longer downtimes. .IP "max-ttl = seconds" 4 .IX Item "max-ttl = seconds" Expire packets that couldn't be sent after this many seconds (default: \f(CW60\fR). Gvpe will normally queue packets for a node without an active connection, in the hope of establishing a connection soon. This value specifies the maximum lifetime a packet will stay in the queue, if a packet gets older, it will be thrown away. .IP "max-queue = positive\-number>=1" 4 .IX Item "max-queue = positive-number>=1" The maximum number of packets that will be queued (default: \f(CW512\fR) for this node. If more packets are sent then earlier packets will be expired. See \f(CW\*(C`max\-ttl\*(C'\fR, above. .IP "router-priority = 0 | 1 | positive\-number>=2" 4 .IX Item "router-priority = 0 | 1 | positive-number>=2" Sets the router priority of the given node (default: \f(CW0\fR, disabled). .Sp If some node tries to connect to another node but it doesn't have a hostname, it asks a router node for it's \s-1IP\s0 address. The router node chosen is the one with the highest priority larger than \f(CW1\fR that is currently reachable. This is called a \fImediated\fR connection, as the connection itself will still be direct, but it uses another node to mediate between the two nodes. .Sp The value \f(CW0\fR disables routing, that means if the node receives a packet not for itself it will not forward it but instead drop it. .Sp The special value \f(CW1\fR allows other hosts to route through the router host, but they will never route through it by default (i.e. the config file of another node needs to specify a router priority higher than one to choose such a node for routing). .Sp The idea behind this is that some hosts can, if required, bump the \&\f(CW\*(C`router\-priority\*(C'\fR setting to higher than \f(CW1\fR in their local config to route through specific hosts. If \f(CW\*(C`router\-priority\*(C'\fR is \f(CW0\fR, then routing will be refused, so \f(CW1\fR serves as a \*(L"enable, but do not use by default\*(R" switch. .Sp Nodes with \f(CW\*(C`router\-priority\*(C'\fR set to \f(CW2\fR or higher will always be forced to \f(CW\*(C`connect\*(C'\fR = \f(CW\*(C`always\*(C'\fR (unless they are \f(CW\*(C`disabled\*(C'\fR). .IP "tcp-port = port-number" 4 .IX Item "tcp-port = port-number" Similar to \f(CW\*(C`udp\-port\*(C'\fR (default: \f(CW655\fR), but sets the \s-1TCP\s0 port number. .IP "udp-port = port-number" 4 .IX Item "udp-port = port-number" Sets the port number used by the \s-1UDP\s0 protocol (default: \f(CW655\fR, not officially assigned by \s-1IANA\s0!). .SH "CONFIG DIRECTORY LAYOUT" .IX Header "CONFIG DIRECTORY LAYOUT" The default (or recommended) directory layout for the config directory is: .IP "gvpe.conf" 4 .IX Item "gvpe.conf" The config file. .IP "if-up" 4 .IX Item "if-up" The if-up script .IP "node-up, node-down" 4 .IX Item "node-up, node-down" If used the node up or node-down scripts. .IP "hostkey" 4 .IX Item "hostkey" The (default path of the) private key of the current host. .IP "pubkey/nodename" 4 .IX Item "pubkey/nodename" The public keys of the other nodes, one file per node. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIgvpe\fR\|(5), \fIgvpe\fR\|(8), \fIgvpectrl\fR\|(8). .SH "AUTHOR" .IX Header "AUTHOR" Marc Lehmann gvpe-3.0/doc/gvpe.protocol.70000644000000000000000000004563112676647634012700 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPE.PROTOCOL 7" .TH GVPE.PROTOCOL 7 "2015-10-31" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "The GNU-VPE Protocols" .IX Header "The GNU-VPE Protocols" .SH "Overview" .IX Header "Overview" \&\s-1GVPE\s0 can make use of a number of protocols. One of them is the \s-1GNU VPE\s0 protocol which is used to authenticate tunnels and send encrypted data packets. This protocol is described in more detail the second part of this document. .PP The first part of this document describes the transport protocols which are used by \s-1GVPE\s0 to send its data packets over the network. .SH "PART 1: Transport protocols" .IX Header "PART 1: Transport protocols" \&\s-1GVPE\s0 offers a wide range of transport protocols that can be used to interchange data between nodes. Protocols differ in their overhead, speed, reliability, and robustness. .PP The following sections describe each transport protocol in more detail. They are sorted by overhead/efficiency, the most efficient transport is listed first: .SS "\s-1RAW IP\s0" .IX Subsection "RAW IP" This protocol is the best choice, performance-wise, as the minimum overhead per packet is only 38 bytes. .PP It works by sending the \s-1VPN\s0 payload using raw \s-1IP\s0 frames (using the protocol set by \f(CW\*(C`ip\-proto\*(C'\fR). .PP Using raw \s-1IP\s0 frames has the drawback that many firewalls block \*(L"unknown\*(R" protocols, so this transport only works if you have full \s-1IP\s0 connectivity between nodes. .SS "\s-1ICMP\s0" .IX Subsection "ICMP" This protocol offers very low overhead (minimum 42 bytes), and can sometimes tunnel through firewalls when other protocols can not. .PP It works by prepending an \s-1ICMP\s0 header with type \f(CW\*(C`icmp\-type\*(C'\fR and a code of \f(CW255\fR. The default \f(CW\*(C`icmp\-type\*(C'\fR is \f(CW\*(C`echo\-reply\*(C'\fR, so the resulting packets look like echo replies, which looks rather strange to network administrators. .PP This transport should only be used if other transports (i.e. raw \s-1IP\s0) are not available or undesirable (due to their overhead). .SS "\s-1UDP\s0" .IX Subsection "UDP" This is a good general choice for the transport protocol as \s-1UDP\s0 packets tunnel well through most firewalls and routers, and the overhead per packet is moderate (minimum 58 bytes). .PP It should be used if \s-1RAW IP\s0 is not available. .SS "\s-1TCP\s0" .IX Subsection "TCP" This protocol is a very bad choice, as it not only has high overhead (more than 60 bytes), but the transport also retries on its own, which leads to congestion when the link has moderate packet loss (as both the \s-1TCP\s0 transport and the tunneled traffic will retry, increasing congestion more and more). It also has high latency and is quite inefficient. .PP It's only useful when tunneling through firewalls that block better protocols. If a node doesn't have direct internet access but a \s-1HTTP\s0 proxy that supports the \s-1CONNECT\s0 method it can be used to tunnel through a web proxy. For this to work, the \f(CW\*(C`tcp\-port\*(C'\fR should be \f(CW443\fR (\f(CW\*(C`https\*(C'\fR), as most proxies do not allow connections to other ports. .PP It is an abuse of the usage a proxy was designed for, so make sure you are allowed to use it for \s-1GVPE.\s0 .PP This protocol also has server and client sides. If the \f(CW\*(C`tcp\-port\*(C'\fR is set to zero, other nodes cannot connect to this node directly. If the \&\f(CW\*(C`tcp\-port\*(C'\fR is non-zero, the node can act both as a client as well as a server. .SS "\s-1DNS\s0" .IX Subsection "DNS" \&\fB\s-1WARNING:\s0\fR Parsing and generating \s-1DNS\s0 packets is rather tricky. The code almost certainly contains buffer overflows and other, likely exploitable, bugs. You have been warned. .PP This is the worst choice of transport protocol with respect to overhead (overhead can be 2\-3 times higher than the transferred data), and latency (which can be many seconds). Some \s-1DNS\s0 servers might not be prepared to handle the traffic and drop or corrupt packets. The client also has to constantly poll the server for data, so the client will constantly create traffic even if it doesn't need to transport packets. .PP In addition, the same problems as the \s-1TCP\s0 transport also plague this protocol. .PP Its only use is to tunnel through firewalls that do not allow direct internet access. Similar to using a \s-1HTTP\s0 proxy (as the \s-1TCP\s0 transport does), it uses a local \s-1DNS\s0 server/forwarder (given by the \f(CW\*(C`dns\-forw\-host\*(C'\fR configuration value) as a proxy to send and receive data as a client, and an \f(CW\*(C`NS\*(C'\fR record pointing to the \s-1GVPE\s0 server (as given by the \&\f(CW\*(C`dns\-hostname\*(C'\fR directive). .PP The only good side of this protocol is that it can tunnel through most firewalls mostly undetected, iff the local \s-1DNS\s0 server/forwarder is sane (which is true for most routers, wireless \s-1LAN\s0 gateways and nameservers). .PP Fine-tuning needs to be done by editing \f(CW\*(C`src/vpn_dns.C\*(C'\fR directly. .SH "PART 2: The GNU VPE protocol" .IX Header "PART 2: The GNU VPE protocol" This section, unfortunately, is not yet finished, although the protocol is stable (until bugs in the cryptography are found, which will likely completely change the following description). Nevertheless, it should give you some overview over the protocol. .SS "Anatomy of a \s-1VPN\s0 packet" .IX Subsection "Anatomy of a VPN packet" The exact layout and field lengths of a \s-1VPN\s0 packet is determined at compile time and doesn't change. The same structure is used for all transport protocols, be it \s-1RAWIP\s0 or \s-1TCP.\s0 .PP .Vb 3 \& +\-\-\-\-\-\-+\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | HMAC | TYPE | SRCDST | DATA | \& +\-\-\-\-\-\-+\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ .Ve .PP The \s-1HMAC\s0 field is present in all packets, even if not used (e.g. in auth request packets), in which case it is set to all zeroes. The \s-1MAC\s0 itself is calculated over the \s-1TYPE, SRCDST\s0 and \s-1DATA\s0 fields in all cases. .PP The \s-1TYPE\s0 field is a single byte and determines the purpose of the packet (e.g. \s-1RESET, COMPRESSED/UNCOMPRESSED DATA, PING, AUTH REQUEST/RESPONSE, CONNECT REQUEST/INFO\s0 etc.). .PP \&\s-1SRCDST\s0 is a three byte field which contains the source and destination node IDs (12 bits each). .PP The \s-1DATA\s0 portion differs between each packet type, naturally, and is the only part that can be encrypted. Data packets contain more fields, as shown: .PP .Vb 3 \& +\-\-\-\-\-\-+\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | HMAC | TYPE | SRCDST | SEQNO | DATA | \& +\-\-\-\-\-\-+\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-+\-\-\-\-\-\-+ .Ve .PP \&\s-1SEQNO\s0 is a 32\-bit sequence number. It is negotiated at every connection initialization and starts at some random 31 bit value. \s-1GVPE\s0 currently uses a sliding window of 512 packets/sequence numbers to detect reordering, duplication and replay attacks. .PP The encryption is done on \s-1SEQNO+DATA\s0 in \s-1CTR\s0 mode with \s-1IV\s0 generated from the seqno (for \s-1AES:\s0 seqno || seqno || seqno || (u32)0), which ensures uniqueness for a given key. .SS "The authentication/key exchange protocol" .IX Subsection "The authentication/key exchange protocol" Before nodes can exchange packets, they need to establish authenticity of the other side and a key. Every node has a private \s-1RSA\s0 key and the public \&\s-1RSA\s0 keys of all other nodes. .PP When a node wants to establish a connection to another node, it sends an RSA-OEAP-encrypted challenge and an \s-1ECDH \s0(curve25519) key. The other node replies with its own \s-1ECDH\s0 key and a \s-1HKDF\s0 of the challenge and both \s-1ECDH\s0 keys to prove its identity. .PP The remote node enganges in exactly the same protocol. When both nodes have exchanged their challenge and verified the response, they calculate a cipher key and a \s-1HMAC\s0 key and start exchanging data packets. .PP In detail, the challenge consist of: .PP .Vb 1 \& RSA\-OAEP (SEQNO MAC CIPHER SALT EXTRA\-AUTH) ECDH1 .Ve .PP That is, it encrypts (with the public key of the remote node) an initial sequence number for data packets, key material for the \s-1HMAC\s0 key, key material for the cipher key, a salt used by the \s-1HKDF \s0(as shown later) and some extra random bytes that are unused except for authentication. It also sends the public key of a curve25519 exchange. .PP The remote node decrypts the \s-1RSA\s0 data, generates its own \s-1ECDH\s0 key (\s-1ECDH2\s0), and replies with: .PP .Vb 1 \& HKDF\-Expand (HKDF\-Extract (ECDH2, RSA), ECDH1, AUTH_DIGEST_SIZE) ECDH2 .Ve .PP That is, it extracts from the decrypted \s-1RSA\s0 challenge, using its \s-1ECDH\s0 key as salt, and then expands using the requesting node's \s-1ECDH1\s0 key. The resulting hash is returned as a proof that the node could decrypt the \s-1RSA\s0 challenge data, together with the \s-1ECDH\s0 key. .PP After both nodes have done this to each other, they calculate the shared \&\s-1ECDH\s0 secret, cipher and \s-1HMAC\s0 keys for the session (each node generates two cipher and \s-1HMAC\s0 keys, one for sending and one for receiving). .PP The \s-1HMAC\s0 key for sending is generated as follow: .PP .Vb 1 \& HMAC_KEY = HKDF\-Expand (HKDF\-Extract (REMOTE_SALT, MAC ECDH_SECRET), info, HMAC_MD_SIZE) .Ve .PP It extracts from \s-1MAC\s0 and \s-1ECDH_SECRET\s0 using the \fIremote\fR \s-1SALT,\s0 then expands using a static info string. .PP The cipher key is generated in the same way, except using the \s-1CIPHER\s0 part of the original challenge. .PP The result of this process is to authenticate each node to the other node, while exchanging keys using both \s-1RSA\s0 and \s-1ECDH,\s0 the latter providing perfect forward secrecy. .PP The protocol has been overdesigned where this was possible without increasing implementation complexity, in an attempt to protect against implementation or protocol failures. For example, if the \s-1ECDH\s0 challenge was found to be flawed, perfect forward secrecy would be lost, but the data would likely still be protected. Likewise, standard algorithms and implementations are used where possible. .SS "Retrying" .IX Subsection "Retrying" When there is no response to an auth request, the node will send auth requests in bursts with an exponential back-off. After some time it will resort to \s-1PING\s0 packets, which are very small (8 bytes + protocol header) and lightweight (no \s-1RSA\s0 operations required). A node that receives ping requests from an unconnected peer will respond by trying to create a connection. .PP In addition to the exponential back-off, there is a global rate-limit on a per-IP base. It allows long bursts but will limit total packet rate to something like one control packet every ten seconds, to avoid accidental floods due to protocol problems (like a \s-1RSA\s0 key file mismatch between two nodes). .PP The intervals between retries are limited by the \f(CW\*(C`max\-retry\*(C'\fR configuration value. A node with \f(CW\*(C`connect\*(C'\fR = \f(CW\*(C`always\*(C'\fR will always retry, a node with \f(CW\*(C`connect\*(C'\fR = \f(CW\*(C`ondemand\*(C'\fR will only try (and re-try) to connect as long as there are packets in the queue, usually this limits the retry period to \f(CW\*(C`max\-ttl\*(C'\fR seconds. .PP Sending packets over the \s-1VPN\s0 will reset the retry intervals as well, which means as long as somebody is trying to send packets to a given node, \s-1GVPE\s0 will try to connect every few seconds. .SS "Routing and Protocol translation" .IX Subsection "Routing and Protocol translation" The \s-1GVPE\s0 routing algorithm is easy: there isn't much routing to speak of: When routing packets to another node, \s-1GVPE\s0 tries the following options, in order: .IP "If the two nodes should be able to reach each other directly (common protocol, port known), then \s-1GVPE\s0 will send the packet directly to the other node." 4 .IX Item "If the two nodes should be able to reach each other directly (common protocol, port known), then GVPE will send the packet directly to the other node." .PD 0 .ie n .IP "If this isn't possible (e.g. because the node doesn't have a \*(C`hostname\*(C' or known port), but the nodes speak a common protocol and a router is available, then \s-1GVPE\s0 will ask a router to ""mediate"" between both nodes (see below)." 4 .el .IP "If this isn't possible (e.g. because the node doesn't have a \f(CW\*(C`hostname\*(C'\fR or known port), but the nodes speak a common protocol and a router is available, then \s-1GVPE\s0 will ask a router to ``mediate'' between both nodes (see below)." 4 .IX Item "If this isn't possible (e.g. because the node doesn't have a hostname or known port), but the nodes speak a common protocol and a router is available, then GVPE will ask a router to mediate between both nodes (see below)." .ie n .IP "If a direct connection isn't possible (no common protocols) or forbidden (\*(C`deny\-direct\*(C') and there are any routers, then \s-1GVPE\s0 will try to send packets to the router with the highest priority that is connected already \fIand\fR is able (as specified by the config file) to connect directly to the target node." 4 .el .IP "If a direct connection isn't possible (no common protocols) or forbidden (\f(CW\*(C`deny\-direct\*(C'\fR) and there are any routers, then \s-1GVPE\s0 will try to send packets to the router with the highest priority that is connected already \fIand\fR is able (as specified by the config file) to connect directly to the target node." 4 .IX Item "If a direct connection isn't possible (no common protocols) or forbidden (deny-direct) and there are any routers, then GVPE will try to send packets to the router with the highest priority that is connected already and is able (as specified by the config file) to connect directly to the target node." .IP "If no such router exists, then \s-1GVPE\s0 will simply send the packet to the node with the highest priority available." 4 .IX Item "If no such router exists, then GVPE will simply send the packet to the node with the highest priority available." .IP "Failing all that, the packet will be dropped." 4 .IX Item "Failing all that, the packet will be dropped." .PD .PP A host can usually declare itself unreachable directly by setting its port number(s) to zero. It can declare other hosts as unreachable by using a config-file that disables all protocols for these other hosts. Another option is to disable all protocols on that host in the other config files. .PP If two hosts cannot connect to each other because their \s-1IP\s0 address(es) are not known (such as dial-up hosts), one side will send a \fImediated\fR connection request to a router (routers must be configured to act as routers!), which will send both the originating and the destination host a connection info request with protocol information and \s-1IP\s0 address of the other host (if known). Both hosts will then try to establish a direct connection to the other peer, which is usually possible even when both hosts are behind a \s-1NAT\s0 gateway. .PP Routing via other nodes works because the \s-1SRCDST\s0 field is not encrypted, so the router can just forward the packet to the destination host. Since each host uses its own private key, the router will not be able to decrypt or encrypt packets, it will just act as a simple router and protocol translator. gvpe-3.0/doc/gvpe.osdep.50000644000000000000000000002760112676647634012144 00000000000000.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GVPE.OSDEP 5" .TH GVPE.OSDEP 5 "2015-10-31" "2.25" "GNU Virtual Private Ethernet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" gvpe.osdep \- os dependent information .SH "DESCRIPTION" .IX Header "DESCRIPTION" This file tries to capture OS-dependent configuration or build issues, quirks and platform limitations, as known. .SH "TUN vs. TAP interface" .IX Header "TUN vs. TAP interface" Most operating systems nowadays support something called a \&\fItunnel\fR\-device, which makes it possible to divert IPv4 (and often other protocols, too) into a user space daemon like \f(CW\*(C`gvpe\*(C'\fR. This is being referred to as a TUN-device. .PP This is fine for point-to-point tunnels, but for a virtual ethernet, an additional ethernet header is needed. This functionality (called a \s-1TAP\s0 device here) is only provided by a subset of the configurations. .PP On platforms only supporting a TUN-device, gvpe will invoke it's magical ethernet emulation package, which currently only handles \s-1ARP\s0 requests for the IPv4 protocol (but more could be added, bu the tincd network drivers might need to be modified for this to work). This means that on those platforms, only IPv4 will be supported. .PP Also, since there is no way (currently) to tell gvpe which \s-1IP\s0 subnets are found on a specific host, you will either need to hardwire the \s-1MAC\s0 address for TUN-style hosts on all networks (and avoid \s-1ARP\s0 altogether, which is possible), or you need to send a packet from these hosts into the vpn network to tell gvpe the local interface address. .SH "Interface Initialisation" .IX Header "Interface Initialisation" Unless otherwise notes, the network interface will be initialized with the expected \s-1MAC\s0 address and correct \s-1MTU\s0 value. With most interface drivers, this is done by running \f(CW\*(C`/sbin/ifconfig\*(C'\fR, so make sure that this command exists. .SH "Interface Types" .IX Header "Interface Types" .SS "native/linux" .IX Subsection "native/linux" TAP-device; already part of the kernel (only 2.4+ supported, but see tincd/linux). This is the configuration tested best, as gvpe is being developed on this platform. .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the name of the network device. .PP To hardwire \s-1ARP\s0 addresses, use iproute2 (\f(CW\*(C`arp\*(C'\fR can do it, too): .PP .Vb 2 \& MAC=fe:fd:80:00:00:$(printf "%02x" $NODEID) \& ip neighbour add 10.11.12.13 lladdr $MAC nud permanent dev $IFNAME .Ve .SS "tincd/linux" .IX Subsection "tincd/linux" TAP-device; already part of the kernel (2.2 only). See \&\f(CW\*(C`native/linux\*(C'\fR for more info. .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the path of a tap device, e.g. \f(CW\*(C`/dev/tap0\*(C'\fR. The interface will be named accordingly. .SS "native/cygwin" .IX Subsection "native/cygwin" TAP-device; The \s-1TAP\s0 device to be used must either be the \s-1CIPE\s0 driver (\f(CW\*(C`http://cipe\-win32.sourceforge.net/\*(C'\fR), or (highly recommended) the newer TAP\-Win32 driver bundled with openvpn (http://openvpn.sf.net/). Just download and run the openvpn installer. The only option you need to select is the \s-1TAP\s0 driver. .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the name of the device, found in the registry at (no kidding :): .PP .Vb 1 \& HKEY_LOCAL_MACHINE\eSYSTEM\eCurrentControlSet\eControl\eNetwork\e{4D36E972\-E325\-11CE\-BFC1\-08002BE10318}\e\eConnection\eName .Ve .PP The \s-1MAC\s0 address is dynamically being patched into packets and ARP-requests, so only IPv4 works with \s-1ARP\s0 on this platform. .SS "tincd/bsd" .IX Subsection "tincd/bsd" TAP-device, maybe; migth work for many bsd variants. .PP This driver is a newer version of the \f(CW\*(C`tincd/*bsd\*(C'\fR drivers. It \fImight\fR provide a \s-1TAP\s0 device, or might not work at all. You might try this interface type first, and, if it doesn't work, try one of the OS-specific drivers. .SS "tincd/freebsd" .IX Subsection "tincd/freebsd" TAP-device; part of the kernel (since 4.x, maybe earlier). .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the path of a tap device, e.g. \f(CW\*(C`/dev/tap0\*(C'\fR. The interface will be named accordingly. .PP These commands might be helpful examples: .PP .Vb 2 \& ifconfig $IFNAME 10.0.0.$NODEID \& route add \-net 10.0.0.0 \-netmask 255.255.255.0 \-interface $IFNAME 10.0.0.$NODEID .Ve .SS "tincd/netbsd" .IX Subsection "tincd/netbsd" TUN-device; The interface is a point-to-point device. To initialize it, you currently need to configure it as a point-to-point device, giving it an address on your vpn (the exact address doesn't matter), like this: .PP .Vb 4 \& ifconfig $IFNAME mtu $MTU up \& ifconfig $IFNAME 10.11.12.13 10.55.66.77 \& route add \-net 10.0.0.0 10.55.66.77 255.0.0.0 \& ping \-c1 10.55.66.77 # ping once to tell gvpe your gw ip .Ve .PP The ping is required to tell the \s-1ARP\s0 emulator inside \s-1GVPE\s0 the local \s-1IP\s0 address. .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the path of a tun device, e.g. \f(CW\*(C`/dev/tun0\*(C'\fR. The interface will be named accordingly. .SS "tincd/openbsd" .IX Subsection "tincd/openbsd" TUN-device; already part of the kernel. See \f(CW\*(C`tincd/netbsd\*(C'\fR for more information. .SS "native/darwin" .IX Subsection "native/darwin" TAP-device; .PP The necessary kernel extension can be found here: .PP .Vb 1 \& http://www\-user.rhrk.uni\-kl.de/~nissler/tuntap/ .Ve .PP There are two drivers, the one to use is the \*(L"tap\*(R" driver. It driver must be loaded before use, read the docs on how to install it as a startup item. .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the path of a tap device, e.g. \f(CW\*(C`/dev/tap0\*(C'\fR. The interface will be named accordingly. .PP These commands might be helpful examples: .PP .Vb 2 \& ifconfig $IFNAME 10.0.0.$NODEID \& route add \-net 10.0.0.0 \-interface $IFNAME 255.255.255.0 .Ve .SS "tincd/darwin" .IX Subsection "tincd/darwin" TUN-device; See \f(CW\*(C`tincd/netbsd\*(C'\fR for more information. \f(CW\*(C`native/darwin\*(C'\fR is preferable. .PP The necessary kernel extension can be found here: .PP .Vb 1 \& http://chrisp.de/en/projects/tunnel.html .Ve .PP \&\f(CW\*(C`ifname\*(C'\fR should be set to the path of a tun device, e.g. \f(CW\*(C`/dev/tun0\*(C'\fR. The interface will be named accordingly. .PP The driver must be loaded before use: .PP .Vb 1 \& kmodload tunnel .Ve .SS "tincd/solaris" .IX Subsection "tincd/solaris" TUN-device; already part of the kernel(?), or available here: .PP .Vb 1 \& http://vtun.sourceforge.net/tun/ .Ve .PP Some precompiled tun drivers might be available here: .PP .Vb 1 \& http://www.monkey.org/~dugsong/fragroute/ .Ve .PP The interface \s-1MAC\s0 and \s-1MTU\s0 are \fI\s-1NOT\s0\fR set up for you. Please try it out and send me an \f(CW\*(C`ifconfig\*(C'\fR command invocation that does that. .PP See \f(CW\*(C`tincd/netbsd\*(C'\fR for more information. .PP Completely untested so far. .SS "tincd/mingw" .IX Subsection "tincd/mingw" TAP-device; see \f(CW\*(C`native/cygwin\*(C'\fR for more information. .PP The setup is likely to be similar to \f(CW\*(C`native/cygwin\*(C'\fR. .PP Completely untested so far. .SS "tincd/raw_socket" .IX Subsection "tincd/raw_socket" TAP-device; purpose unknown and untested, probably binds itself on an existing ethernet device (given by \f(CW\*(C`ifname\*(C'\fR). It must be down prior to running the command, and \s-1GVPE\s0 will try to set it's \s-1MAC\s0 address and \s-1MTU\s0 to the \*(L"correct\*(R" values. .PP Completely untested so far. .SS "tincd/uml_socket" .IX Subsection "tincd/uml_socket" TAP-device; purpose unknown and untested, probably creates a \s-1UNIX\s0 datagram socket (path given by \f(CW\*(C`ifname\*(C'\fR) and reads and writes raw packets, so might be useful in other than \s-1UML\s0 contexts. .PP No network interface is created, and the \s-1MAC\s0 and \s-1MTU\s0 must be set as appropriate on the other side of the socket. \s-1GVPE\s0 will exit if the \s-1MAC\s0 address doesn't match what it expects. .PP Completely untested so far. .SS "tincd/cygwin" .IX Subsection "tincd/cygwin" Known to be broken, use \f(CW\*(C`native/cygwin\*(C'\fR instead. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIgvpe\fR\|(5). .SH "AUTHOR" .IX Header "AUTHOR" Marc Lehmann gvpe-3.0/doc/Makefile.maint0000644000000000000000000000244011046631516012523 00000000000000# This -*- Makefile -*- uses features of GNU make. # It is included via GNUmakefile. # The following one line summaries were extracted from the # original man pages using this bit of sh code: # for i in *.1; do echo "$i: "|tr -d '\012'; \ # grep -A1 SH.NAME $i|sed '/SH NAME/d;s/^[^ ][^ ]* .- //'; done # Depend on configure.in to get version number changes. $(dyn_MANS): $(top_srcdir)/configure.in # Depend on the source file containing the --help text. # Filter out irregular cases. regular-men = $(filter-out $(irregular-men),$(dyn_MANS)) $(regular-men): %.8: $(top_srcdir)/src/%.c executable = $(patsubst %/install,%/ginstall, ../src/$(basename $@)) %.5: %.5.pod Makefile.maint pod2man -n$(shell perl -e '$$ARGV[0] =~ s/\.\d$$//; print uc $$ARGV[0]' $@) -qnone -r$(VERSION) -s5 -c "GNU Virtual Private Ethernet" $< >$@ %.7: %.7.pod Makefile.maint pod2man -n$(shell perl -e '$$ARGV[0] =~ s/\.\d$$//; print uc $$ARGV[0]' $@) -qnone -r$(VERSION) -s7 -c "GNU Virtual Private Ethernet" $< >$@ %.8: %.8.pod Makefile.maint pod2man -n$(shell perl -e '$$ARGV[0] =~ s/\.\d$$//; print uc $$ARGV[0]' $@) -qnone -r$(VERSION) -s8 -c "GNU Virtual Private Ethernet" $< >$@ gvpe.texi: gvpe.texi.pod pod2texi ./pod2texi gvpe.texi ../README: gvpe.5.pod pod2text -q\\\" -a gvpe.5.pod >../README gvpe-3.0/doc/pod2texi0000744000000000000000000001046111525406703011440 00000000000000#!/usr/bin/perl # TODO: texinfo fails on @cindex in title elements etc. *sigh* use Pod::POM; sub escape_texi($) { local $_ = shift; s/([\@\{\}])/\@$1/g; s/\n+/ /g; $_; } sub example { my $text = $_[0]; $text =~ s/\n+$//; $text =~ s/([\@\{\}])/\@$1/g; "\n\n\@example\n" . $text . "\n\@end example\n\n"; } my @nodes; # nodelist my @ctx; # curstack sub out { $ctx[-1]{out} .= join "", @_; } sub TEX::view_seq_code { "\@t{$_[1]}" } sub TEX::view_seq_file { "\@file{$_[1]}" } sub TEX::view_seq_bold { "\@strong{$_[1]}" } sub TEX::view_seq_italic { "\@emph{$_[1]}" } sub TEX::view_seq_space { escape_texi $_[1] } sub TEX::view_seq_text { escape_texi $_[1] } sub TEX::view_seq_link { $_[1] } sub TEX::view_seq_index { "\n\@cindex $_[1]\n$_[1]" } *TXT::view_seq_code = *TXT::view_seq_bold = *TXT::view_seq_italic = *TXT::view_seq_space = *TXT::view_seq_text = *TXT::view_seq_link = *TXT::view_seq_index = sub { $_[1] }; my %ignore = ( "SEE ALSO" => 1, "AUTHOR" => 1, ); sub parse_pod { my ($data) = @_; local $out; local $Pod::POM::DEFAULT_VIEW = TEX::; my $parser = new Pod::POM; my $pod = $parser->parse_text ($data) or die; my $walker; $walker = sub { my $n = $_[0]; my $t = $n->type; if ($t eq "text") { out $n->text . "\n\@refill\n"; } elsif ($t eq "pod") { $walker->($_) for $n->content; } elsif ($t eq "verbatim") { out example $n->text; } elsif ($t eq "head1") { return if $ignore{$n->title}; out "\n\@section " . $n->title . "\n"; $walker->($_) for $n->content; out "\n"; } elsif ($t eq "head2") { out "\n\n\@subsection " . $n->title . "\n"; $walker->($_) for $n->content; } elsif ($t eq "over") { out "\n\n\@itemize\n"; $walker->($_) for $n->content; out "\@end itemize\n\n"; } elsif ($t eq "item") { out "\n\n\@item\n" . $n->title . "\n\n"; if ($n->title->present (TXT::) =~ /^\s*([a-zA-Z0-9\-\_]+)\s*=/) { out "\@cindex $1\n"; } $walker->($_) for $n->content; } elsif ($t eq "begin") { local $Pod::POM::DEFAULT_VIEW = Pod::POM::View::Pod; my $format = $n->format; if ($format =~ /texinfo\s+header/) { $header = $n->content; } elsif ($format =~ /texinfo\s+footer/) { $footer = $n->content; } else { out $n->content; } } elsif ($t eq "for") { my $text = $n->text; if ($text =~ /^menu-begin/) { out "\n\@menu\n"; push @ctx, {}; # dummy node } elsif ($text =~ /^menu-item (.*?)::\s+(.*)/) { my ($name, $desc) = ($1, $2); push @{ $ctx[-2]{menu} }, [$name, $desc]; $ctx[-2]{width} = length $name if $ctx[-2]{width} < length $name; my $ctx = { name => $name, up => $ctx[-2]{name}, }; push @nodes, $ctx; $ctx[-1] = $ctx; } elsif ($text =~ /^menu-end/) { pop @ctx; for (@{ $ctx[-1]{menu} }) { out sprintf "* %-*s %s\n", $ctx[-1]{width} + 2, "$_->[0]::", $_->[1]; } out "\@end menu\n"; } elsif ($text =~ /^include (\S+) (.*)/) { my ($type, $path) = ($1, $2); open my $x, "<$path" or die "$path: $!"; my $data = do { local $/; <$x> }; if ($type eq "pod") { out parse_pod ($data); } elsif ($type eq "text") { out $data; } elsif ($type eq "example") { out example $data; } } else { die "UNKNOWN for command <$text>\n"; } } else { die "UNKNOWN NODE $t\n"; } }; $walker->($pod); } @ctx = @nodes = { up => "(dir)", name => "Top", }; parse_pod do { local $/; <> }; print $header; for (0 .. $#nodes) { my $node = $nodes[$_]; my $prev = $_ > 0 ? $nodes[$_-1] : undef; my $next = $nodes[$_+1]; my $chapter = $node->{name} eq "Top" ? "Introduction" : $node->{name}; print "\@node $node->{name},$next->{name},$prev->{name},$node->{up}\n\n", "\@chapter $chapter\n", "$node->{out}\n\n"; } print $footer; gvpe-3.0/doc/gvpe.texi.pod0000644000000000000000000001227712615056110012374 00000000000000=begin texinfo header \input texinfo @c -*-texinfo-*- @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c GENERATED FILE, gvpe.texi.pod is the source, not gvpe.texi! @c %**start of header @finalout @setfilename gvpe.info @settitle GNU Virtual Private Ethernet Manual @setchapternewpage odd @c %**end of header @ifinfo @dircategory Networking tools @direntry * gvpe: (gvpe). The GNU VPE Manual. @end direntry This is the info manual for vpe, the Virtual Private Ethernet daemon. Copyright @copyright{} 2003-2008 Marc Lehmann . Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. @end ifinfo @titlepage @title gvpe Manual @author Marc Lehmann @page @vskip 0pt plus 1filll @cindex copyright Copyright @copyright{} 2003-2008 Marc Lehmann . Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. @end titlepage @contents =end texinfo This is the documentation for the GNU Virtual Private Ethernet suite. The GNU Virtual Private Ethernet suite implements a virtual (uses udp, tcp, rawip and other protocols for tunneling), private (encrypted, authenticated) ethernet (mac-based, broadcast-based network) that is shared among multiple nodes, in effect implementing an ethernet bus over public networks. =for texinfo menu-begin =for texinfo menu-item Overview:: Introduction to and Tutorial for GVPE (gvpe(5)) =for texinfo include pod gvpe.5.pod =for texinfo menu-item OS Dependencies:: OS-Dependent Installation and Configuration Notes (gvpe.osdep(5)) =for texinfo include pod gvpe.osdep.5.pod =for texinfo menu-item gvpe.conf:: The main configuration file (gvpe.conf(5)) =for texinfo include pod gvpe.conf.5.pod =for texinfo menu-item gvpectrl:: Configuration/Control Program Reference (gvpectrl(8)) =for texinfo include pod gvpectrl.8.pod =for texinfo menu-item gvpe:: The GVPE Daemon (gvpe(8)) =for texinfo include pod gvpe.8.pod =for texinfo menu-item gvpe.protocol:: The GVPE Transport and VPN Protocols (gvpe.protocol(7)) =for texinfo include pod gvpe.protocol.7.pod =for texinfo menu-item Simple Example:: A simple yet realistic Example In this example, gvpe is used to implement a simple, UDP-based ethernet on three hosts. The config file (C) is the same on all hosts: enable-udp = yes # use UDP udp-port = 407 # use this UDP port mtu = 1492 # handy for TDSL ifname = vpn0 # I prefer vpn0 over e.g. tap0 node = huffy # arbitrary node name hostname = 1.2.3.4 # ip address if this host node = welshy hostname = www.example.net # resolve at connection time node = wheelery # no hostname, will be determinded dynamically using router1 or router2 C will execute the C script on every hosts, which, for linux, could look like this for all three hosts: ifconfig $IFNAME hw ether $MAC mtu $MTU ifconfig $IFNAME 10.0.0.$NODE route add -net 10.0.0.0 netmask 255.0.0.0 dev $IFNAME The C<10.0.0.$NODE> resolves to C<10.0.0.1> on C, C<10.0.0.2> on C and so on. Other schemes, such as C<10.$NODE.0.1> might be useful, too. After generating the keys (L) and starting the daemon (CI for test purposes) the three hosts should be able to ping each other. If you have an internal C<10.x.x.x> network (with a tighter netmask then C<255.0.0.0>, e.g. C<10.1.0.0> on C, C<10.2.0.0> on C and so on), you can now enable ip-forwarding and proxy-arp (or set the hosts as default gateway), and your three hosts should forward traffic from each network to each other. =for texinfo menu-item Complex Example:: A non-trivial Example =for texinfo include text complex-example/README =for texinfo menu-begin =for texinfo menu-item complex/gvpe.conf:: An example gvpe configuration =for texinfo include example complex-example/gvpe.conf =for texinfo menu-item complex/if-up:: A fully-routing if-up config =for texinfo include example complex-example/if-up =for texinfo menu-item complex/node-up:: A node-up/node-down script utilizing dynds =for texinfo include example complex-example/node-up =for texinfo menu-end =for texinfo menu-item Index:: Keyword and Concept index =begin texinfo @printindex cp =end texinfo =for texinfo menu-end =begin texinfo footer @bye =end texinfo gvpe-3.0/doc/gvpe.5.pod0000644000000000000000000002420213006306731011560 00000000000000=head1 NAME GNU-VPE - Overview of the GNU Virtual Private Ethernet suite. =head1 DESCRIPTION GVPE is a suite designed to provide a virtual private network for multiple nodes over an untrusted network. This document first gives an introduction to VPNs in general and then describes the specific implementation of GVPE. =head2 WHAT IS A VPN? VPN is an acronym, it stands for: =over 4 =item Virtual Virtual means that no physical network is created (of course), but a network is I by creating multiple tunnels between the member nodes by encapsulating and sending data over another transport network. Usually the emulated network is a normal IP or Ethernet, and the transport network is the Internet. However, using a VPN system like GVPE to connect nodes over other untrusted networks such as Wireless LAN is not uncommon. =item Private Private means that non-participating nodes cannot decode ("sniff)" nor inject ("spoof") packets. This means that nodes can be connected over untrusted networks such as the public Internet without fear of being eavesdropped while at the same time being able to trust data sent by other nodes. In the case of GVPE, even participating nodes cannot sniff packets send to other nodes or spoof packets as if sent from other nodes, so communications between any two nodes is private to those two nodes. =item Network Network means that more than two parties can participate in the network, so for instance it's possible to connect multiple branches of a company into a single network. Many so-called "VPN" solutions only create point-to-point tunnels, which in turn can be used to build larger networks. GVPE provides a true multi-point network in which any number of nodes (at least a few dozen in practise, the theoretical limit is 4095 nodes) can participate. =back =head2 GVPE DESIGN GOALS =over 4 =item SIMPLE DESIGN Cipher, HMAC algorithms and other key parameters must be selected at compile time - this makes it possible to only link in algorithms you actually need. It also makes the crypto part of the source very transparent and easy to inspect, and last not least this makes it possible to hardcode the layout of all packets into the binary. GVPE goes a step further and internally reserves blocks of the same length for all packets, which virtually removes all possibilities of buffer overflows, as there is only a single type of buffer and it's always of fixed length. =item EASY TO SETUP A few lines of config (the config file is shared unmodified between all hosts) and generating an RSA key-pair on each node suffices to make it work. =item MAC-BASED SECURITY Since every host has it's own private key, other hosts cannot spoof traffic from this host. That makes it possible to filter packet by MAC address, e.g. to ensure that packets from a specific IP address come, in fact, from a specific host that is associated with that IP and not from another host. =back =head1 PROGRAMS Gvpe comes with two programs: one daemon (C) and one control program (C). =over 4 =item gvpectrl This program is used to generate the keys, check and give an overview of of the configuration and to control the daemon (restarting etc.). =item gvpe This is the daemon used to establish and maintain connections to the other network nodes. It should be run on the gateway of each VPN subnet. =back =head1 COMPILETIME CONFIGURATION Please have a look at the C manpage for platform-specific information. Gvpe hardcodes most encryption parameters. While this reduces flexibility, it makes the program much simpler and helps making buffer overflows impossible under most circumstances. Here are a few recipes for compiling your gvpe, showing the extremes (fast, small, insecure OR slow, large, more secure), between which you should choose: =head2 AS LOW PACKET OVERHEAD AS POSSIBLE ./configure --enable-hmac-length=4 --enable-rand-length=0 Minimize the header overhead of VPN packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a HMAC length of 4 makes collision attacks almost trivial. =head2 MINIMIZE CPU TIME REQUIRED ./configure --enable-cipher=bf --enable-digest=md4 Use the fastest cipher and digest algorithms currently available in gvpe. MD4 has been broken and is quite insecure, though, so using another digest algorithm is recommended. =head2 MAXIMIZE SECURITY ./configure --enable-hmac-length=16 --enable-rand-length=12 --enable-digest=ripemd610 This uses a 16 byte HMAC checksum to authenticate packets (I guess 8-12 would also be pretty secure ;) and will additionally prefix each packet with 12 bytes of random data. In general, remember that AES-128 seems to be as secure but faster than AES-192 or AES-256, more randomness helps against sniffing and a longer HMAC helps against spoofing. MD4 is a fast digest, SHA1, RIPEMD160, SHA256 are consecutively better, and Blowfish is a fast cipher (and also quite secure). =head1 HOW TO SET UP A SIMPLE VPN In this section I will describe how to get a simple VPN consisting of three hosts up and running. =head2 STEP 1: configuration First you have to create a daemon configuration file and put it into the configuration directory. This is usually C, depending on how you configured gvpe, and can be overwritten using the C<-c> command line switch. Put the following lines into C: udp-port = 50000 # the external port to listen on (configure your firewall) mtu = 1400 # minimum MTU of all outgoing interfaces on all hosts ifname = vpn0 # the local network device name node = first # just a nickname hostname = first.example.net # the DNS name or IP address of the host node = second hostname = 133.55.82.9 node = third hostname = third.example.net The only other file necessary is the C script that initializes the virtual ethernet interface on the local host. Put the following lines into C and make it executable (C): #!/bin/sh ip link set $IFNAME address $MAC mtu $MTU up [ $NODENAME = first ] && ip addr add 10.0.1.1 dev $IFNAME [ $NODENAME = second ] && ip addr add 10.0.2.1 dev $IFNAME [ $NODENAME = third ] && ip addr add 10.0.3.1 dev $IFNAME ip route add 10.0.0.0/16 dev $IFNAME This script will give each node a different IP address in the C<10.0/16> network. The internal network (if gvpe runs on a router) should then be set to a subset of that network, e.g. C<10.0.1.0/24> on node C, C<10.0.2.0/24> on node C, and so on. By enabling routing on the gateway host that runs C all nodes will be able to reach the other nodes. You can, of course, also use proxy ARP or other means of pseudo-bridging, or (best) full routing - the choice is yours. =head2 STEP 2: create the RSA key pair for each node Next you have to generate the RSA keys for the nodes. While you can set up GVPE so you can generate all keys on a single host and centrally distribute all keys, it is safer to generate the key for each node on the node, so that the secret/private key does not have to be copied over the network. To do so, run the following command to generate a key pair: gvpectrl -c /etc/gvpe -g nodekey This will create two files, F and F. The former should be copied to F<< /etc/gvpe/pubkey/I >> on the host where your config file is (you will have to create the F directory first): scp nodekey confighost:/etc/gvpe/pubkey/nodename The private key F should be moved to F: mkdir -p /etc/gvpe mv nodekey.privkey /etc/gvpe/hostkey =head2 STEP 3: distribute the config files to all nodes Now distribute the config files and public keys to the other nodes. The example uses rsync-over-ssh to copy the config file and all the public keys: rsync -avzessh /etc/gvpe first.example.net:/etc/. --exclude hostkey rsync -avzessh /etc/gvpe 133.55.82.9:/etc/. --exclude hostkey rsync -avzessh /etc/gvpe third.example.net:/etc/. --exclude hostkey You should now check the configuration by issuing the command C on each node and verify it's output. =head2 STEP 4: starting gvpe You should then start gvpe on each node by issuing a command like: gvpe -D -l info first # first is the nodename This will make the gvpe daemon stay in foreground. You should then see "connection established" messages. If you don't see them check your firewall and routing (use tcpdump ;). If this works you should check your networking setup by pinging various endpoints. To make gvpe run more permanently you can either run it as a daemon (by starting it without the C<-D> switch), or, much better, from your inittab or equivalent. I use a line like this on all my systems: t1:2345:respawn:/opt/gvpe/sbin/gvpe -D -L first >/dev/null 2>&1 =head2 STEP 5: enjoy ... and play around. Sending a -HUP (C) to the daemon will make it try to connect to all other nodes again. If you run it from inittab C (or simply C) will kill the daemon, start it again, making it read it's configuration files again. To run the GVPE daemon permanently from your SysV init, you can add it to your F, e.g.: t1:2345:respawn:/bin/sh -c "exec nice -n-20 /path/to/gvpe -D node >/var/log/gvpe.log 2>&1" For systems using systemd, you can use a unit file similar to this one: [Unit] Description=gvpe After=network.target Before=remote-fs.target [Service] ExecStart=/path/to/gvpe -D node KillMode=process Restart=always [Install] WantedBy=multi-user.target =head1 SEE ALSO gvpe.osdep(5) for OS-dependent information, gvpe.conf(5), gvpectrl(8), and for a description of the transports, protocol, and routing algorithm, gvpe.protocol(7). The GVPE mailing list, at L, or C. =head1 AUTHOR Marc Lehmann =head1 COPYRIGHTS AND LICENSES GVPE itself is distributed under the GENERAL PUBLIC LICENSE (see the file COPYING that should be part of your distribution). In some configurations it uses modified versions of the tinc vpn suite, which is also available under the GENERAL PUBLIC LICENSE. gvpe-3.0/doc/gvpe.8.pod0000644000000000000000000001033213006307224011560 00000000000000=head1 NAME C - GNU Virtual Private Ethernet Daemon =head1 SYNOPSIS C [B<-cDlL>] [B<--config=>I] [B<--no-detach>] [B<-l=>I] [B<--kill>[B<=>I]] [B<--mlock>] [B<--help>] [B<--version>] I [I] =head1 DESCRIPTION See the gvpe(5) man page for an introduction to the gvpe suite. This is the manual page for gvpe, the virtual private ethernet daemon. When started, C will read it's configuration file to determine the network topology, and other configuration information, assuming the role of node I It will then create/connect to the tun/tap device and set up a socket for incoming connections. Then a C script will be executed to further configure the virtual network device. If that succeeds, it will detach from the controlling terminal and continue in the background, accepting and setting up connections to other gvpe daemons that are part of the same virtual private ethernet. The optional arguments after the node name have to be of the form: [I.]var=value If the argument has a prefix of C (i.e. C) then it will be parsed after all the config directives for that node, if not, it is parsed before the first node directive in the config file, and can be used to set global options or default variables. For example, to start C in the foreground, with log-level C on the node C, with TCP enabled and HTTP-Proxy host and Port set, use this: gvpe -D -l info laptop \ http-proxy-host=10.0.0.18 http-proxy-port=3128 \ laptop.enable-tcp=yes =head1 OPTIONS =over 4 =item B<-c>, B<--config=>I Read configuration options from I =item B<-d>, B<--l=>I Set logging level to I (one of: noise, trace, debug, info, notice, warn, error, critical). =item B<--help> Display short list of options. =item B<-D>, B<--no-detach> Don't fork and detach but stay in foreground and log messages to stderr in addition to syslog. =item B<-L>, B<--mlock> Lock C into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. =item B<--version> Output version information and exit. =back =head1 SIGNALS =over 4 =item HUP Closes/resets all connections, resets the retry time and will start connecting again (it will NOT re-read the config file). This is useful e.g. in a C script. =item TERM Closes/resets all connections and exits. =item USR1 Dump current network status into the syslog (at loglevel C, so make sure your loglevel allows this). =back =head1 FILES =over 4 =item C The configuration file for C. =item C Script which is executed as soon as the virtual network device has been allocated. Purpose is to further configure that device. =item C Script which is executed whenever a node connects to this node. This can be used for example to run nsupdate. =item C Script which is executed whenever a connection to another node is lost. for example to run nsupdate. =item C The directory containing the public keys for every node, one file per node with the name of the node. =item C The file containing the private key of the node GVPE runs on. Unlike all the other files in the F directory, this file usually differes for each node that GVPE runs on. =item C The PID of the currently running C is stored in this file. =back =head1 BUGS The cryptography in gvpe has not been thoroughly checked by many people yet. Use it at your own risk! If you find any bugs, report them to C. =head1 SEE ALSO gvpe(5) for an introduction, gvpe.conf(5), gvpectrl(8). The GVPE mailing list, at L or C. GVPE comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details. =head1 AUTHOR Marc Lehmann C<< >>. And thanks to many others for their contributions to gvpe, especially the tincd authors, who inspired me to write this program (after scavenging their source code ;). gvpe-3.0/doc/gvpectrl.8.pod0000644000000000000000000000452613006305645012462 00000000000000=head1 NAME C - GNU Virtual Private Ethernet Control Program =head1 SYNOPSIS C [B<-ckgs>] [B<--config=>I] [B<--generate-keys>] [B<--help>] [B<--kill>[B<=>I]] [B<--show-config>] [B<--version>] =head1 DESCRIPTION This is the control program for the C, the virtual private ethernet daemon. =head1 OPTIONS =over 4 =item B<-c>, B<--config=>I Read configuration options from I. =item B<-g>, B<--generate-key=path> Generates a single RSA key-pair. The public key will be stored in F<< I >> while the private key will be stored in F<< I .privkey >>. Neither file must be non-empty for this to succeed. The public key file F<< I >> is normally copied to F in the config directory on all nodes, while the private key F<< I.privkey >> should be copied to the file F on the node the key is for. It's recommended to generate the keypair on the node where it will be used, so that the private key file does not have to travel over the network. =item B<-G>, B<--generate-keys> Generate public/private RSA key-pairs for all nodes not having a key and exit. Note that in normal configurations this will fail, as there cna only be one private key per host. To make this configuration work you need to specify separate keyfiles for hostkeys in your config file, e.g.: private-key = hostkeys/%s Such a configuration makes it easier to distribute a configuration centrally but requires private keys to be transported securely over the network. =item B<-q>, B<--quiet> Suppresses messages the author finds nonessential for scripting purposes. =item B<--help> Display short list of options. =item B<--kill>[B<=>I] Attempt to kill a running C (optionally with the specified I instead of C) and exit. =item B<--show-config> Show a summary of the configuration, and how gvpe interprets it. Can also be very useful when designing firewall scripts. =item B<--version> Output version information and exit. =back =head1 BUGS If you find any bugs, report them to C. =head1 SEE ALSO gvpe(5), gvpe.conf(5), gvpe(8). GVPE comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details. =head1 AUTHOR Marc Lehmann C<< >>. gvpe-3.0/doc/gvpe.conf.5.pod0000644000000000000000000006524713006307060012516 00000000000000=head1 NAME gvpe.conf - configuration file for the GNU VPE daemon =head1 SYNOPSIS # global options for all nodes udp-port = 407 mtu = 1492 ifname = vpn0 # first node is named branch1 and is at 1.2.3.4 node = branch1 hostname = 1.2.3.4 # second node uses dns to resolve the address node = branch2 hostname = www.example.net udp-port = 500 # this host uses a different udp-port # third node has no fixed ip address node = branch3 connect = ondemand =head1 DESCRIPTION The gvpe config file consists of a series of lines that contain C pairs. Empty lines are ignored. Comments start with a C<#> and extend to the end of the line. They can be used on their own lines, or after any directives. Whitespace is allowed around the C<=> sign or after values, but not within the variable names or values themselves. All settings are applied "in order", that is, later settings of the same variable overwrite earlier ones. The only exceptions to the above are the following directives: =over 4 =item node nodename Introduces a node section. The nodename is used to select the right configuration section and is the same string as is passed as an argument to the gvpe daemon. Multiple C statements with the same node name are supported and will be merged together. =item global This statement switches back to the global section, which is mainly useful if you want to include a second config file, e..g for local customisations. To do that, simply include this at the very end of your config file: global include local.conf =item on nodename ... =item on !nodename ... You can prefix any configuration directive with C and a nodename. GVPE will will only "execute" it on the named node, or (if the nodename starts with C) on all nodes except the named one. Example: set the MTU to C<1450> everywhere, C to C on C, and C to C everywhere but on branch2. mtu = 1450 on branch1 loglevel = noise on !branch2 connect = ondemand =item include relative-or-absolute-path Reads the specified file (the path must not contain whitespace or C<=> characters) and evaluate all config directives in it as if they were spelled out in place of the C directive. The path is a printf format string, that is, you must escape any C<%> by doubling it, and you can have a single C<%s> inside, which will be replaced by the current nodename. Relative paths are interpreted relative to the GVPE config directory. Example: include the file F in the config directory on every node. include local.conf Example: include a file FnodenameF<.conf> include conf/%s.conf =back =head1 ANATOMY OF A CONFIG FILE Usually, a config file starts with a few global settings (like the UDP port to listen on), followed by node-specific sections that begin with a C line. Every node that is part of the network must have a section that starts with C. The number and order of the nodes is important and must be the same on all nodes. It is not uncommon for node sections to be completely empty - if the default values are right. Node-specific settings can be used at any time. If used before the first node section they will set the default values for all following nodes. =head1 CONFIG VARIABLES =head2 GLOBAL SETTINGS Global settings will affect the behaviour of the running gvpe daemon, that is, they are in some sense node-specific (config files can set different values on different nodes using C), but will affect the behaviour of the gvpe daemon and all connections it creates. =over 4 =item chroot = path or / Tells GVPE to chroot(2) to the specified path after reading all necessary files, binding to sockets and running the C script, but before running C or any other scripts. The special path F instructs GVPE to create (and remove) an empty temporary directory to use as new root. This is most secure, but makes it impossible to use any scripts other than the C one. =item chuid = numerical-uid =item chgid = numerical-gid These two options tell GVPE to change to the given user and/or group id after reading all necessary files, binding to sockets and running the C script. Other scripts, such as C, are run with the new user id or group id. =item chuser = username Alternative to C and C: Sets both C and C to the user and (primary) group ids of the specified user (for example, C). =item dns-forw-host = hostname/ip The DNS server to forward DNS requests to for the DNS tunnel protocol (default: C<127.0.0.1>, changing it is highly recommended). =item dns-forw-port = port-number The port where the C is to be contacted (default: C<53>, which is fine in most cases). =item dns-case-preserving = yes|true|on | no|false|off Sets whether the DNS transport forwarding server preserves case (DNS servers have to, but some access systems are even more broken than others) (default: true). Normally, when the forwarding server changes the case of domain names then GVPE will automatically set this to false. =item dns-max-outstanding = integer-number-of-requests The maximum number of outstanding DNS transport requests (default: C<100>). GVPE will never issue more requests then the given limit without receiving replies. In heavily overloaded situations it might help to set this to a low number (e.g. C<3> or even C<1>) to limit the number of parallel requests. The default should be working OK for most links. =item dns-overlap-factor = float The DNS transport uses the minimum request latency (B) seen during a connection as it's timing base. This factor (default: C<0.5>, must be > 0) is multiplied by B to get the maximum sending rate (= minimum send interval), i.e. a factor of C<1> means that a new request might be generated every B seconds, which means on average there should only ever be one outstanding request. A factor of C<0.5> means that GVPE will send requests twice as often as the minimum latency measured. For congested or picky DNS forwarders you could use a value nearer to or exceeding C<1>. The default should be working OK for most links. =item dns-send-interval = send-interval-in-seconds The minimum send interval (= maximum rate) that the DNS transport will use to send new DNS requests. GVPE will not exceed this rate even when the latency is very low. The default is C<0.01>, which means GVPE will not send more than 100 DNS requests per connection per second. For high-bandwidth links you could go lower, e.g. to C<0.001> or so. For congested or rate-limited links, you might want to go higher, say C<0.1>, C<0.2> or even higher. The default should be working OK for most links. =item dns-timeout-factor = float Factor to multiply the C (see C) by to get request timeouts. The default of C<8> means that the DNS transport will resend the request when no reply has been received for longer than eight times the minimum (= expected) latency, assuming the request or reply has been lost. For congested links a higher value might be necessary (e.g. C<30>). If the link is very stable lower values (e.g. C<2>) might work nicely. Values near or below C<1> makes no sense whatsoever. The default should be working OK for most links but will result in low throughput if packet loss is high. =item if-up = relative-or-absolute-path Sets the path of a script that should be called immediately after the network interface is initialized (but not necessarily up). The following environment variables are passed to it (the values are just examples). Variables that have the same value on all nodes: =over 4 =item CONFBASE=/etc/gvpe The configuration base directory. =item IFNAME=vpn0 The network interface to initialize. =item IFTYPE=native # or tincd =item IFSUBTYPE=linux # or freebsd, darwin etc.. The interface type (C or C) and the subtype (usually the OS name in lowercase) that this GVPE was configured for. Can be used to select the correct syntax to use for network-related commands. =item MTU=1436 The MTU to set the interface to. You can use lower values (if done consistently on all nodes), but this is usually either inefficient or simply ineffective. =item NODES=5 The number of nodes in this GVPE network. =back Variables that are node-specific and with values pertaining to the node running this GVPE: =over 4 =item IFUPDATA=string The value of the configuration directive C. =item MAC=fe:fd:80:00:00:01 The MAC address the network interface has to use. Might be used to initialize interfaces on platforms where GVPE does not do this automatically. Please see the C man page for platform-specific information. =item NODENAME=branch1 The nickname of the node. =item NODEID=1 The numerical node ID of the node running this instance of GVPE. The first node mentioned in the config file gets ID 1, the second ID 2 and so on. =back In addition, all node-specific variables (except C) will be available with a postfix of C<_nodeid>, which contains the value for that node, e.g. the C variable contains the MAC address of node #1, while the C variable contains the name of node #22. Here is a simple if-up script: #!/bin/sh ip link set $IFNAME up [ $NODENAME = branch1 ] && ip addr add 10.0.0.1 dev $IFNAME [ $NODENAME = branch2 ] && ip addr add 10.1.0.1 dev $IFNAME ip route add 10.0.0.0/8 dev $IFNAME More complicated examples (using routing to reduce ARP traffic) can be found in the F subdirectory of the distribution. =item ifname = devname Sets the tun interface name to the given name. The default is OS-specific and most probably something like C. =item ifpersist = yes|true|on | no|false|off Should the tun/tap device be made persistent, that is, should the device stay up even when gvpe exits? Some versions of the tunnel device have problems sending packets when gvpe is restarted in persistent mode, so if the connections can be established but you cannot send packets from the local node, try to set this to C and do an ifconfig down on the device. =item ip-proto = numerical-ip-protocol Sets the protocol number to be used for the rawip protocol. This is a global option because all nodes must use the same protocol, and since there are no port numbers, you cannot easily run more than one gvpe instance using the same protocol, nor can you share the protocol with other programs. The default is 47 (GRE), which has a good chance of tunneling through firewalls (but note that gvpe's rawip protocol is not GRE compatible). Other common choices are 50 (IPSEC, ESP), 51 (IPSEC, AH), 4 (IPIP tunnels) or 98 (ENCAP, rfc1241). Many versions of Linux seem to have a bug that causes them to reorder packets for some ip protocols (GRE, ESP) but not for others (AH), so choose wisely (that is, use 51, AH). =item http-proxy-host = hostname/ip The C family of options are only available if gvpe was compiled with the C<--enable-http-proxy> option and enable tunneling of tcp connections through a http proxy server. C and C should specify the hostname and port number of the proxy server. See C if your proxy requires authentication. Please note that gvpe will still try to resolve all hostnames in the configuration file, so if you are behind a proxy without access to a DNS server better use numerical IP addresses. To make best use of this option disable all protocols except TCP in your config file and make sure your routers (or all other nodes) are listening on a port that the proxy allows (443, https, is a common choice). If you have a router, connecting to it will suffice. Otherwise TCP must be enabled on all nodes. Example: http-proxy-host = proxy.example.com http-proxy-port = 3128 # 8080 is another common choice http-proxy-auth = schmorp:grumbeere =item http-proxy-port = proxy-tcp-port The port where your proxy server listens. =item http-proxy-auth = login:password The optional login and password used to authenticate to the proxy server, separated by a literal colon (C<:>). Only basic authentication is currently supported. =item keepalive = seconds Sets the keepalive probe interval in seconds (default: C<60>). After this many seconds of inactivity the daemon will start to send keepalive probe every 3 seconds until it receives a reply from the other end. If no reply is received within 15 seconds, the peer is considered unreachable and the connection is closed. =item loglevel = noise|trace|debug|info|notice|warn|error|critical Set the logging level. Connection established messages are logged at level C, notable errors are logged with C. Default is C. =item mtu = bytes Sets the maximum MTU that should be used on outgoing packets (basically the MTU of the outgoing interface) The daemon will automatically calculate maximum overhead (e.g. UDP header size, encryption blocksize...) and pass this information to the C script. Recommended values are 1500 (ethernet), 1492 (pppoe), 1472 (pptp). This value must be the minimum of the MTU values of all nodes. =item nfmark = integer This advanced option, when set to a nonzero value (default: C<0>), tries to set the netfilter mark (or fwmark) value on all sockets gvpe uses to send packets. This can be used to make gvpe use a different set of routing rules. For example, on GNU/Linux, the C could set C to 1000 and then put all routing rules into table C<99> and then use an ip rule to make gvpe traffic avoid that routing table, in effect routing normal traffic via gvpe and gvpe traffic via the normal system routing tables: ip rule add not fwmark 1000 lookup 99 =item node-up = relative-or-absolute-path Sets a command (default: none) that should be called whenever a connection is established (even on rekeying operations). Note that node-up/down scripts will be run asynchronously, but execution is serialised, so there will only ever be one such script running. In addition to all the variables passed to C scripts, the following environment variables will be set (values are just examples): =over 4 =item DESTNODE=branch2 The name of the remote node. =item DESTID=2 The node id of the remote node. =item DESTSI=rawip/88.99.77.55:0 The "socket info" of the target node, protocol dependent but usually in the format protocol/ip:port. =item DESTIP=188.13.66.8 The numerical IP address of the remote node (gvpe accepts connections from everywhere, as long as the other node can authenticate itself). =item DESTPORT=655 # deprecated The protocol port used by the other side, if applicable. =item STATE=up Node-up scripts get called with STATE=up, node-change scripts get called with STATE=change and node-down scripts get called with STATE=down. =back Here is a nontrivial example that uses nsupdate to update the name => ip mapping in some DNS zone: #!/bin/sh { echo update delete $DESTNODE.lowttl.example.net. a echo update add $DESTNODE.lowttl.example.net. 1 in a $DESTIP echo } | nsupdate -d -k $CONFBASE:key.example.net. =item node-change = relative-or-absolute-path Same as C, but gets called whenever something about a connection changes (such as the source IP address). =item node-down = relative-or-absolute-path Same as C, but gets called whenever a connection is lost. =item pid-file = path The path to the pid file to check and create (default: C). The first C<%s> is replaced by the nodename - any other use of C<%> must be written as C<%%>. =item private-key = relative-path-to-key Sets the path (relative to the config directory) to the private key (default: C). This is a printf format string so every C<%> must be doubled. A single C<%s> is replaced by the hostname, so you could use paths like C to be able to share the same config directory between nodes. Since only the private key file of the current node is used and the private key file should be kept secret per-node to avoid spoofing, it is not recommended to use this feature this way though. =item rekey = seconds Sets the rekeying interval in seconds (default: C<3607>). Connections are reestablished every C seconds, making them use a new encryption key. =item seed-device = path The random device used to initially and regularly seed the random number generator (default: F). Randomness is of paramount importance to the security of the algorithms used in gvpe. On program start and every seed-interval, gvpe will read 64 octets. Setting this path to the empty string will disable this functionality completely (the underlying crypto library will likely look for entropy sources on it's own though, so not all is lost). =item seed-interval = seconds The number of seconds between reseeds of the random number generator (default: C<3613>). A value of C<0> disables this regular reseeding. =item serial = string The configuration serial number. This can be any string up to 16 bytes length. Only when the serial matches on both sides of a conenction will the connection succeed. This is I a security mechanism and eay to spoof, this mechanism exists to alert users that their config is outdated. It's recommended to specify this is a date string such as C<2013-05-05> or C<20121205084417>. The exact algorithm is as this: if a connection request is received form a node with an identical serial, then it succeeds normally. If the remote serial is lower than the local serial, it is ignored. If the remote serial is higher than the local serial, a warning message is logged. =back =head2 NODE SPECIFIC SETTINGS The following settings are node-specific, that is, every node can have different settings, even within the same gvpe instance. Settings that are set before the first node section set the defaults, settings that are set within a node section only apply to the given node. =over 4 =item allow-direct = nodename Allow direct connections to this node. See C for more info. =item compress = yes|true|on | no|false|off For the current node, this specified whether it will accept compressed packets, and for all other nodes, this specifies whether to try to compress data packets sent to this node (default: C). Compression is really cheap even on slow computers, has no size overhead at all and will only be used when the other side supports compression, so enabling this is often a good idea. =item connect = ondemand | never | always | disabled Sets the connect mode (default: C). It can be C (always try to establish and keep a connection to the given node), C (never initiate a connection to the given host, but accept connections), C (try to establish a connection when there are outstanding packets in the queue and take it down after the keepalive interval) or C (node is bad, don't talk to it). Routers will automatically be forced to C unless they are C, to ensure all nodes can talk to each other. =item deny-direct = nodename | * Deny direct connections to the specified node (or all nodes when C<*> is given). Only one node can be specified, but you can use multiple C and C statements. This only makes sense in networks with routers, as routers are required for indirect connections. Sometimes, a node cannot reach some other nodes for reasons of network connectivity. For example, a node behind a firewall that only allows connections to/from a single other node in the network. In this case one should specify C and C (the other node I be a router for this to work). The algorithm to check whether a connection may be direct is as follows: 1. Other node mentioned in an C? If yes, allow the connection. 2. Other node mentioned in a C? If yes, deny direct connections. 3. Allow the connection. That is, C takes precedence over C. The check is done in both directions, i.e. both nodes must allow a direct connection before one is attempted, so you only need to specify connect limitations on one node. =item dns-domain = domain-suffix The DNS domain suffix that points to the DNS tunnel server for this node. The domain must point to a NS record that points to the I, i.e. dns-domainname = tunnel.example.net dns-hostname = tunnel-server.example.net Corresponds to the following DNS entries in the C domain: tunnel.example.net. NS tunnel-server.example.net. tunnel-server.example.net. A 13.13.13.13 =item dns-hostname = hostname/ip The address to bind the DNS tunnel socket to, similar to the C, but for the DNS tunnel protocol only. Default: C<0.0.0.0>, but that might change. =item dns-port = port-number The port to bind the DNS tunnel socket to. Must be C<53> on DNS tunnel servers. =item enable-dns = yes|true|on | no|false|off See gvpe.protocol(7) for a description of the DNS transport protocol. Avoid this protocol if you can. Enable the DNS tunneling protocol on this node, either as server or as client. Support for this transport protocol is only available when gvpe was compiled using the C<--enable-dns> option. =item enable-icmp = yes|true|on | no|false|off See gvpe.protocol(7) for a description of the ICMP transport protocol. Enable the ICMP transport using ICMP packets of type C on this node. =item enable-rawip = yes|true|on | no|false|off See gvpe.protocol(7) for a description of the RAW IP transport protocol. Enable the RAW IPv4 transport using the C protocol (default: C). =item enable-tcp = yes|true|on | no|false|off See gvpe.protocol(7) for a description of the TCP transport protocol. Enable the TCPv4 transport using the C port (default: C). Support for this transport protocol is only available when gvpe was compiled using the C<--enable-tcp> option. =item enable-udp = yes|true|on | no|false|off See gvpe.protocol(7) for a description of the UDP transport protocol. Enable the UDPv4 transport using the C port (default: C). =item hostname = hostname | ip [can not be defaulted] Forces the address of this node to be set to the given DNS hostname or IP address. It will be resolved before each connect request, so dyndns should work fine. If this setting is not specified and a router is available, then the router will be queried for the address of this node. Otherwise, the connection attempt will fail. Note that DNS resolving is done synchronously, pausing the daemon. If that is an issue you need to specify IP addresses. =item icmp-type = integer Sets the type value to be used for outgoing (and incoming) packets sent via the ICMP transport. The default is C<0> (which is C, also known as "ping-reply"). Other useful values include C<8> (C, a.k.a. "ping") and C<11> (C), but any 8-bit value can be used. =item if-up-data = value The value specified using this directive will be passed to the C script in the environment variable C. =item inherit-tos = yes|true|on | no|false|off Whether to inherit the TOS settings of packets sent to the tunnel when sending packets to this node (default: C). If set to C then outgoing tunnel packets will have the same TOS setting as the packets sent to the tunnel device, which is usually what you want. =item low-power = yes|true|on | no|false|off If true, designates a node as a low-power node. Low-power nodes use larger timeouts and try to reduce cpu time. Other nodes talking to a low-power node will also use larger timeouts, and will use less aggressive optimisations, in the hope of reducing load. Security is not compromised. The typical low-power node would be a mobile phone, where wakeups and encryption can significantly increase power drain. =item max-retry = positive-number The maximum interval in seconds (default: C<3600>, one hour) between retries to establish a connection to this node. When a connection cannot be established, gvpe uses exponential back-off capped at this value. It's sometimes useful to set this to a much lower value (e.g. C<120>) on connections to routers that usually are stable but sometimes are down, to assure quick reconnections even after longer downtimes. =item max-ttl = seconds Expire packets that couldn't be sent after this many seconds (default: C<60>). Gvpe will normally queue packets for a node without an active connection, in the hope of establishing a connection soon. This value specifies the maximum lifetime a packet will stay in the queue, if a packet gets older, it will be thrown away. =item max-queue = positive-number>=1 The maximum number of packets that will be queued (default: C<512>) for this node. If more packets are sent then earlier packets will be expired. See C, above. =item router-priority = 0 | 1 | positive-number>=2 Sets the router priority of the given node (default: C<0>, disabled). If some node tries to connect to another node but it doesn't have a hostname, it asks a router node for it's IP address. The router node chosen is the one with the highest priority larger than C<1> that is currently reachable. This is called a I connection, as the connection itself will still be direct, but it uses another node to mediate between the two nodes. The value C<0> disables routing, that means if the node receives a packet not for itself it will not forward it but instead drop it. The special value C<1> allows other hosts to route through the router host, but they will never route through it by default (i.e. the config file of another node needs to specify a router priority higher than one to choose such a node for routing). The idea behind this is that some hosts can, if required, bump the C setting to higher than C<1> in their local config to route through specific hosts. If C is C<0>, then routing will be refused, so C<1> serves as a "enable, but do not use by default" switch. Nodes with C set to C<2> or higher will always be forced to C = C (unless they are C). =item tcp-port = port-number Similar to C (default: C<655>), but sets the TCP port number. =item udp-port = port-number Sets the port number used by the UDP protocol (default: C<655>, not officially assigned by IANA!). =back =head1 CONFIG DIRECTORY LAYOUT The default (or recommended) directory layout for the config directory is: =over 4 =item gvpe.conf The config file. =item if-up The if-up script =item node-up, node-down If used the node up or node-down scripts. =item hostkey The (default path of the) private key of the current host. =item pubkey/nodename The public keys of the other nodes, one file per node. =back =head1 SEE ALSO gvpe(5), gvpe(8), gvpectrl(8). =head1 AUTHOR Marc Lehmann gvpe-3.0/doc/gvpe.protocol.7.pod0000644000000000000000000002756612615056110013440 00000000000000=head1 The GNU-VPE Protocols =head1 Overview GVPE can make use of a number of protocols. One of them is the GNU VPE protocol which is used to authenticate tunnels and send encrypted data packets. This protocol is described in more detail the second part of this document. The first part of this document describes the transport protocols which are used by GVPE to send its data packets over the network. =head1 PART 1: Transport protocols GVPE offers a wide range of transport protocols that can be used to interchange data between nodes. Protocols differ in their overhead, speed, reliability, and robustness. The following sections describe each transport protocol in more detail. They are sorted by overhead/efficiency, the most efficient transport is listed first: =head2 RAW IP This protocol is the best choice, performance-wise, as the minimum overhead per packet is only 38 bytes. It works by sending the VPN payload using raw IP frames (using the protocol set by C). Using raw IP frames has the drawback that many firewalls block "unknown" protocols, so this transport only works if you have full IP connectivity between nodes. =head2 ICMP This protocol offers very low overhead (minimum 42 bytes), and can sometimes tunnel through firewalls when other protocols can not. It works by prepending an ICMP header with type C and a code of C<255>. The default C is C, so the resulting packets look like echo replies, which looks rather strange to network administrators. This transport should only be used if other transports (i.e. raw IP) are not available or undesirable (due to their overhead). =head2 UDP This is a good general choice for the transport protocol as UDP packets tunnel well through most firewalls and routers, and the overhead per packet is moderate (minimum 58 bytes). It should be used if RAW IP is not available. =head2 TCP This protocol is a very bad choice, as it not only has high overhead (more than 60 bytes), but the transport also retries on its own, which leads to congestion when the link has moderate packet loss (as both the TCP transport and the tunneled traffic will retry, increasing congestion more and more). It also has high latency and is quite inefficient. It's only useful when tunneling through firewalls that block better protocols. If a node doesn't have direct internet access but a HTTP proxy that supports the CONNECT method it can be used to tunnel through a web proxy. For this to work, the C should be C<443> (C), as most proxies do not allow connections to other ports. It is an abuse of the usage a proxy was designed for, so make sure you are allowed to use it for GVPE. This protocol also has server and client sides. If the C is set to zero, other nodes cannot connect to this node directly. If the C is non-zero, the node can act both as a client as well as a server. =head2 DNS B Parsing and generating DNS packets is rather tricky. The code almost certainly contains buffer overflows and other, likely exploitable, bugs. You have been warned. This is the worst choice of transport protocol with respect to overhead (overhead can be 2-3 times higher than the transferred data), and latency (which can be many seconds). Some DNS servers might not be prepared to handle the traffic and drop or corrupt packets. The client also has to constantly poll the server for data, so the client will constantly create traffic even if it doesn't need to transport packets. In addition, the same problems as the TCP transport also plague this protocol. Its only use is to tunnel through firewalls that do not allow direct internet access. Similar to using a HTTP proxy (as the TCP transport does), it uses a local DNS server/forwarder (given by the C configuration value) as a proxy to send and receive data as a client, and an C record pointing to the GVPE server (as given by the C directive). The only good side of this protocol is that it can tunnel through most firewalls mostly undetected, iff the local DNS server/forwarder is sane (which is true for most routers, wireless LAN gateways and nameservers). Fine-tuning needs to be done by editing C directly. =head1 PART 2: The GNU VPE protocol This section, unfortunately, is not yet finished, although the protocol is stable (until bugs in the cryptography are found, which will likely completely change the following description). Nevertheless, it should give you some overview over the protocol. =head2 Anatomy of a VPN packet The exact layout and field lengths of a VPN packet is determined at compile time and doesn't change. The same structure is used for all transport protocols, be it RAWIP or TCP. +------+------+--------+------+ | HMAC | TYPE | SRCDST | DATA | +------+------+--------+------+ The HMAC field is present in all packets, even if not used (e.g. in auth request packets), in which case it is set to all zeroes. The MAC itself is calculated over the TYPE, SRCDST and DATA fields in all cases. The TYPE field is a single byte and determines the purpose of the packet (e.g. RESET, COMPRESSED/UNCOMPRESSED DATA, PING, AUTH REQUEST/RESPONSE, CONNECT REQUEST/INFO etc.). SRCDST is a three byte field which contains the source and destination node IDs (12 bits each). The DATA portion differs between each packet type, naturally, and is the only part that can be encrypted. Data packets contain more fields, as shown: +------+------+--------+-------+------+ | HMAC | TYPE | SRCDST | SEQNO | DATA | +------+------+--------+-------+------+ SEQNO is a 32-bit sequence number. It is negotiated at every connection initialization and starts at some random 31 bit value. GVPE currently uses a sliding window of 512 packets/sequence numbers to detect reordering, duplication and replay attacks. The encryption is done on SEQNO+DATA in CTR mode with IV generated from the seqno (for AES: seqno || seqno || seqno || (u32)0), which ensures uniqueness for a given key. =head2 The authentication/key exchange protocol Before nodes can exchange packets, they need to establish authenticity of the other side and a key. Every node has a private RSA key and the public RSA keys of all other nodes. When a node wants to establish a connection to another node, it sends an RSA-OEAP-encrypted challenge and an ECDH (curve25519) key. The other node replies with its own ECDH key and a HKDF of the challenge and both ECDH keys to prove its identity. The remote node enganges in exactly the same protocol. When both nodes have exchanged their challenge and verified the response, they calculate a cipher key and a HMAC key and start exchanging data packets. In detail, the challenge consist of: RSA-OAEP (SEQNO MAC CIPHER SALT EXTRA-AUTH) ECDH1 That is, it encrypts (with the public key of the remote node) an initial sequence number for data packets, key material for the HMAC key, key material for the cipher key, a salt used by the HKDF (as shown later) and some extra random bytes that are unused except for authentication. It also sends the public key of a curve25519 exchange. The remote node decrypts the RSA data, generates its own ECDH key (ECDH2), and replies with: HKDF-Expand (HKDF-Extract (ECDH2, RSA), ECDH1, AUTH_DIGEST_SIZE) ECDH2 That is, it extracts from the decrypted RSA challenge, using its ECDH key as salt, and then expands using the requesting node's ECDH1 key. The resulting hash is returned as a proof that the node could decrypt the RSA challenge data, together with the ECDH key. After both nodes have done this to each other, they calculate the shared ECDH secret, cipher and HMAC keys for the session (each node generates two cipher and HMAC keys, one for sending and one for receiving). The HMAC key for sending is generated as follow: HMAC_KEY = HKDF-Expand (HKDF-Extract (REMOTE_SALT, MAC ECDH_SECRET), info, HMAC_MD_SIZE) It extracts from MAC and ECDH_SECRET using the I SALT, then expands using a static info string. The cipher key is generated in the same way, except using the CIPHER part of the original challenge. The result of this process is to authenticate each node to the other node, while exchanging keys using both RSA and ECDH, the latter providing perfect forward secrecy. The protocol has been overdesigned where this was possible without increasing implementation complexity, in an attempt to protect against implementation or protocol failures. For example, if the ECDH challenge was found to be flawed, perfect forward secrecy would be lost, but the data would likely still be protected. Likewise, standard algorithms and implementations are used where possible. =head2 Retrying When there is no response to an auth request, the node will send auth requests in bursts with an exponential back-off. After some time it will resort to PING packets, which are very small (8 bytes + protocol header) and lightweight (no RSA operations required). A node that receives ping requests from an unconnected peer will respond by trying to create a connection. In addition to the exponential back-off, there is a global rate-limit on a per-IP base. It allows long bursts but will limit total packet rate to something like one control packet every ten seconds, to avoid accidental floods due to protocol problems (like a RSA key file mismatch between two nodes). The intervals between retries are limited by the C configuration value. A node with C = C will always retry, a node with C = C will only try (and re-try) to connect as long as there are packets in the queue, usually this limits the retry period to C seconds. Sending packets over the VPN will reset the retry intervals as well, which means as long as somebody is trying to send packets to a given node, GVPE will try to connect every few seconds. =head2 Routing and Protocol translation The GVPE routing algorithm is easy: there isn't much routing to speak of: When routing packets to another node, GVPE tries the following options, in order: =over 4 =item If the two nodes should be able to reach each other directly (common protocol, port known), then GVPE will send the packet directly to the other node. =item If this isn't possible (e.g. because the node doesn't have a C or known port), but the nodes speak a common protocol and a router is available, then GVPE will ask a router to "mediate" between both nodes (see below). =item If a direct connection isn't possible (no common protocols) or forbidden (C) and there are any routers, then GVPE will try to send packets to the router with the highest priority that is connected already I is able (as specified by the config file) to connect directly to the target node. =item If no such router exists, then GVPE will simply send the packet to the node with the highest priority available. =item Failing all that, the packet will be dropped. =back A host can usually declare itself unreachable directly by setting its port number(s) to zero. It can declare other hosts as unreachable by using a config-file that disables all protocols for these other hosts. Another option is to disable all protocols on that host in the other config files. If two hosts cannot connect to each other because their IP address(es) are not known (such as dial-up hosts), one side will send a I connection request to a router (routers must be configured to act as routers!), which will send both the originating and the destination host a connection info request with protocol information and IP address of the other host (if known). Both hosts will then try to establish a direct connection to the other peer, which is usually possible even when both hosts are behind a NAT gateway. Routing via other nodes works because the SRCDST field is not encrypted, so the router can just forward the packet to the destination host. Since each host uses its own private key, the router will not be able to decrypt or encrypt packets, it will just act as a simple router and protocol translator. gvpe-3.0/doc/gvpe.osdep.5.pod0000644000000000000000000001504012615056110012667 00000000000000=head1 NAME gvpe.osdep - os dependent information =head1 DESCRIPTION This file tries to capture OS-dependent configuration or build issues, quirks and platform limitations, as known. =head1 TUN vs. TAP interface Most operating systems nowadays support something called a I-device, which makes it possible to divert IPv4 (and often other protocols, too) into a user space daemon like C. This is being referred to as a TUN-device. This is fine for point-to-point tunnels, but for a virtual ethernet, an additional ethernet header is needed. This functionality (called a TAP device here) is only provided by a subset of the configurations. On platforms only supporting a TUN-device, gvpe will invoke it's magical ethernet emulation package, which currently only handles ARP requests for the IPv4 protocol (but more could be added, bu the tincd network drivers might need to be modified for this to work). This means that on those platforms, only IPv4 will be supported. Also, since there is no way (currently) to tell gvpe which IP subnets are found on a specific host, you will either need to hardwire the MAC address for TUN-style hosts on all networks (and avoid ARP altogether, which is possible), or you need to send a packet from these hosts into the vpn network to tell gvpe the local interface address. =head1 Interface Initialisation Unless otherwise notes, the network interface will be initialized with the expected MAC address and correct MTU value. With most interface drivers, this is done by running C, so make sure that this command exists. =head1 Interface Types =head2 native/linux TAP-device; already part of the kernel (only 2.4+ supported, but see tincd/linux). This is the configuration tested best, as gvpe is being developed on this platform. C should be set to the name of the network device. To hardwire ARP addresses, use iproute2 (C can do it, too): MAC=fe:fd:80:00:00:$(printf "%02x" $NODEID) ip neighbour add 10.11.12.13 lladdr $MAC nud permanent dev $IFNAME =head2 tincd/linux TAP-device; already part of the kernel (2.2 only). See C for more info. C should be set to the path of a tap device, e.g. C. The interface will be named accordingly. =head2 native/cygwin TAP-device; The TAP device to be used must either be the CIPE driver (C), or (highly recommended) the newer TAP-Win32 driver bundled with openvpn (http://openvpn.sf.net/). Just download and run the openvpn installer. The only option you need to select is the TAP driver. C should be set to the name of the device, found in the registry at (no kidding :): HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\\Connection\Name The MAC address is dynamically being patched into packets and ARP-requests, so only IPv4 works with ARP on this platform. =head2 tincd/bsd TAP-device, maybe; migth work for many bsd variants. This driver is a newer version of the C drivers. It I provide a TAP device, or might not work at all. You might try this interface type first, and, if it doesn't work, try one of the OS-specific drivers. =head2 tincd/freebsd TAP-device; part of the kernel (since 4.x, maybe earlier). C should be set to the path of a tap device, e.g. C. The interface will be named accordingly. These commands might be helpful examples: ifconfig $IFNAME 10.0.0.$NODEID route add -net 10.0.0.0 -netmask 255.255.255.0 -interface $IFNAME 10.0.0.$NODEID =head2 tincd/netbsd TUN-device; The interface is a point-to-point device. To initialize it, you currently need to configure it as a point-to-point device, giving it an address on your vpn (the exact address doesn't matter), like this: ifconfig $IFNAME mtu $MTU up ifconfig $IFNAME 10.11.12.13 10.55.66.77 route add -net 10.0.0.0 10.55.66.77 255.0.0.0 ping -c1 10.55.66.77 # ping once to tell gvpe your gw ip The ping is required to tell the ARP emulator inside GVPE the local IP address. C should be set to the path of a tun device, e.g. C. The interface will be named accordingly. =head2 tincd/openbsd TUN-device; already part of the kernel. See C for more information. =head2 native/darwin TAP-device; The necessary kernel extension can be found here: http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ There are two drivers, the one to use is the "tap" driver. It driver must be loaded before use, read the docs on how to install it as a startup item. C should be set to the path of a tap device, e.g. C. The interface will be named accordingly. These commands might be helpful examples: ifconfig $IFNAME 10.0.0.$NODEID route add -net 10.0.0.0 -interface $IFNAME 255.255.255.0 =head2 tincd/darwin TUN-device; See C for more information. C is preferable. The necessary kernel extension can be found here: http://chrisp.de/en/projects/tunnel.html C should be set to the path of a tun device, e.g. C. The interface will be named accordingly. The driver must be loaded before use: kmodload tunnel =head2 tincd/solaris TUN-device; already part of the kernel(?), or available here: http://vtun.sourceforge.net/tun/ Some precompiled tun drivers might be available here: http://www.monkey.org/~dugsong/fragroute/ The interface MAC and MTU are I set up for you. Please try it out and send me an C command invocation that does that. See C for more information. Completely untested so far. =head2 tincd/mingw TAP-device; see C for more information. The setup is likely to be similar to C. Completely untested so far. =head2 tincd/raw_socket TAP-device; purpose unknown and untested, probably binds itself on an existing ethernet device (given by C). It must be down prior to running the command, and GVPE will try to set it's MAC address and MTU to the "correct" values. Completely untested so far. =head2 tincd/uml_socket TAP-device; purpose unknown and untested, probably creates a UNIX datagram socket (path given by C) and reads and writes raw packets, so might be useful in other than UML contexts. No network interface is created, and the MAC and MTU must be set as appropriate on the other side of the socket. GVPE will exit if the MAC address doesn't match what it expects. Completely untested so far. =head2 tincd/cygwin Known to be broken, use C instead. =head1 SEE ALSO gvpe(5). =head1 AUTHOR Marc Lehmann