Description: Add support for kFreeBSD
 The configure script should check for available features of the host instead
 of assuming that specific hosts (e.g. Linux) have specific features.
 .
 This patch hacks the configure script and various source files to behave
 on kFreeBSD similar to Linux.
Author: Benjamin Drung <benjamin.drung@profitbricks.com>

--- a/configure.ac
+++ b/configure.ac
@@ -569,6 +569,46 @@ case $host in
     AC_SUBST([LIBCRYPT], [$LIBCRYPT])
     AC_DEFINE([USE_POSIX_RWLOCKS], [1], [POSIX rwlocks])
     ;;
+  *-*-kfreebsd*)
+    dnl Assume that BSD has the getpeereid() function.
+    dnl TODO: Check for the existance of the getpeereid() function!
+    AC_DEFINE([HAVE_GETPEEREID], [1], [have getpeereid])
+    dnl Check if we need to link against the bsd library for the getpeereid() function.
+    AC_SEARCH_LIBS([getpeereid], [bsd])
+    dnl Copied stuff from Linux section above
+    dnl TODO: Check for features instead of setting flags based on the host!
+    AC_DEFINE([XP_UNIX], [1], [UNIX])
+    AC_DEFINE([freebsd], [1], [freebsd])
+    AC_DEFINE([_GNU_SOURCE], [1], [GNU Source])
+    initdir='$(sysconfdir)/rc.d/init.d'
+    # do arch specific kfreebsd stuff here
+    case $host in
+      i*86-*-linux*)
+        AC_DEFINE([CPU_x86], [], [cpu type x86])
+        AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
+        ;;
+      x86_64-*-linux*)
+        AC_DEFINE([CPU_x86_64], [], [cpu type x86_64])
+        AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
+        ;;
+    esac
+    AC_MSG_CHECKING([for GCC provided 64-bit atomic bool cas function ...])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+                                    [[long long ptrval = 0, val = 0, newval = 1; (void)__sync_bool_compare_and_swap_8(&ptrval, val, newval);]])],
+                   [AC_DEFINE([HAVE_64BIT_ATOMIC_CAS_FUNC], [1], [have 64-bit atomic bool compare and swap function provided by gcc])AC_MSG_RESULT([yes])],
+                   [AC_MSG_RESULT([no])])
+    AC_MSG_CHECKING([for GCC provided 64-bit atomic ops functions ...])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+                                    [[long long ptrval = 0, val = 0; (void)__sync_add_and_fetch_8(&ptrval, val);]])],
+                   [AC_DEFINE([HAVE_64BIT_ATOMIC_OP_FUNCS], [1], [have 64-bit atomic operation functions provided by gcc])AC_MSG_RESULT([yes])],
+                   [AC_MSG_RESULT([no])])
+    # some programs use the native thread library directly
+    THREADLIB=-lpthread
+    AC_SUBST([THREADLIB], [$THREADLIB])
+    LIBCRYPT=-lcrypt
+    AC_SUBST([LIBCRYPT], [$LIBCRYPT])
+    AC_DEFINE([USE_POSIX_RWLOCKS], [1], [POSIX rwlocks])
+    ;;
   ia64-hp-hpux*)
     AC_DEFINE([hpux], [1], [HP-UX])
     AC_DEFINE([HPUX], [1], [HP-UX])
--- a/include/base/systems.h
+++ b/include/base/systems.h
@@ -62,7 +62,7 @@
 /* warning: mmap doesn't work under 9.04 */
 #define SHMEM_MMAP_FLAGS MAP_FILE | MAP_VARIABLE | MAP_SHARED
 
-#elif defined(Linux)
+#elif defined(Linux) || defined(freebsd)
 
 #define ACCELERATOR_CACHE
 #define DNS_CACHE
--- a/include/public/base/systems.h
+++ b/include/public/base/systems.h
@@ -56,7 +56,7 @@
 #define SHMEM_UNIX_MMAP
 #define ZERO(ptr,len) memset(ptr,0,len)
 
-#elif defined(Linux)
+#elif defined(Linux) || defined(freebsd)
 
 #define FILE_UNIX
 #define FILE_UNIX_MMAP
--- a/ldap/include/portable.h
+++ b/ldap/include/portable.h
@@ -250,7 +250,7 @@ int strncasecmp(const char *, const char
     defined(UNIXWARE) || defined(SUNOS4) || defined(SNI) || defined(BSDI) || \
     defined(NCR) || defined(OSF1) || defined(NEC) || \
     ( defined(HPUX10) && !defined(_REENTRANT)) || defined(HPUX11) || \
-    defined(UnixWare) || defined(LINUX2_0)
+    defined(UnixWare) || defined(LINUX2_0) || defined(freebsd)
 #define GETHOSTBYNAME( n, r, b, l, e )  gethostbyname( n )
 #elif defined(AIX)
 #define GETHOSTBYNAME_BUF_T struct hostent_data
@@ -288,7 +288,7 @@ typedef char GETHOSTBYADDR_buf_t [BUFSIZ
 #elif defined( hpux10 )
 #define CTIME( c, b, l )		nsldapi_compat_ctime_r( c, b, l )
 #elif defined( IRIX ) || defined(UNIXWARE) || defined(LINUX) \
-	|| defined(OSF1V4) || defined(AIX) || defined(UnixWare) || defined (HPUX11)
+	|| defined(OSF1V4) || defined(AIX) || defined(UnixWare) || defined (HPUX11) || defined(freebsd)
 #define CTIME( c, b, l )                ctime_r( c, b )
 #elif defined( OSF1V3 )
 #define CTIME( c, b, l )		(ctime_r( c, b, l ) ? NULL : b)
@@ -297,7 +297,7 @@ typedef char GETHOSTBYADDR_buf_t [BUFSIZ
 #endif
 #if defined(hpux9) || defined(LINUX1_2) || defined(SUNOS4) || defined(SNI) || \
     defined(SCOOS) || defined(BSDI) || defined(NCR) || \
-    defined(NEC) || defined(LINUX2_0)
+    defined(NEC) || defined(LINUX2_0) || defined(freebsd)
 /* strtok() is not MT safe, but it is okay to call here because used in mmt_protocol.xs which 
    has been moved in the tetframewrok */
 #define STRTOK( s1, s2, l )		strtok( s1, s2 )
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -38,7 +38,7 @@
 #endif /* NEED_FILIO */
 /* for some reason, linux tty stuff defines CTIME */
 #include <stdio.h>
-#ifdef LINUX
+#if defined(LINUX) || defined(freebsd)
 #undef CTIME
 #include <sys/statfs.h>
 #else
@@ -380,7 +380,7 @@ disk_mon_get_dirs(char ***list, int logs
 char *
 disk_mon_check_diskspace(char **dirs, PRUint64 threshold, PRUint64 *disk_space)
 {
-#ifdef LINUX
+#if defined(LINUX) || defined(freebsd)
     struct statfs buf;
 #else
     struct statvfs buf;
@@ -393,7 +393,7 @@ disk_mon_check_diskspace(char **dirs, PR
     int i = 0;
 
     for(i = 0; dirs && dirs[i]; i++){
-#ifndef LINUX
+#if !defined(LINUX) && !defined(freebsd)
         if (statvfs(dirs[i], &buf) != -1)
 #else
         if (statfs(dirs[i], &buf) != -1)
--- a/ldap/servers/slapd/tools/pwenc.c
+++ b/ldap/servers/slapd/tools/pwenc.c
@@ -16,7 +16,7 @@
 #include <sys/errno.h>
 #include <sys/param.h>
 #include <sys/types.h>
-#if defined(LINUX) /* I bet other Unix would like
+#if defined(LINUX) || defined(freebsd) /* I bet other Unix would like
 					* this flag. But don't want to
 					* break other builds so far */
 #include <unistd.h>
--- a/ldap/systools/idsktune.c
+++ b/ldap/systools/idsktune.c
@@ -17,6 +17,11 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 static char *build_date = "23-FEBRUARY-2012";
 
+#if defined(freebsd)
+#define IDDS_BSD_INCLUDE 1
+#define IDDS_BSD_SYSCTL 1
+#endif
+
 #if defined(linux) || defined(__linux) || defined(__linux__)
 #define IDDS_LINUX_INCLUDE 1
 #define IDDS_LINUX_SYSCTL 1
--- a/lib/base/dnsdmain.cpp
+++ b/lib/base/dnsdmain.cpp
@@ -35,12 +35,12 @@ extern "C" {
 #define _PATH_RESCONF "/etc/resolv.conf"
 
 NSPR_BEGIN_EXTERN_C
-#ifdef Linux
+#if defined Linux || defined(freebsd)
 extern int getdomainname(char *, size_t);
 #else 
 extern int getdomainname(char *, int);
 #endif /* Linux */
-#if defined(HPUX) || defined(Linux) || defined(SOLARIS_GCC)
+#if defined(HPUX) || defined(Linux) || defined(SOLARIS_GCC) || defined(freebsd)
 extern int gethostname (char *name, size_t namelen);
 #else
 extern int gethostname (char *name, int namelen);
--- a/lib/base/file.cpp
+++ b/lib/base/file.cpp
@@ -214,7 +214,7 @@ NSAPI_PUBLIC int file_notfound(void)
     return (errno == ENOENT);
 }
 
-#if !defined(LINUX)
+#if !defined(LINUX) && !defined(freebsd)
 extern char *sys_errlist[];
 #endif
 
