[OpenIndiana-discuss] Milter-Greylist for OpenIndiana+Postfix?

Jim Klimov jimklimov at cos.ru
Sun Mar 3 14:23:31 UTC 2013


On 2013-03-03 13:15, Hans J. Albertsson wrote:
> And I can answer that myself: there are several implementations, some in
> perl, and it's probably a no-brainer.

I am a long-time user of milter-greylist, and worked in January to have
it compile under a number of Solarises - tested to build with OI also.

Part of my fixes were integrated into a published tarball (Jan 8 2013),
and some stalled on the mailing list awaiting more approval/disproval
comments.

 From my mails at that time:

---

Some changes are published as a 4.4.2 tarball, and some newer ones
should be in main repo. Just in case, I post my fixes (4.4.1->4.4.2
and beyond) so that you can hopefully compile with less hassle than
I've had. With the last one regarding make, Manu had same uneasiness
as myself and suggested I do post on the mail-list with that one.

And if you do still have solaris build/config troubles - keep the
list posted.

Also attached is a build fix for p0f - I've tried to get most of the
features provided by milter-greylist this time (didn't try to add
only drac and dkim), and the p0f daemon didn't want to build too.

I'm just past the builds and packaging, now converting my older
milter configs - so I have little idea if this all works in fact ;)

---

I hope the attachments pass this mailing list - otherwise search
their mailing list archive for my posts from January this year.

HTH,
//Jim Klimov

-------------- next part --------------
diff -Naur milter-greylist-4.4.1-orig/config.h.in milter-greylist-4.4.1/config.h.in
--- milter-greylist-4.4.1-orig/config.h.in	2010-05-22 23:30:16.000000000 +0400
+++ milter-greylist-4.4.1/config.h.in	2013-01-07 01:17:49.543105286 +0400
@@ -18,6 +18,9 @@
 /* Define to 1 if you have the `bzero' function. */
 #undef HAVE_BZERO
 
+/* Define to 1 if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
@@ -109,6 +112,9 @@
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
+/* Define to 1 if you have the `strcasestr' function. */
+#undef HAVE_STRCASESTR
+
 /* Define to 1 if you have the `strerror' function. */
 #undef HAVE_STRERROR
 
diff -Naur milter-greylist-4.4.1-orig/configure.ac milter-greylist-4.4.1/configure.ac
--- milter-greylist-4.4.1-orig/configure.ac	2012-10-19 08:00:12.000000000 +0400
+++ milter-greylist-4.4.1/configure.ac	2013-01-07 01:17:22.102074713 +0400
@@ -96,11 +96,13 @@
 	[CFLAGS=$CFLAGS" -I$withval/include -DUSE_LDAP -DLDAP_DEPRECATED" 
 	    LIBS="-lldap_r -llber $LIBS"
 	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"])
+use_libcurl=no
 AC_ARG_WITH(libcurl, 
 	[  --with-libcurl=DIR  Find libcurl in DIR],
 	[CFLAGS=$CFLAGS" -I$withval/include -DUSE_CURL" 
 	    LIBS="-lcurl $LIBS"
-	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"])
+	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"
+	    use_libcurl=yes])
 AC_ARG_WITH(libGeoIP, 
 	[  --with-libGeoIP=DIR  Find libGeoIP in DIR],
 	[CFLAGS=$CFLAGS" -I$withval/include -DUSE_GEOIP" 
@@ -114,7 +116,7 @@
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h sys/param.h netdb.h getopt.h sys/cdefs.h arpa/nameser.h stdbool.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h sys/param.h netdb.h getopt.h sys/cdefs.h arpa/nameser.h stdbool.h err.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_PID_T
@@ -140,6 +142,27 @@
 	LIBS=$SAVEDLIBS
 fi
 
+# Do we need -lcrypto with -lcurl?
+if test $use_libcurl = yes ; then
+	AC_MSG_CHECKING([if -lcurl needs -lcrypto to link and run])
+	lcurl_needs_lcrypto=no
+	SAVEDLIBS=$LIBS
+	AC_RUN_IFELSE([AC_LANG_PROGRAM([],[])], 
+	    [],
+	    [
+		LIBS="-lcrypto $LIBS"
+		AC_RUN_IFELSE([AC_LANG_PROGRAM([],[])],
+		    [lcurl_needs_lcrypto=yes],
+			[echo "Required libcrypto not found for libcurl. Use --with-openssl=DIR to provide the OpenSSL installation root.";
+                	 exit 1;])
+	    ])
+	if test $lcurl_needs_lcrypto = yes ; then
+		SAVEDLIBS=$LIBS
+	fi
+	AC_MSG_RESULT($lcurl_needs_lcrypto)
+	LIBS=$SAVEDLIBS
+fi
+
 # Checks for library functions.
 AC_FUNC_FORK
 AC_FUNC_STRFTIME
@@ -147,7 +170,7 @@
 AC_FUNC_SELECT_ARGTYPES
 AC_FUNC_SETVBUF_REVERSED
 AC_FUNC_STAT
-AC_CHECK_FUNCS([bzero gettimeofday malloc inet_ntoa strerror select socket initgroups strlcat vsyslog])
+AC_CHECK_FUNCS([bzero gettimeofday malloc inet_ntoa strerror select socket initgroups strlcat vsyslog strcasestr])
 
 
 # Check for libpthread. On FreeBSD, the libc_r does the job.
@@ -189,6 +212,31 @@
 LDFLAGS=$SAVEDLDFLAGS
 CFLAGS=$SAVEDCFLAGS
 
+# Try to configure for libspf2static
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+AC_ARG_WITH(libspf2static,
+       [  --with-libspf2static=DIR  Find libspf2 in DIR],
+       [LDFLAGS=$LDFLAGS" -L$withval/lib"
+	   CFLAGS=$CFLAGS" -I$withval/include"
+           AC_CHECK_LIB(spf2, SPF_server_new, [
+               SAVEDLDFLAGS=$LDFLAGS
+               SAVEDCFLAGS=$CFLAGS
+               LIBS=$LIBS" $withval/lib/libspf2.a"
+               AC_DEFINE([HAVE_SPF2], [], [we use libspf2])
+               ],[AC_CHECK_LIB([spf2 -lintl],  SPF_server_new, [
+                       SAVEDLDFLAGS=$LDFLAGS
+                       SAVEDCFLAGS=$CFLAGS
+                       LIBS=$LIBS" $withval/lib/libspf2.a -lintl"
+                       AC_DEFINE([HAVE_SPF2], [], [we use libspf2])
+               ], [echo "static library libspf2.a not found, check config.log for details"
+                   echo "Remove --with-libspf2static to build without SPF support or try --with-libspf2 for the shared library"
+                   exit 1;])
+       ])
+])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+
 # Try to configure for libspf2 1.0
 SAVEDLDFLAGS=$LDFLAGS
 SAVEDCFLAGS=$CFLAGS
diff -Naur milter-greylist-4.4.1-orig/p0f.c milter-greylist-4.4.1/p0f.c
--- milter-greylist-4.4.1-orig/p0f.c	2012-02-21 09:53:44.000000000 +0400
+++ milter-greylist-4.4.1/p0f.c	2013-01-06 22:51:13.693929640 +0400
@@ -29,6 +29,14 @@
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * NOTE: This is a client half for the p0f (passive-fingerprinter) daemon
+ * by Michal Zalewski, source code to which may currently be found at:
+ *    http://lcamtuf.coredump.cx/p0f3/
+ * This separate program must be built, installed and run alongside
+ * milter-greylist in order to use the relevant "p0f" ACL rules.
+ */
+
 #include "config.h"
 
 #ifdef USE_P0F
@@ -53,7 +61,9 @@
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <errno.h>
+#ifdef HAVE_ERR_H
 #include <err.h>
+#endif
 #include <sysexits.h>
 #include <syslog.h>
 
@@ -64,6 +74,40 @@
 #include "milter-greylist.h"
 #include "p0f.h"
 
+#ifndef HAVE_STRCASESTR
+#include <ctype.h>
+/* 
+* strcasestr(): case-insensitive version of strstr() - find substring NEEDLE in
+* the string HAYSTACK and return pointer to it, or NULL if not found
+* Details: http://linux.die.net/man/3/strcasestr
+* Source taken from an internet forum:
+* http://www.sunhelp.ru/forum/viewtopic.php?p=8374&sid=0fd2c2501a0234c5267efc2a610a79c9
+*/
+char * 
+strcasestr ( haystack, needle )
+	char *haystack;
+	const char *needle;
+{ 
+	char *h; 
+	const char *n; 
+
+	h = haystack; 
+	n = needle; 
+	while (*haystack) { 
+		if (tolower ((unsigned char)*h) == tolower ((unsigned char)*n)) { 
+			h++; 
+			n++; 
+			if (!*n) 
+				return haystack; 
+			} else { 
+				h = ++haystack; 
+				n = needle; 
+			}
+		}
+	return NULL; 
+}
+#endif /* HAVE_STRCASESTR */
+
 #ifndef HAVE_P0F3
 #ifdef P0F_QUERY_FROM_P0F_DIST
 #include <p0f-query.h>
@@ -404,7 +448,7 @@
 static int
 p0f_connect(void)
 {
-	struct sockaddr_un sun;
+	struct sockaddr_un s_un;
 	int p0fsock = -1;
 
 	if (!conf.c_p0fsock[0])
@@ -424,11 +468,11 @@
 
 	if (conf.c_debug)
 		mg_log(LOG_DEBUG, "using p0f socket \"%s\"", conf.c_p0fsock);		
-	(void)memset(&sun, 0, sizeof(sun));
-	sun.sun_family = AF_UNIX;
-	strncpy(sun.sun_path, conf.c_p0fsock, sizeof(sun.sun_path));
+	(void)memset(&s_un, 0, sizeof(s_un));
+	s_un.sun_family = AF_UNIX;
+	strncpy(s_un.sun_path, conf.c_p0fsock, sizeof(s_un.sun_path));
 
-	if (connect(p0fsock, (struct sockaddr *)&sun, sizeof(sun)) != 0) {
+	if (connect(p0fsock, (struct sockaddr *)&s_un, sizeof(s_un)) != 0) {
 		mg_log(LOG_ERR, "Cannot connect to p0f socket \"%s\"",
 		      conf.c_p0fsock);	
 		close(p0fsock);
diff -Naur milter-greylist-4.4.1-orig/spamd.c milter-greylist-4.4.1/spamd.c
--- milter-greylist-4.4.1-orig/spamd.c	2012-02-24 06:25:46.000000000 +0400
+++ milter-greylist-4.4.1/spamd.c	2013-01-06 22:45:31.782006771 +0400
@@ -436,12 +436,12 @@
 spamd_unix_socket(path)
 	char *path;
 {
-	struct sockaddr_un sun;
+	struct sockaddr_un s_un;
 	int sock;
 	
-	bzero(&sun, sizeof(sun));
-	sun.sun_family = AF_UNIX;
-	strncpy(sun.sun_path, path, sizeof(sun.sun_path) - 1);
+	bzero(&s_un, sizeof(s_un));
+	s_un.sun_family = AF_UNIX;
+	strncpy(s_un.sun_path, path, sizeof(s_un.sun_path) - 1);
 
 	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
 		mg_log(LOG_ERR, "spamd socket failed: %s", strerror(errno));
@@ -450,7 +450,7 @@
 
 	SET_CLOEXEC(sock);
 
-	if (connect(sock, (struct sockaddr*) &sun, sizeof(sun))) {
+	if (connect(sock, (struct sockaddr*) &s_un, sizeof(s_un))) {
 		mg_log(LOG_ERR, "spamd connect failed: %s", strerror(errno));
 		return -1;
 	}
-------------- next part --------------
diff -Naur p0f-3.06b-orig/build.sh p0f-3.06b-jimbuild/build.sh
--- p0f-3.06b-orig/build.sh	2012-12-29 16:38:45.000000000 +0400
+++ p0f-3.06b-jimbuild/build.sh	2013-01-17 22:15:47.865211543 +0400
@@ -12,10 +12,11 @@
 VERSION="3.06b"
 
 echo "Building $PROGNAME-$VERSION for $OSTYPE: $0 $@"
+#set
 
 test "$CC" = "" && CC="gcc"
 
-BASIC_CFLAGS="-Wall -Wno-format -I/usr/local/include/ \
+BASIC_CFLAGS="-Wall -Wno-format -I/usr/include -I/usr/local/include/ \
               -I/opt/local/include/ -DVERSION=\"$VERSION\" $CFLAGS"
 
 BASIC_LDFLAGS="-L/usr/local/lib/ -L/opt/local/lib $LDFLAGS"
@@ -25,13 +26,27 @@
 
 USE_LDFLAGS="-Wl,-z,relro -pie $BASIC_LDFLAGS"
 
-if [ "$OSTYPE" = "cygwin" ]; then
-  USE_LIBS="-lwpcap $LIBS"
-elif [ "$OSTYPE" = "solaris" ]; then
-  USE_LIBS="-lsocket -lnsl $LIBS"
-else
-  USE_LIBS="-lpcap $LIBS"
-fi
+case "$OSTYPE" in
+  cygwin)	echo "Detected OS to tweak: CygWin"
+		USE_LIBS="-lwpcap $LIBS"
+		;;
+  solaris*)	echo "Detected OS to tweak: Solaris"
+		USE_CFLAGS="$USE_CFLAGS -DSOLARIS=1"
+		BASIC_CFLAGS="$BASIC_CFLAGS -DSOLARIS=1"
+		USE_LIBS="-lsocket -lnsl -lpcap $LIBS" 
+		if [ ! -s /usr/include/stdint.h -a -f stdint-replacement.h ]; then
+		    ln -s stdint-replacement.h stdint.h
+		    BASIC_CFLAGS="$BASIC_CFLAGS -I."
+		    USE_CFLAGS="$USE_CFLAGS -I."
+		fi
+#		if [ -f /usr/ucblib/libucb.so -a -d /usr/ucbinclude ]; then
+#		    USE_LIBS="-lucb $USE_LIBS"
+#		    USE_CFLAGS="$USE_CFLAGS -L/usr/ucblib -DDSOLARIS_UCB=1"
+#		    BASIC_CFLAGS="$BASIC_CFLAGS -L/usr/ucblib -DDSOLARIS_UCB=1"
+#		fi
+		;;
+  *)		USE_LIBS="-lpcap $LIBS" ;;
+esac
 
 OBJFILES="api.c process.c fp_tcp.c fp_mtu.c fp_http.c readfp.c"
 
@@ -103,7 +116,7 @@
 
 echo -n "[*] Checking for a sane build environment... "
 
-if ls -ld ./ | grep -q '^d.......w'; then
+if ls -ld ./ | grep '^d.......w' >/dev/null 2>&1; then
 
   echo "FAIL (bad permissions)"
   echo
@@ -328,6 +341,8 @@
   echo
   echo "Well, something went horribly wrong, sorry. Here's the output from GCC:"
   echo
+  echo "$CC $USE_CFLAGS $USE_LDFLAGS '$PROGNAME.c' $OBJFILES -o '$PROGNAME' $USE_LIBS"
+  echo
   cat "$TMP.log"
   echo
   echo "Sorry! You may want to ping <lcamtuf at coredump.cx> about this."
diff -Naur p0f-3.06b-orig/err-replacement.h p0f-3.06b-jimbuild/err-replacement.h
--- p0f-3.06b-orig/err-replacement.h	1970-01-01 03:00:00.000000000 +0300
+++ p0f-3.06b-jimbuild/err-replacement.h	2012-12-30 02:09:14.581035535 +0400
@@ -0,0 +1,105 @@
+/* Replacement for BSD err.h and its routines
+ *   http://code.google.com/p/logwarn/issues/detail?id=4
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static const char *__getprogname() {
+        return
+                getexecname()
+        ;
+}
+void
+err(int eval, const char *fmt, ...)
+{
+        va_list ap;
+        int     sverrno;
+
+        sverrno = errno;
+        (void)fprintf(stderr, "%s: ", __getprogname());
+        va_start(ap, fmt);
+        if (fmt != NULL) {
+                (void)vfprintf(stderr, fmt, ap);
+                (void)fprintf(stderr, ": ");
+        }
+        va_end(ap);
+        (void)fprintf(stderr, "%s\n", strerror(sverrno));
+        exit(eval);
+}
+
+void
+errx(int eval, const char *fmt, ...)
+{
+        va_list ap;
+
+        (void)fprintf(stderr, "%s: ", __getprogname());
+        va_start(ap, fmt);
+        if (fmt != NULL)
+                (void)vfprintf(stderr, fmt, ap);
+        va_end(ap);
+        (void)fprintf(stderr, "\n");
+        exit(eval);
+}
+
+void
+warn(const char *fmt, ...)
+{
+        va_list ap;
+        int     sverrno;
+
+        sverrno = errno;
+        (void)fprintf(stderr, "%s: ", __getprogname());
+        va_start(ap, fmt);
+        if (fmt != NULL) {
+                (void)vfprintf(stderr, fmt, ap);
+                (void)fprintf(stderr, ": ");
+        }
+        va_end(ap);
+        (void)fprintf(stderr, "%s\n", strerror(sverrno));
+}
+
+void
+warnx(const char *fmt, ...)
+{
+        va_list ap;
+
+        (void)fprintf(stderr, "%s: ", __getprogname());
+        va_start(ap, fmt);
+        if (fmt != NULL)
+                (void)vfprintf(stderr, fmt, ap);
+        va_end(ap);
+        (void)fprintf(stderr, "\n");
+}
+
+
+/* 
+* case-insensitive version of strstr() 
+* http://www.sunhelp.ru/forum/viewtopic.php?p=8374&sid=0fd2c2501a0234c5267efc2a610a79c9
+*/ 
+char * 
+strcasestr ( 
+char *haystack, 
+const char *needle) 
+{ 
+char *h; 
+const char *n; 
+
+h = haystack; 
+n = needle; 
+while (*haystack) { 
+if (tolower ((unsigned char)*h) == tolower ((unsigned char)*n)) { 
+h++; 
+n++; 
+if (!*n) 
+return haystack; 
+} else { 
+h = ++haystack; 
+n = needle; 
+} 
+} 
+return NULL; 
+}
+
diff -Naur p0f-3.06b-orig/p0f.c p0f-3.06b-jimbuild/p0f.c
--- p0f-3.06b-orig/p0f.c	2012-09-30 08:44:27.000000000 +0400
+++ p0f-3.06b-jimbuild/p0f.c	2013-01-12 06:29:56.830125665 +0400
@@ -28,12 +28,26 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <sys/un.h>
-#include <sys/fcntl.h>
+#ifdef SOLARIS
+//#  warning "SOLARIS=yes"
+#  include <sys/fcntl.h>
+#  include <fcntl.h>
+# ifdef SOLARIS_UCB
+#    include "/usr/ucbinclude/sys/file.h"
+# else
+#    include <sys/file.h>
+# endif
+   int flock(int fd, int operation);
+#else
+//#  warning "SOLARIS=no"
+#  include <sys/fcntl.h>
+#  include <sys/file.h>
+#endif /* !SOLARIS */
 #include <sys/stat.h>
-#include <sys/file.h>
 #include <sys/wait.h>
 #include <netinet/in.h>
 
+
 #include <pcap.h>
 
 #ifdef NET_BPF
@@ -52,6 +66,53 @@
 #include "fp_http.h"
 #include "p0f.h"
 
+#ifdef SOLARIS
+#ifndef SOLARIS_UCB
+
+#ifndef LOCK_SH
+#define   LOCK_SH   1    /* shared lock */
+#define   LOCK_EX   2    /* exclusive lock */
+#define   LOCK_NB   4    /* don't block when locking */
+#define   LOCK_UN   8    /* unlock */
+#endif
+
+/* http://www.perkin.org.uk/posts/solaris-portability-flock.html */
+int flock(int fd, int op) {
+    int rc = 0;
+
+#if defined(F_SETLK) && defined(F_SETLKW)
+    struct flock fl = {0};
+
+    switch (op & (LOCK_EX|LOCK_SH|LOCK_UN)) {
+    case LOCK_EX:
+	fl.l_type = F_WRLCK;
+	break;
+
+    case LOCK_SH:
+	fl.l_type = F_RDLCK;
+	break;
+
+    case LOCK_UN:
+	fl.l_type = F_UNLCK;
+	break;
+
+    default:
+	errno = EINVAL;
+	return -1;
+    }
+
+    fl.l_whence = SEEK_SET;
+    rc = fcntl(fd, op & LOCK_NB ? F_SETLK : F_SETLKW, &fl);
+
+    if (rc && (errno == EAGAIN))
+	errno = EWOULDBLOCK;
+#endif
+
+    return rc;
+}
+#endif
+#endif
+
 #ifndef PF_INET6
 #  define PF_INET6          10
 #endif /* !PF_INET6 */
diff -Naur p0f-3.06b-orig/p0f.sh p0f-3.06b-jimbuild/p0f.sh
diff -Naur p0f-3.06b-orig/readfp.c p0f-3.06b-jimbuild/readfp.c
--- p0f-3.06b-orig/readfp.c	2012-01-14 21:48:40.000000000 +0400
+++ p0f-3.06b-jimbuild/readfp.c	2013-01-12 04:42:23.905196397 +0400
@@ -17,7 +17,21 @@
 #include <unistd.h>
 #include <ctype.h>
 
-#include <sys/fcntl.h>
+#ifdef SOLARIS
+//#  warning "SOLARIS=yes"
+#  include <sys/fcntl.h>
+#  include <fcntl.h>
+# ifdef SOLARIS_UCB
+#    include "/usr/ucbinclude/sys/file.h"
+# else
+#    include <sys/file.h>
+# endif
+#else
+//#  warning "SOLARIS=no"
+#  include <sys/fcntl.h>
+#  include <sys/file.h>
+#endif /* !SOLARIS */
+
 #include <netinet/in.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff -Naur p0f-3.06b-orig/stdint-replacement.h p0f-3.06b-jimbuild/stdint-replacement.h
--- p0f-3.06b-orig/stdint-replacement.h	1970-01-01 03:00:00.000000000 +0300
+++ p0f-3.06b-jimbuild/stdint-replacement.h	2005-01-22 01:19:48.000000000 +0300
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_STDINT_H
+#define	_SYS_STDINT_H
+
+#pragma ident	"@(#)stdint.h	1.1	03/12/04 SMI"
+
+/*
+ * This header is included by <stdint.h> which was introduced by
+ * the ISO C Standard, ISO/IEC 9899:1999 Programming language - C.
+ * The header is a subset of the <inttypes.h> header.
+ */
+
+#include <sys/int_types.h>
+#include <sys/int_limits.h>
+#include <sys/int_const.h>
+
+#endif	/* _SYS_STDINT_H */
diff -Naur p0f-3.06b-orig/tools/Makefile p0f-3.06b-jimbuild/tools/Makefile
--- p0f-3.06b-orig/tools/Makefile	2012-01-04 13:34:28.000000000 +0400
+++ p0f-3.06b-jimbuild/tools/Makefile	2013-01-03 21:57:13.367498253 +0400
@@ -9,7 +9,7 @@
 
 CC      = gcc
 CFLAGS  = -g -ggdb -Wall -Wno-format -funsigned-char
-LDFLAGS =
+LDFLAGS = -lsocket
 TARGETS = p0f-client p0f-sendsyn p0f-sendsyn6
 
 all: $(TARGETS)
diff -Naur p0f-3.06b-orig/tools/p0f-client.c p0f-3.06b-jimbuild/tools/p0f-client.c
--- p0f-3.06b-orig/tools/p0f-client.c	2012-01-19 21:17:02.000000000 +0400
+++ p0f-3.06b-jimbuild/tools/p0f-client.c	2013-01-03 21:56:50.289375418 +0400
@@ -89,7 +89,7 @@
   static struct p0f_api_query q;
   static struct p0f_api_response r;
 
-  static struct sockaddr_un sun;
+  static struct sockaddr_un p0fsockstruct;
 
   s32  sock;
   time_t ut;
@@ -117,14 +117,14 @@
 
   if (sock < 0) PFATAL("Call to socket() failed.");
 
-  sun.sun_family = AF_UNIX;
+  p0fsockstruct.sun_family = AF_UNIX;
 
-  if (strlen(argv[1]) >= sizeof(sun.sun_path))
+  if (strlen(argv[1]) >= sizeof(p0fsockstruct.sun_path))
     FATAL("API socket filename is too long for sockaddr_un (blame Unix).");
 
-  strcpy(sun.sun_path, argv[1]);
+  strcpy(p0fsockstruct.sun_path, argv[1]);
 
-  if (connect(sock, (struct sockaddr*)&sun, sizeof(sun)))
+  if (connect(sock, (struct sockaddr*)&p0fsockstruct, sizeof(p0fsockstruct)))
     PFATAL("Can't connect to API socket.");
 
   if (write(sock, &q, sizeof(struct p0f_api_query)) !=
-------------- next part --------------
diff -Naur milter-greylist-4.4.2-orig/Makefile.in milter-greylist-4.4.2-jimbuild/Makefile.in
--- milter-greylist-4.4.2-orig/Makefile.in	2010-07-13 08:18:06.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/Makefile.in	2013-01-13 03:30:18.894434435 +0400
@@ -138,12 +138,14 @@
 clean:
 	${RM} -f milter-greylist ${OBJ} ${GENSRC} \
 	rc-redhat.sh rc-bsd.sh rc-solaris.sh rc-debian.sh rc-gentoo.sh \
-	rc-suse.sh
+	rc-suse.sh y.tab.c
 
 realclean:	clean
 	${RM} -Rf Makefile config.h config.log config.status \
 		 autom4te.cache configure.lineno *.orig *.bak autoscan.log
 
+distclean:	realclean
+
 .SUFFIXES:	.o .c .h .y .l
 .l.c:
 	${LEX} -o$@ $<
diff -Naur milter-greylist-4.4.2-orig/acl.c milter-greylist-4.4.2-jimbuild/acl.c
--- milter-greylist-4.4.2-orig/acl.c	2012-09-20 12:31:49.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/acl.c	2013-01-13 06:02:28.505073769 +0400
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/acl.h milter-greylist-4.4.2-jimbuild/acl.h
--- milter-greylist-4.4.2-orig/acl.h	2012-09-19 06:04:38.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/acl.h	2013-01-13 06:03:37.326697498 +0400
@@ -33,7 +33,7 @@
 #define _ACL_H_
 
 #include "config.h"
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/clock.c milter-greylist-4.4.2-jimbuild/clock.c
--- milter-greylist-4.4.2-orig/clock.c	2007-11-06 14:39:33.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/clock.c	2013-01-13 06:01:49.031561467 +0400
@@ -45,7 +45,7 @@
 #include <errno.h>
 #include <sysexits.h>
 #include <time.h>
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/conf.c milter-greylist-4.4.2-jimbuild/conf.c
--- milter-greylist-4.4.2-orig/conf.c	2011-08-17 05:06:49.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/conf.c	2013-01-13 06:02:36.904016964 +0400
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/conf.h milter-greylist-4.4.2-jimbuild/conf.h
--- milter-greylist-4.4.2-orig/conf.h	2012-02-21 09:53:43.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/conf.h	2013-01-13 06:03:43.997093796 +0400
@@ -33,7 +33,7 @@
 #define _CONF_H_
 
 #include "config.h"
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/dkimcheck.c milter-greylist-4.4.2-jimbuild/dkimcheck.c
--- milter-greylist-4.4.2-orig/dkimcheck.c	2013-01-08 18:30:01.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/dkimcheck.c	2013-01-11 15:45:35.886704089 +0400
@@ -29,6 +29,11 @@
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/* For DKIM support you will need to build the Sendmail milter-dkim
+ * (now formally obsoleted) and in particular its libdkim, source from:
+ *    http://sourceforge.net/projects/dkim-milter
+ */
+
 #include "config.h"
 
 #ifdef USE_DKIM
diff -Naur milter-greylist-4.4.2-orig/dnsrbl.c milter-greylist-4.4.2-jimbuild/dnsrbl.c
--- milter-greylist-4.4.2-orig/dnsrbl.c	2010-03-13 10:00:12.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/dnsrbl.c	2013-01-13 06:03:21.228334440 +0400
@@ -50,7 +50,7 @@
 #include <errno.h>
 #include <sysexits.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/dump.c milter-greylist-4.4.2-jimbuild/dump.c
--- milter-greylist-4.4.2-orig/dump.c	2012-09-11 08:29:19.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/dump.c	2013-01-13 06:03:49.916283899 +0400
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/dump.h milter-greylist-4.4.2-jimbuild/dump.h
--- milter-greylist-4.4.2-orig/dump.h	2009-09-26 18:38:39.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/dump.h	2013-01-13 06:02:23.682249734 +0400
@@ -32,7 +32,7 @@
 #define _DUMP_H_
 
 #include "config.h"
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/ldapcheck.c milter-greylist-4.4.2-jimbuild/ldapcheck.c
--- milter-greylist-4.4.2-orig/ldapcheck.c	2013-01-08 18:30:01.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/ldapcheck.c	2013-01-13 06:01:16.539979795 +0400
@@ -49,6 +49,9 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <syslog.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
 
 #include "conf.h"
 #include "milter-greylist.h"
diff -Naur milter-greylist-4.4.2-orig/list.c milter-greylist-4.4.2-jimbuild/list.c
--- milter-greylist-4.4.2-orig/list.c	2009-02-09 07:12:07.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/list.c	2013-01-13 06:03:26.544177321 +0400
@@ -47,7 +47,7 @@
 #include <sys/types.h>
 #include <regex.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/macro.c milter-greylist-4.4.2-jimbuild/macro.c
--- milter-greylist-4.4.2-orig/macro.c	2008-11-18 14:57:29.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/macro.c	2013-01-13 06:02:14.476609635 +0400
@@ -47,7 +47,7 @@
 #include <sysexits.h>
 #include <regex.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/mx.c milter-greylist-4.4.2-jimbuild/mx.c
--- milter-greylist-4.4.2-orig/mx.c	2010-03-15 23:34:49.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/mx.c	2013-01-13 06:03:55.712737534 +0400
@@ -19,7 +19,7 @@
 #include <errno.h>
 #include <sysexits.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/pending.c milter-greylist-4.4.2-jimbuild/pending.c
--- milter-greylist-4.4.2-orig/pending.c	2010-04-12 16:04:41.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/pending.c	2013-01-13 06:03:14.796057164 +0400
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/pending.h milter-greylist-4.4.2-jimbuild/pending.h
--- milter-greylist-4.4.2-orig/pending.h	2010-04-12 16:04:41.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/pending.h	2013-01-13 06:01:38.022763059 +0400
@@ -33,7 +33,7 @@
 #define _PENDING_H_
 
 #include "config.h"
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/prop.c milter-greylist-4.4.2-jimbuild/prop.c
--- milter-greylist-4.4.2-orig/prop.c	2012-09-27 22:10:04.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/prop.c	2013-01-13 06:02:49.201794081 +0400
@@ -50,7 +50,7 @@
 #include <sysexits.h>
 #include <signal.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/queue.h milter-greylist-4.4.2-jimbuild/queue.h
--- milter-greylist-4.4.2-orig/queue.h	2009-02-09 07:12:07.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/queue.h	2013-01-13 08:21:07.420615213 +0400
@@ -1,5 +1,5 @@
 /* $Id: queue.h,v 1.3 2009/02/09 04:12:07 manu Exp $ */
-/*	$NetBSD: queue.h,v 1.30 2001/06/22 06:18:22 chs Exp $	*/
+/*	$NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993
@@ -62,7 +62,7 @@
  *
  * A simple queue is headed by a pair of pointers, one the head of the
  * list and the other to the tail of the list. The elements are singly
- * linked to save space, so only elements can only be removed from the
+ * linked to save space, so elements can only be removed from the
  * head of the list. New elements can be added to the list after
  * an existing element, at the head of the list, or at the end of the
  * list. A simple queue may only be traversed in the forward direction.
@@ -88,15 +88,15 @@
 /*
  * List definitions.
  */
-#define LIST_HEAD(name, type)						\
+#define	LIST_HEAD(name, type)						\
 struct name {								\
 	struct type *lh_first;	/* first element */			\
 }
 
-#define LIST_HEAD_INITIALIZER(head)					\
+#define	LIST_HEAD_INITIALIZER(head)					\
 	{ NULL }
 
-#define LIST_ENTRY(type)						\
+#define	LIST_ENTRY(type)						\
 struct {								\
 	struct type *le_next;	/* next element */			\
 	struct type **le_prev;	/* address of previous next element */	\
@@ -106,31 +106,31 @@
  * List functions.
  */
 #if defined(_KERNEL) && defined(QUEUEDEBUG)
-#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
+#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
 	if ((head)->lh_first &&						\
 	    (head)->lh_first->field.le_prev != &(head)->lh_first)	\
 		panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
-#define QUEUEDEBUG_LIST_OP(elm, field)					\
+#define	QUEUEDEBUG_LIST_OP(elm, field)					\
 	if ((elm)->field.le_next &&					\
 	    (elm)->field.le_next->field.le_prev !=			\
 	    &(elm)->field.le_next)					\
 		panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
 	if (*(elm)->field.le_prev != (elm))				\
 		panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
-#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
+#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
 	(elm)->field.le_next = (void *)1L;				\
 	(elm)->field.le_prev = (void *)1L;
 #else
-#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
-#define QUEUEDEBUG_LIST_OP(elm, field)
-#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
+#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
+#define	QUEUEDEBUG_LIST_OP(elm, field)
+#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
 #endif
 
 #define	LIST_INIT(head) do {						\
 	(head)->lh_first = NULL;					\
 } while (/*CONSTCOND*/0)
 
-#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
 	QUEUEDEBUG_LIST_OP((listelm), field)				\
 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
 		(listelm)->field.le_next->field.le_prev =		\
@@ -147,7 +147,7 @@
 	(listelm)->field.le_prev = &(elm)->field.le_next;		\
 } while (/*CONSTCOND*/0)
 
-#define LIST_INSERT_HEAD(head, elm, field) do {				\
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
 	QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)		\
 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
@@ -155,7 +155,7 @@
 	(elm)->field.le_prev = &(head)->lh_first;			\
 } while (/*CONSTCOND*/0)
 
-#define LIST_REMOVE(elm, field) do {					\
+#define	LIST_REMOVE(elm, field) do {					\
 	QUEUEDEBUG_LIST_OP((elm), field)				\
 	if ((elm)->field.le_next != NULL)				\
 		(elm)->field.le_next->field.le_prev = 			\
@@ -164,11 +164,15 @@
 	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
 } while (/*CONSTCOND*/0)
 
-#define LIST_FOREACH(var, head, field)					\
+#define	LIST_FOREACH(var, head, field)					\
 	for ((var) = ((head)->lh_first);				\
 		(var);							\
 		(var) = ((var)->field.le_next))
 
+#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = LIST_FIRST((head));				\
+		(var) && ((tvar) = LIST_NEXT((var), field), 1);		\
+		(var) = (tvar))
 /*
  * List access methods.
  */
@@ -176,53 +180,45 @@
 #define	LIST_FIRST(head)		((head)->lh_first)
 #define	LIST_NEXT(elm, field)		((elm)->field.le_next)
 
+
 /*
  * Singly-linked List definitions.
  */
-#define SLIST_HEAD(name, type)						\
+#define	SLIST_HEAD(name, type)						\
 struct name {								\
 	struct type *slh_first;	/* first element */			\
 }
 
-#define SLIST_HEAD_INITIALIZER(head)					\
+#define	SLIST_HEAD_INITIALIZER(head)					\
 	{ NULL }
- 
-#define SLIST_ENTRY(type)						\
+
+#define	SLIST_ENTRY(type)						\
 struct {								\
 	struct type *sle_next;	/* next element */			\
 }
- 
+
 /*
  * Singly-linked List functions.
  */
-#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
-#define	SLIST_FIRST(head)	((head)->slh_first)
-#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-
-#define SLIST_FOREACH(var, head, field)					\
-	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define SLIST_INIT(head) do {						\
+#define	SLIST_INIT(head) do {						\
 	(head)->slh_first = NULL;					\
 } while (/*CONSTCOND*/0)
 
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
 	(slistelm)->field.sle_next = (elm);				\
 } while (/*CONSTCOND*/0)
 
-#define SLIST_INSERT_HEAD(head, elm, field) do {			\
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
 	(elm)->field.sle_next = (head)->slh_first;			\
 	(head)->slh_first = (elm);					\
 } while (/*CONSTCOND*/0)
 
-#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-
-#define SLIST_REMOVE_HEAD(head, field) do {				\
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
 	(head)->slh_first = (head)->slh_first->field.sle_next;		\
 } while (/*CONSTCOND*/0)
 
-#define SLIST_REMOVE(head, elm, type, field) do {			\
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
 	if ((head)->slh_first == (elm)) {				\
 		SLIST_REMOVE_HEAD((head), field);			\
 	}								\
@@ -235,19 +231,133 @@
 	}								\
 } while (/*CONSTCOND*/0)
 
+#define	SLIST_REMOVE_AFTER(slistelm, field) do {			\
+	(slistelm)->field.sle_next =					\
+	    SLIST_NEXT(SLIST_NEXT((slistelm), field), field);		\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+/*
+ * Singly-linked List access methods.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+#define	SLIST_FIRST(head)	((head)->slh_first)
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)					\
+struct name {								\
+	struct type *stqh_first;	/* first element */			\
+	struct type **stqh_last;	/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_INIT(head) do {						\
+	(head)->stqh_first = NULL;					\
+	(head)->stqh_last = &(head)->stqh_first;				\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
+		(head)->stqh_last = &(elm)->field.stqe_next;		\
+	(head)->stqh_first = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.stqe_next = NULL;					\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &(elm)->field.stqe_next;			\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
+		(head)->stqh_last = &(elm)->field.stqe_next;		\
+	(listelm)->field.stqe_next = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
+		(head)->stqh_last = &(head)->stqh_first;			\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if ((head)->stqh_first == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->stqh_first;		\
+		while (curelm->field.stqe_next != (elm))			\
+			curelm = curelm->field.stqe_next;		\
+		if ((curelm->field.stqe_next =				\
+			curelm->field.stqe_next->field.stqe_next) == NULL) \
+			    (head)->stqh_last = &(curelm)->field.stqe_next; \
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for ((var) = ((head)->stqh_first);				\
+		(var);							\
+		(var) = ((var)->field.stqe_next))
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST((head));				\
+	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)(void *)				\
+		((char *)((head)->stqh_last) - offsetof(struct type, field))))
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+
 /*
  * Simple queue definitions.
  */
-#define SIMPLEQ_HEAD(name, type)					\
+#define	SIMPLEQ_HEAD(name, type)					\
 struct name {								\
 	struct type *sqh_first;	/* first element */			\
 	struct type **sqh_last;	/* addr of last next element */		\
 }
 
-#define SIMPLEQ_HEAD_INITIALIZER(head)					\
+#define	SIMPLEQ_HEAD_INITIALIZER(head)					\
 	{ NULL, &(head).sqh_first }
 
-#define SIMPLEQ_ENTRY(type)						\
+#define	SIMPLEQ_ENTRY(type)						\
 struct {								\
 	struct type *sqe_next;	/* next element */			\
 }
@@ -260,34 +370,66 @@
 	(head)->sqh_last = &(head)->sqh_first;				\
 } while (/*CONSTCOND*/0)
 
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
+#define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
 		(head)->sqh_last = &(elm)->field.sqe_next;		\
 	(head)->sqh_first = (elm);					\
 } while (/*CONSTCOND*/0)
 
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
+#define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
 	(elm)->field.sqe_next = NULL;					\
 	*(head)->sqh_last = (elm);					\
 	(head)->sqh_last = &(elm)->field.sqe_next;			\
 } while (/*CONSTCOND*/0)
 
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+#define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
 		(head)->sqh_last = &(elm)->field.sqe_next;		\
 	(listelm)->field.sqe_next = (elm);				\
 } while (/*CONSTCOND*/0)
 
-#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
-	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
+#define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
+	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
 		(head)->sqh_last = &(head)->sqh_first;			\
 } while (/*CONSTCOND*/0)
 
-#define SIMPLEQ_FOREACH(var, head, field)				\
+#define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
+	if ((head)->sqh_first == (elm)) {				\
+		SIMPLEQ_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->sqh_first;		\
+		while (curelm->field.sqe_next != (elm))			\
+			curelm = curelm->field.sqe_next;		\
+		if ((curelm->field.sqe_next =				\
+			curelm->field.sqe_next->field.sqe_next) == NULL) \
+			    (head)->sqh_last = &(curelm)->field.sqe_next; \
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_FOREACH(var, head, field)				\
 	for ((var) = ((head)->sqh_first);				\
 		(var);							\
 		(var) = ((var)->field.sqe_next))
 
+#define	SIMPLEQ_FOREACH_SAFE(var, head, field, next)			\
+	for ((var) = ((head)->sqh_first);				\
+		(var) && ((next = ((var)->field.sqe_next)), 1);		\
+		(var) = (next))
+
+#define	SIMPLEQ_CONCAT(head1, head2) do {				\
+	if (!SIMPLEQ_EMPTY((head2))) {					\
+		*(head1)->sqh_last = (head2)->sqh_first;		\
+		(head1)->sqh_last = (head2)->sqh_last;		\
+		SIMPLEQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_LAST(head, type, field)					\
+	(SIMPLEQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)(void *)				\
+		((char *)((head)->sqh_last) - offsetof(struct type, field))))
+
 /*
  * Simple queue access methods.
  */
@@ -295,50 +437,59 @@
 #define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
 #define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
 
+
 /*
  * Tail queue definitions.
  */
-#define TAILQ_HEAD(name, type)						\
+#define	_TAILQ_HEAD(name, type, qual)					\
 struct name {								\
-	struct type *tqh_first;	/* first element */			\
-	struct type **tqh_last;	/* addr of last next element */		\
+	qual type *tqh_first;		/* first element */		\
+	qual type *qual *tqh_last;	/* addr of last next element */	\
 }
+#define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)
 
-#define TAILQ_HEAD_INITIALIZER(head)					\
+#define	TAILQ_HEAD_INITIALIZER(head)					\
 	{ NULL, &(head).tqh_first }
 
-#define TAILQ_ENTRY(type)						\
+#define	_TAILQ_ENTRY(type, qual)					\
 struct {								\
-	struct type *tqe_next;	/* next element */			\
-	struct type **tqe_prev;	/* address of previous next element */	\
+	qual type *tqe_next;		/* next element */		\
+	qual type *qual *tqe_prev;	/* address of previous next element */\
 }
+#define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)
 
 /*
  * Tail queue functions.
  */
 #if defined(_KERNEL) && defined(QUEUEDEBUG)
-#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
+#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
 	if ((head)->tqh_first &&					\
 	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
 		panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
-#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
+#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
 	if (*(head)->tqh_last != NULL)					\
 		panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
-#define QUEUEDEBUG_TAILQ_OP(elm, field)					\
+#define	QUEUEDEBUG_TAILQ_OP(elm, field)					\
 	if ((elm)->field.tqe_next &&					\
 	    (elm)->field.tqe_next->field.tqe_prev !=			\
 	    &(elm)->field.tqe_next)					\
 		panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
 	if (*(elm)->field.tqe_prev != (elm))				\
 		panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
-#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
+#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)			\
+	if ((elm)->field.tqe_next == NULL &&				\
+	    (head)->tqh_last != &(elm)->field.tqe_next)			\
+		panic("TAILQ_PREREMOVE head %p elm %p %s:%d",		\
+		      (head), (elm), __FILE__, __LINE__);
+#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
 	(elm)->field.tqe_next = (void *)1L;				\
 	(elm)->field.tqe_prev = (void *)1L;
 #else
-#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
-#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
-#define QUEUEDEBUG_TAILQ_OP(elm, field)
-#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
+#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_OP(elm, field)
+#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
 #endif
 
 #define	TAILQ_INIT(head) do {						\
@@ -346,7 +497,7 @@
 	(head)->tqh_last = &(head)->tqh_first;				\
 } while (/*CONSTCOND*/0)
 
-#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
 	QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)		\
 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
 		(head)->tqh_first->field.tqe_prev =			\
@@ -357,7 +508,7 @@
 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
 } while (/*CONSTCOND*/0)
 
-#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
 	QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)		\
 	(elm)->field.tqe_next = NULL;					\
 	(elm)->field.tqe_prev = (head)->tqh_last;			\
@@ -365,7 +516,7 @@
 	(head)->tqh_last = &(elm)->field.tqe_next;			\
 } while (/*CONSTCOND*/0)
 
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
 	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
 		(elm)->field.tqe_next->field.tqe_prev = 		\
@@ -384,7 +535,8 @@
 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
 } while (/*CONSTCOND*/0)
 
-#define TAILQ_REMOVE(head, elm, field) do {				\
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)		\
 	QUEUEDEBUG_TAILQ_OP((elm), field)				\
 	if (((elm)->field.tqe_next) != NULL)				\
 		(elm)->field.tqe_next->field.tqe_prev = 		\
@@ -395,6 +547,35 @@
 	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
 } while (/*CONSTCOND*/0)
 
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = ((head)->tqh_first);				\
+		(var);							\
+		(var) = ((var)->field.tqe_next))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, next)			\
+	for ((var) = ((head)->tqh_first);				\
+	        (var) != NULL && ((next) = TAILQ_NEXT(var, field), 1);	\
+		(var) = (next))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
+		(var);							\
+		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+		(var) && ((prev) = TAILQ_PREV((var), headname, field), 1);\
+		(var) = (prev))
+
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
 /*
  * Tail queue access methods.
  */
@@ -402,34 +583,63 @@
 #define	TAILQ_FIRST(head)		((head)->tqh_first)
 #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
 
-#define TAILQ_LAST(head, headname) \
+#define	TAILQ_LAST(head, headname) \
 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define TAILQ_PREV(elm, headname, field) \
+#define	TAILQ_PREV(elm, headname, field) \
 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 
-#define TAILQ_FOREACH(var, head, field)					\
-	for ((var) = ((head)->tqh_first);				\
-		(var);							\
-		(var) = ((var)->field.tqe_next))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
-	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
-		(var);							\
-		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
 
 /*
  * Circular queue definitions.
  */
-#define CIRCLEQ_HEAD(name, type)					\
+#if defined(_KERNEL) && defined(QUEUEDEBUG)
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)				\
+	if ((head)->cqh_first != (void *)(head) &&			\
+	    (head)->cqh_first->field.cqe_prev != (void *)(head))	\
+		panic("CIRCLEQ head forw %p %s:%d", (head),		\
+		      __FILE__, __LINE__);				\
+	if ((head)->cqh_last != (void *)(head) &&			\
+	    (head)->cqh_last->field.cqe_next != (void *)(head))		\
+		panic("CIRCLEQ head back %p %s:%d", (head),		\
+		      __FILE__, __LINE__);
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)			\
+	if ((elm)->field.cqe_next == (void *)(head)) {			\
+		if ((head)->cqh_last != (elm))				\
+			panic("CIRCLEQ elm last %p %s:%d", (elm),	\
+			      __FILE__, __LINE__);			\
+	} else {							\
+		if ((elm)->field.cqe_next->field.cqe_prev != (elm))	\
+			panic("CIRCLEQ elm forw %p %s:%d", (elm),	\
+			      __FILE__, __LINE__);			\
+	}								\
+	if ((elm)->field.cqe_prev == (void *)(head)) {			\
+		if ((head)->cqh_first != (elm))				\
+			panic("CIRCLEQ elm first %p %s:%d", (elm),	\
+			      __FILE__, __LINE__);			\
+	} else {							\
+		if ((elm)->field.cqe_prev->field.cqe_next != (elm))	\
+			panic("CIRCLEQ elm prev %p %s:%d", (elm),	\
+			      __FILE__, __LINE__);			\
+	}
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)			\
+	(elm)->field.cqe_next = (void *)1L;				\
+	(elm)->field.cqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
+#endif
+
+#define	CIRCLEQ_HEAD(name, type)					\
 struct name {								\
 	struct type *cqh_first;		/* first element */		\
 	struct type *cqh_last;		/* last element */		\
 }
 
-#define CIRCLEQ_HEAD_INITIALIZER(head)					\
+#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
 	{ (void *)&head, (void *)&head }
 
-#define CIRCLEQ_ENTRY(type)						\
+#define	CIRCLEQ_ENTRY(type)						\
 struct {								\
 	struct type *cqe_next;		/* next element */		\
 	struct type *cqe_prev;		/* previous element */		\
@@ -443,7 +653,9 @@
 	(head)->cqh_last = (void *)(head);				\
 } while (/*CONSTCOND*/0)
 
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
 	(elm)->field.cqe_prev = (listelm);				\
 	if ((listelm)->field.cqe_next == (void *)(head))		\
@@ -453,7 +665,9 @@
 	(listelm)->field.cqe_next = (elm);				\
 } while (/*CONSTCOND*/0)
 
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
+#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
 	(elm)->field.cqe_next = (listelm);				\
 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
 	if ((listelm)->field.cqe_prev == (void *)(head))		\
@@ -463,7 +677,8 @@
 	(listelm)->field.cqe_prev = (elm);				\
 } while (/*CONSTCOND*/0)
 
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
+#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
 	(elm)->field.cqe_next = (head)->cqh_first;			\
 	(elm)->field.cqe_prev = (void *)(head);				\
 	if ((head)->cqh_last == (void *)(head))				\
@@ -473,7 +688,8 @@
 	(head)->cqh_first = (elm);					\
 } while (/*CONSTCOND*/0)
 
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
+#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
 	(elm)->field.cqe_next = (void *)(head);				\
 	(elm)->field.cqe_prev = (head)->cqh_last;			\
 	if ((head)->cqh_first == (void *)(head))			\
@@ -484,6 +700,8 @@
 } while (/*CONSTCOND*/0)
 
 #define	CIRCLEQ_REMOVE(head, elm, field) do {				\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field)			\
 	if ((elm)->field.cqe_next == (void *)(head))			\
 		(head)->cqh_last = (elm)->field.cqe_prev;		\
 	else								\
@@ -494,16 +712,17 @@
 	else								\
 		(elm)->field.cqe_prev->field.cqe_next =			\
 		    (elm)->field.cqe_next;				\
+	QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field)			\
 } while (/*CONSTCOND*/0)
 
-#define CIRCLEQ_FOREACH(var, head, field)				\
+#define	CIRCLEQ_FOREACH(var, head, field)				\
 	for ((var) = ((head)->cqh_first);				\
-		(var) != (void *)(head);				\
+		(var) != (const void *)(head);				\
 		(var) = ((var)->field.cqe_next))
 
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
+#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
 	for ((var) = ((head)->cqh_last);				\
-		(var) != (void *)(head);				\
+		(var) != (const void *)(head);				\
 		(var) = ((var)->field.cqe_prev))
 
 /*
@@ -514,4 +733,14 @@
 #define	CIRCLEQ_LAST(head)		((head)->cqh_last)
 #define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
 #define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field)				\
+	(((elm)->field.cqe_next == (void *)(head))			\
+	    ? ((head)->cqh_first)					\
+	    : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field)				\
+	(((elm)->field.cqe_prev == (void *)(head))			\
+	    ? ((head)->cqh_last)					\
+	    : (elm->field.cqe_prev))
+
 #endif	/* !_SYS_QUEUE_H_ */
diff -Naur milter-greylist-4.4.2-orig/ratelimit.c milter-greylist-4.4.2-jimbuild/ratelimit.c
--- milter-greylist-4.4.2-orig/ratelimit.c	2012-09-20 12:31:49.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/ratelimit.c	2013-01-13 06:03:09.407830014 +0400
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/ratelimit.h milter-greylist-4.4.2-jimbuild/ratelimit.h
--- milter-greylist-4.4.2-orig/ratelimit.h	2010-04-18 08:03:56.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/ratelimit.h	2013-01-13 06:00:31.001047454 +0400
@@ -32,7 +32,7 @@
 #define _RATELIMIT_H_
 
 #include "config.h"
-#ifdef HAVE_OLD_QUEUE_H
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/stat.c milter-greylist-4.4.2-jimbuild/stat.c
--- milter-greylist-4.4.2-orig/stat.c	2012-09-20 12:31:49.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/stat.c	2013-01-13 06:02:18.714920475 +0400
@@ -46,7 +46,7 @@
 #include <ctype.h>
 #include <sysexits.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/store.c milter-greylist-4.4.2-jimbuild/store.c
--- milter-greylist-4.4.2-orig/store.c	2009-11-01 00:28:03.000000000 +0300
+++ milter-greylist-4.4.2-jimbuild/store.c	2013-01-13 06:02:42.848953574 +0400
@@ -44,7 +44,7 @@
 #include <ctype.h>
 #include <sysexits.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
diff -Naur milter-greylist-4.4.2-orig/urlcheck.c milter-greylist-4.4.2-jimbuild/urlcheck.c
--- milter-greylist-4.4.2-orig/urlcheck.c	2012-09-20 12:31:49.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/urlcheck.c	2013-01-13 06:03:04.310423206 +0400
@@ -50,7 +50,7 @@
 #include <sysexits.h>
 #include <signal.h>
 
-#ifdef HAVE_OLD_QUEUE_H 
+#if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H) 
 #include "queue.h"
 #else 
 #include <sys/queue.h>
--- milter-greylist-4.4.2-orig/configure.ac	2013-01-08 18:30:01.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/configure.ac	2013-01-13 09:52:32.909409233 +0400
@@ -29,6 +29,16 @@
 AC_MSG_RESULT([$wall])
 CFLAGS=$SAVEDCFLAGS
 
+# Check that the compiler won't bug us for -Werror
+AC_MSG_CHECKING([if compiler accepts -Werror])
+SAVEDCFLAGS=$CFLAGS
+CFLAGS=$CFLAGS" -Werror"
+werror="no"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], 
+    [Werror="yes"; efl=$efl" -Werror"])
+AC_MSG_RESULT([$werror])
+CFLAGS=$SAVEDCFLAGS
+
 NORPSAVEDLDFLAGS=$LDFLAGS
 
 # Any linker will probably accept -L
@@ -65,9 +75,12 @@
 	[  --with-libpthread=DIR  Find libpthread in DIR],
 	[CFLAGS=$CFLAGS" -I$withval/include" 
 	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"])
+
+# Which BIND resolver to use?..
 use_libbind=no
 SAVEDLDFLAGS=$LDFLAGS
 SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
 AC_ARG_WITH(libbind, 
 	[  --with-libbind=DIR	Find libbind in DIR],
 	[CFLAGS=$CFLAGS" -I$withval/include/bind -I$withval/include"
@@ -75,12 +88,12 @@
 	    AC_CHECK_LIB(bind, bind9_getaddresses, [
 		SAVEDLDFLAGS=$LDFLAGS
 		SAVEDCFLAGS=$CFLAGS
-	    LIBS="-lbind $LIBS"
-	    use_libbind=yes
+		SAVEDLIBS="-lbind $LIBS"
+		use_libbind=yes
 	    ], [AC_CHECK_LIB(bind9, bind9_getaddresses, [
                 SAVEDLDFLAGS=$LDFLAGS
                 SAVEDCFLAGS=$CFLAGS
-                LIBS="-lbind9 $LIBS"
+                SAVEDLIBS="-lbind9 $LIBS"
                 use_libbind=yes
 	    ], [echo "neither -lbind nor -lbind9 worked. check config.log for details"
 		exit 1;])
@@ -88,14 +101,216 @@
 ])
 LDFLAGS=$SAVEDLDFLAGS
 CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
+# OpenSSL, may be needed by itself and for curl, ldap, dkim, ...
+dir_openssl=""
+LDFLAGS_openssl=""
+LIBS_openssl_ssl=""
+LIBS_openssl_crypto=""
+LIBS_openssl_ssh2=""
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
 AC_ARG_WITH(openssl,
-	[  --with-openssl=DIR  Find OpenSSL in DIR],
-	[LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"])
+	[  --with-openssl(=DIR)  Find OpenSSL in DIR],
+	[if test x"$withval" = xyes; then withval=""; fi
+	 if test -z "$withval"; then           
+            for _DIR in "/usr/local/ssl" "/usr/local" "/usr" "/usr/sfw" "/opt/sfw" "/"; do
+                if test -z "$withval" -a -e "$_DIR/lib/libssl.so"; then
+                    withval="$_DIR";          
+                    echo "autodetected OpenSSL library directory: $_DIR"
+                fi
+            done
+	fi
+	if test -z "$withval"; then
+	    echo "Error: path for OpenSSL libraries not provided and not autodetected!"
+	    exit 1
+        fi
+	LDFLAGS_openssl="-L$withval/lib -Wl,$rpath$withval/lib"
+	SAVEDLDFLAGS=$LDFLAGS" $LDFLAGS_openssl"
+        SAVEDCFLAGS=$CFLAGS" -I$withval/include"
+	dir_openssl="$withval"
+	LIBS_openssl_ssl="-lssl"
+	LIBS_openssl_crypto="-lcrypto"
+	SAVEDLIBS="$LIBS_openssl_ssl $LIBS_openssl_crypto $LIBS"
+	AC_CHECK_LIB(c -lssh2, main, [
+	    LIBS_openssl_ssh2="-lssh2 -lz"
+	    echo "autodetected libssh2: $LIBS_openssl_ssh2"
+	    SAVEDLIBS="$LIBS_openssl_ssh2 $SAVEDLIBS"],[])
+	])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
+AC_ARG_WITH(openssl-static,
+	[  --with-openssl-static(=DIR)  Find OpenSSL in DIR and link statically],
+	[if test x"$withval" = xyes; then withval=""; fi
+	if test -z "$withval"; then
+            for _DIR in "/usr/local/ssl" "/usr/local" "/usr" "/usr/sfw" "/opt/sfw" "/"; do
+                if test -z "$withval" -a -e "$_DIR/lib/libssl.a"; then
+                    withval="$_DIR";          
+                    echo "autodetected OpenSSL-static library directory: $_DIR"
+                fi
+            done
+	fi
+	if test -z "$withval"; then
+	    echo "Error: path for OpenSSL static libraries not provided and not autodetected!"
+	    exit 1
+        fi
+	LDFLAGS_openssl=""
+	SAVEDLDFLAGS=$LDFLAGS" $LDFLAGS_openssl"
+	SAVEDCFLAGS=$CFLAGS" -I$withval/include"
+	dir_openssl="$withval"
+	LIBS_openssl_ssl="$withval/lib/libssl.a"
+	LIBS_openssl_crypto="$withval/lib/libcrypto.a"
+	SAVEDLIBS="$LIBS_openssl_ssl $LIBS_openssl_crypto $LIBS"
+	_lib_ssh2=""
+	for _DIR in "/usr/local/ssl" "/usr/local" "/usr" "/usr/sfw" "/opt/sfw" "/"; do
+	    if test -z "$_lib_ssh2" -a -e "$_DIR/lib/libssh2.a"; then
+		_lib_ssh2="$_DIR/lib/libssh2.a"
+	    fi
+	done
+	if test -z "$_lib_ssh2"; then
+	    _lib_ssh2="-lssh2"
+	fi
+	AC_CHECK_LIB(c $_lib_ssh2, main, [
+	    LIBS_openssl_ssh2="$_lib_ssh2 -lz"
+	    echo "autodetected libssh2: $LIBS_openssl_ssh2"
+	    SAVEDLIBS="$LIBS_openssl_ssh2 $SAVEDLIBS"],[])
+	unset _lib_ssh2
+	])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
+# OpenLDAP may be used instead of curl to access multiple
+# (failover) LDAP catalog servers
+dir_openldap=""
+LDFLAGS_openldap=""
+LIBS_openldap=""
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
 AC_ARG_WITH(openldap, 
-	[  --with-openldap=DIR  Find OpenLDAP in DIR],
-	[CFLAGS=$CFLAGS" -I$withval/include -DUSE_LDAP -DLDAP_DEPRECATED" 
-	    LIBS="-lldap_r -llber $LIBS"
-	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"])
+	[  --with-openldap(=DIR)  Find OpenLDAP in DIR],
+	[if test x"$withval" = xyes; then withval=""; fi
+        if test -z "$withval"; then
+            for _DIR in "/usr/local" "/usr" "/usr/sfw" "/opt/sfw" "/"; do
+                if test -z "$withval" -a -e "$_DIR/lib/libldap_r-2.4.so" || \
+		   test -z "$withval" -a -e "$_DIR/lib/libldap_r.so"; then
+                    withval="$_DIR";
+                    echo "autodetected OpenLDAP library directory: $_DIR"
+                fi
+            done
+        fi
+	if test -z "$withval"; then
+	    echo "Error: path for OpenLDAP libraries not provided and not autodetected!"
+	    exit 1
+        fi
+	    SAVEDCFLAGS=$CFLAGS" -I$withval/include -DUSE_LDAP -DLDAP_DEPRECATED" 
+	    LDFLAGS_openldap="-L$withval/lib -Wl,$rpath$withval/lib"
+	    SAVEDLDFLAGS=$LDFLAGS" $LDFLAGS_openldap"
+	    dir_openldap="$withval"
+	    if test -d "$dir_openldap/include/openldap"; then
+		### Promote this include path
+		SAVEDCFLAGS="-I$dir_openldap/include/openldap $SAVEDCFLAGS"
+	    fi
+            ### Pick variants of more important libs that may be needed by LDAP
+            _ldap_LIBS="-lldap_r-2.4 -llber-2.4"
+            AC_CHECK_LIB(c $_ldap_LIBS, ldap_search, [
+               SAVEDLIBS="$_ldap_LIBS $LIBS"
+	       LIBS_openldap="$_ldap_LIBS"
+               ],[_ldap_LIBS="-lldap_r -llber"
+                       AC_CHECK_LIB([c $_ldap_LIBS], ldap_search, [
+                       SAVEDLIBS="$_ldap_LIBS $LIBS"
+		       LIBS_openldap="$_ldap_LIBS"
+		       ],[echo "Error: no OpenLDAP library names located!"; exit 1;])
+	       ])
+	])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
+# Try to configure for openldap-static
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
+AC_ARG_WITH(openldap-static,
+       [  --with-openldap-static(=DIR)  Find OpenLDAP in DIR and link statically],
+       [if test x"$withval" = xyes; then withval=""; fi
+	if test -z "$withval"; then
+	    for _DIR in "/usr/local" "/usr" "/usr/sfw" "/opt/sfw" "/"; do
+		if test -z "$withval" -a -e "$_DIR/lib/libldap_r-2.4.a" || \
+		   test -z "$withval" -a -e "$_DIR/lib/libldap_r.a"; then
+		    withval="$_DIR";
+		    echo "autodetected OpenLDAP library directory: $_DIR"
+		fi
+	    done
+	fi
+	if test -z "$withval"; then
+	    echo "Error: path for OpenLDAP static libraries not provided and not autodetected!"
+	    exit 1
+        fi
+	   dir_openldap="$withval"
+	   LDFLAGS_openldap=""
+	   SAVEDLDFLAGS=$LDFLAGS" $LDFLAGS_openldap"
+	   SAVEDCFLAGS=$CFLAGS" -I$withval/include -DUSE_LDAP -DLDAP_DEPRECATED"
+	   SAVEDLIBS="$LIBS"
+	   if test -d "$dir_openldap/include/openldap"; then
+		### Promote this include path
+		SAVEDCFLAGS="-I$dir_openldap/include/openldap $SAVEDCFLAGS"
+	   fi
+	   ### Lower-priority variants first; in case of conflicts use the later one
+	   if test -e "$withval/lib/libldap_r.a"; then
+		LIBS_openldap="$withval/lib/libldap_r.a $withval/lib/liblber.a"
+	   fi
+	   if test -e "$withval/lib/libldap_r-2.4.a"; then
+		LIBS_openldap="$withval/lib/libldap_r-2.4.a $withval/lib/liblber-2.4.a"
+	   fi
+	   if test -z "$LIBS_openldap"; then
+		echo "Error: searched for OpenLDAP static libraries in dir '$withval/lib', not found"
+		exit 1
+	   fi
+	   LIBS_openldap_add=""
+	   ### More generic libs
+	   for L in nsl socket gss dl resolv; do
+		AC_CHECK_LIB(c -l$L, main, [LIBS_openldap_add="-l$L $LIBS_openldap_add"])
+	   done
+	   ### Pick variants of more important libs that may be needed by LDAP
+	   _ldap_LIBS="$LIBS_openldap"
+           AC_CHECK_LIB(c $_ldap_LIBS, ldap_search, [
+               SAVEDLIBS="$_ldap_LIBS $LIBS"
+               ],[_ldap_LIBS="$LIBS_openldap $LIBS_openldap_add -lsasl"
+		       AC_CHECK_LIB([c $_ldap_LIBS], ldap_search, [
+                       SAVEDLIBS="$_ldap_LIBS $LIBS"
+               ],[_ldap_LIBS="$LIBS_openldap $LIBS_openldap_add -lsasl2"
+		       AC_CHECK_LIB([c $_ldap_LIBS], ldap_search, [
+                       SAVEDLIBS="$_ldap_LIBS $LIBS"
+               ],[_ldap_LIBS="$LIBS_openldap $LIBS_openldap_add -lsasl $LDFLAGS_openssl $LIBS_openssl_crypto $LIBS_openssl_ssl"
+		       AC_CHECK_LIB([c $_ldap_LIBS], ldap_search, [
+                       SAVEDLIBS="$_ldap_LIBS $LIBS"
+               ],[_ldap_LIBS="$LIBS_openldap $LIBS_openldap_add -lsasl2 $LDFLAGS_openssl $LIBS_openssl_crypto $LIBS_openssl_ssl"
+		       AC_CHECK_LIB([c $_ldap_LIBS], ldap_search, [
+                       SAVEDLIBS="$_ldap_LIBS $LIBS"
+        	   ], [echo "OpenLDAP static libraries libldap_r.a and/or liblber.a, or their shared";
+		       echo "  dependencies (SASL, OpenSSL, GSS) were not found, check config.log for details";
+            	       echo "Remove --with-openldap-static to build without LDAP support, or";
+		       echo "  try --with-openldap for the shared library, or";
+		       echo "  try --with-curl for an alternate solution";
+            	       exit 1;])
+	       ])
+	       ])
+	       ])
+       ])
+])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
 use_libcurl=no
 AC_ARG_WITH(libcurl, 
 	[  --with-libcurl=DIR  Find libcurl in DIR],
@@ -103,6 +318,40 @@
 	    LIBS="-lcurl $LIBS"
 	    LDFLAGS=$LDFLAGS" -L$withval/lib -Wl,$rpath$withval/lib"
 	    use_libcurl=yes])
+
+# Try to configure for libcurl-static
+SAVEDLDFLAGS=$LDFLAGS
+SAVEDCFLAGS=$CFLAGS
+SAVEDLIBS=$LIBS
+AC_ARG_WITH(libcurl-static,
+       [  --with-libcurl-static=DIR  Find libcurl in DIR and link statically],
+       [SAVEDLDFLAGS=$LDFLAGS" -L$withval/lib"
+	   SAVEDCFLAGS=$CFLAGS" -I$withval/include -DUSE_CURL"
+	   _lib_idn=""
+	   AC_CHECK_LIB(idn, main, [echo "autodetected libidn, will use with libcurl"
+	       _lib_idn="-lidn"
+	       SAVEDLIBS=" $_lib_idn $LIBS"])
+	   LIBS=$SAVEDLIBS
+           AC_CHECK_LIB(curl $_lib_idn, Curl_connect, [
+               SAVEDLDFLAGS=$LDFLAGS
+               SAVEDCFLAGS=$CFLAGS
+               SAVEDLIBS="$withval/lib/libcurl.a $LIBS"
+	       use_libcurl=yes
+               ],[AC_CHECK_LIB([curl $_lib_idn $LIBS_openssl_ssh2],  Curl_connect, [
+                       SAVEDLDFLAGS=$LDFLAGS
+                       SAVEDCFLAGS=$CFLAGS
+                       SAVEDLIBS="$withval/lib/libcurl.a $LIBS_openssl_ssh2 $LIBS"
+		       use_libcurl=yes
+               ], [echo "static library libcurl.a and/or libssh2.a not found, check config.log for details";
+                   echo "Remove --with-libcurl-static to build without CURL support ";
+		   echo "  or try --with-libcurl for the shared library";
+                   exit 1;])
+       ])
+])
+LDFLAGS=$SAVEDLDFLAGS
+CFLAGS=$SAVEDCFLAGS
+LIBS=$SAVEDLIBS
+
 AC_ARG_WITH(libGeoIP, 
 	[  --with-libGeoIP=DIR  Find libGeoIP in DIR],
 	[CFLAGS=$CFLAGS" -I$withval/include -DUSE_GEOIP" 
@@ -116,7 +365,7 @@
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h sys/param.h netdb.h getopt.h sys/cdefs.h arpa/nameser.h stdbool.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h sys/param.h netdb.h getopt.h sys/cdefs.h arpa/nameser.h stdbool.h sys/queue.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_PID_T
@@ -147,20 +396,25 @@
 	AC_MSG_CHECKING([if -lcurl needs -lcrypto to link and run])
 	lcurl_needs_lcrypto=no
 	SAVEDLIBS=$LIBS
+	SAVEDLDFLAGS=$LDFLAGS
 	AC_RUN_IFELSE([AC_LANG_PROGRAM([],[])], 
 	    [],
-	    [
-		LIBS="-lcrypto $LIBS"
+	    [LDFLAGS="$LDFLAGS $LDFLAGS_openssl"
+		LIBS="$LIBS_openssl_crypto $LIBS"
 		AC_RUN_IFELSE([AC_LANG_PROGRAM([],[])],
-		    [lcurl_needs_lcrypto=yes],
-			[echo "Required libcrypto not found for libcurl. Use --with-openssl=DIR to provide the OpenSSL installation root.";
+		    [lcurl_needs_lcrypto=yes
+		    SAVEDLIBS=$LIBS],
+			[echo "Required libcrypto not found for libcurl.";
+			 echo "  Use --with-openssl=DIR to provide the OpenSSL installation root.";
                 	 exit 1;])
 	    ])
 	if test $lcurl_needs_lcrypto = yes ; then
 		SAVEDLIBS=$LIBS
+		SAVEDLDFLAGS=$LDFLAGS
 	fi
 	AC_MSG_RESULT($lcurl_needs_lcrypto)
 	LIBS=$SAVEDLIBS
+	LDFLAGS=$SAVEDLDFLAGS
 fi
 
 # Checks for library functions.
@@ -212,11 +466,11 @@
 LDFLAGS=$SAVEDLDFLAGS
 CFLAGS=$SAVEDCFLAGS
 
-# Try to configure for libspf2static
+# Try to configure for libspf2-static
 SAVEDLDFLAGS=$LDFLAGS
 SAVEDCFLAGS=$CFLAGS
-AC_ARG_WITH(libspf2static,
-       [  --with-libspf2static=DIR  Find libspf2 in DIR],
+AC_ARG_WITH(libspf2-static,
+       [  --with-libspf2-static=DIR  Find libspf2 in DIR and link statically],
        [LDFLAGS=$LDFLAGS" -L$withval/lib"
 	   CFLAGS=$CFLAGS" -I$withval/include"
            AC_CHECK_LIB(spf2, SPF_server_new, [
@@ -230,7 +484,8 @@
                        LIBS=$LIBS" $withval/lib/libspf2.a -lintl"
                        AC_DEFINE([HAVE_SPF2], [], [we use libspf2])
                ], [echo "static library libspf2.a not found, check config.log for details"
-                   echo "Remove --with-libspf2static to build without SPF support or try --with-libspf2 for the shared library"
+                   echo "Remove --with-libspf2-static to build without SPF support "
+		   echo "  or try --with-libspf2 for the shared library"
                    exit 1;])
        ])
 ])
@@ -464,6 +719,7 @@
 AC_MSG_CHECKING([if -D_REENTRANT is needed to use localtime_r and strtok_r])
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
                #include <time.h>
+               #include <string.h>
                #include <stdio.h>
        ],[[
 
@@ -472,6 +728,8 @@
        ]])], [dreentrant=no],
                [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
                                #define _REENTRANT
+                               #include <time.h>
+                               #include <string.h>
                                #include <stdio.h>
                        ],[[
                                 (void)localtime_r(NULL, NULL);
@@ -571,6 +829,7 @@
 LIBS=$SAVEDLIBS
 AC_MSG_RESULT([$pthend])
 
+# Solaris 8 has no <sys/queue.h> at all - headers checked above
 # Some Linux flavors have an outdated <sys/queue.h>
 AC_MSG_CHECKING([if <sys/queue.h> is outdated])
 oldqueue=no
@@ -580,6 +839,9 @@
 		#ifndef TAILQ_FIRST
 		error Your <sys/queue.h> is outdated
 		#endif
+		#ifndef SIMPLEQ_REMOVE
+		error Your <sys/queue.h> is outdated
+		#endif
 	])], [oldqueue=no], 
 	[AC_DEFINE([HAVE_OLD_QUEUE_H], [], [old <sys/queue.h>]) oldqueue=yes])
 AC_MSG_RESULT([$oldqueue])
-------------- next part --------------
diff -Naur milter-greylist-4.4.2-orig/Makefile.in milter-greylist-4.4.2-jimbuild/Makefile.in
--- milter-greylist-4.4.2-orig/Makefile.in	2010-07-13 08:18:06.000000000 +0400
+++ milter-greylist-4.4.2-jimbuild/Makefile.in	2013-01-19 23:18:38.089620115 +0400
@@ -45,6 +45,12 @@
 CONFFILE=       @CONFFILE@
 DUMPFILE=       @DUMPFILE@
 
+# This may be too ad-hoc relying on GNU make, though many others respect -j...
+# Ultimately this syntax should be autoconfigured...
+# NOTE: Sun CCS make insists on a space "-j 1" instead of "-j1" ok for gmake.
+MAKESEQ=        $(MAKE) -j 1
+#MAKESEQ=       MAKEFLAGS= $(MAKE) -j 1 MAKEFLAGS=
+
 CC=		@CC@
 MKDEP=		@MKDEP@
 RM=		@RM@
@@ -55,11 +61,14 @@
 LEX=		@LEX@
 YACC=		@YACC@
 TRUE=		@TRUE@
+TOUCH=		@TOUCH@
 
 OBJ= 		milter-greylist.o pending.o sync.o dnsrbl.o list.o macro.o \
-		conf_yacc.o dump_yacc.o conf.o store.o dump.o spf.o \
+		conf.o store.o dump.o spf.o \
 		acl.o urlcheck.o stat.o clock.o geoip.o fd_pool.o prop.o \
 		ldapcheck.o dkimcheck.o p0f.o spamd.o mx.o ratelimit.o
+OBJ_SEQ=	conf_yacc.o dump_yacc.o
+OBJ_SEQ_FLAG=	.objseq-built
 SRC= 		milter-greylist.c pending.c sync.c conf.c macro.c stat.c \
 		clock.c store.c dump.c spf.c acl.c dnsrbl.c list.c \
 		urlcheck.c geoip.c prop.c ldapcheck.c dkimcheck.c p0f.c \
@@ -71,8 +80,28 @@
 all:		milter-greylist rc-bsd.sh rc-redhat.sh \
 		rc-solaris.sh rc-debian.sh rc-gentoo.sh rc-suse.sh
 
-milter-greylist:	${OBJ}
-	${CC} -o milter-greylist ${OBJ} ${LDFLAGS} ${LIBS}
+# GNU make: targets which are not expected to produce same-named files
+.PHONY:		bld-milter-greylist obj-seq bld-seq all-seq
+#		all clean realclean distclean install \
+
+milter-greylist:	${OBJ} ${OBJ_SEQ_FLAG}
+	@echo "=== Linking $@:"
+	${CC} -o $@ ${OBJ} ${OBJ_SEQ} ${LDFLAGS} ${LIBS}
+
+# The idea is that a successful obj-seq build would produce the flag-file,
+# thus "milter-greylist"'s verifiable dependencies are satisfied and the
+# binary is not relinked on every make run. However, code updates that can
+# cause rebuilds of ${OBJ_SEQ} files might require a "gmake rebuild" now.
+${OBJ_SEQ_FLAG}:	obj-seq
+	sync || $(TRUE)
+
+all-seq:	obj-seq
+obj-seq:
+	@echo "=== Call make sequential for objects sensitive to that (current make='$(MAKE)' MAKEFLAGS='$(MAKEFLAGS)'):"
+	$(MAKESEQ) bld-seq
+
+bld-seq:	${OBJ_SEQ}
+	$(TEST) -f ${OBJ_SEQ_FLAG} || $(TOUCH) ${OBJ_SEQ_FLAG}
 
 sync_yacc.o:	sync_yacc.c sync_lex.c
 conf_yacc.o:	conf_yacc.c conf_lex.c
@@ -81,17 +110,17 @@
 sed_subst = "s|@BINDIR[@]|${BINDIR}|g; s|@SBINDIR[@]|${SBINDIR}|g; s|@USER[@]|${USER}|g"
 
 rc-bsd.sh:      rc-bsd.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-bsd.sh.in > rc-bsd.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 rc-redhat.sh:    rc-redhat.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-redhat.sh.in > rc-redhat.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 rc-solaris.sh:    rc-solaris.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-solaris.sh.in > rc-solaris.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 rc-debian.sh:    rc-debian.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-debian.sh.in > rc-debian.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 rc-gentoo.sh:    rc-gentoo.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-gentoo.sh.in > rc-gentoo.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 rc-suse.sh:	 rc-suse.sh.in
-	${SED} ${sed_subst} ${SRCDIR}/rc-suse.sh.in > rc-suse.sh
+	${SED} ${sed_subst} ${SRCDIR}/$< > $@
 
 install-daemon-to-bin: milter-greylist
 	${INSTALL} -d -m 755 ${DESTDIR}${BINDIR}
@@ -136,13 +165,26 @@
 	${MKDEP} ${CPPFLAGS} ${CFLAGS} ${SRC}
 
 clean:
-	${RM} -f milter-greylist ${OBJ} ${GENSRC} \
-	rc-redhat.sh rc-bsd.sh rc-solaris.sh rc-debian.sh rc-gentoo.sh \
-	rc-suse.sh
+	${RM} -f milter-greylist ${OBJ} ${OBJ_SEQ} ${OBJ_SEQ_FLAG} ${GENSRC} \
+		rc-redhat.sh rc-bsd.sh rc-solaris.sh rc-debian.sh rc-gentoo.sh \
+		rc-suse.sh y.tab.c
+	sync || $(TRUE)
 
 realclean:	clean
 	${RM} -Rf Makefile config.h config.log config.status \
 		 autom4te.cache configure.lineno *.orig *.bak autoscan.log
+	sync || $(TRUE)
+
+distclean:	realclean
+
+rebuild:	clean
+	@echo "=== Making all. MAKEFLAGS=$(MAKEFLAGS)"
+	@$(MAKE) all || ( \
+		echo "==============================================================="; \
+		echo "=== First build failed. Making all sequentially just in case..."; \
+		echo "==============================================================="; \
+		sync || $(TRUE); \
+		$(MAKESEQ) all )
 
 .SUFFIXES:	.o .c .h .y .l
 .l.c:


More information about the OpenIndiana-discuss mailing list