Blob Blame History Raw
diff -uNr exim-4.69-old/Makefile exim-4.69/Makefile
--- exim-4.69-old/Makefile	2005-09-12 14:55:54.000000000 +0100
+++ exim-4.69/Makefile	2008-08-13 15:30:05.000000000 +0100
@@ -80,11 +80,11 @@
 	cd build-$(buildname); \
 	$(RM_COMMAND) -f *.o lookups/*.o lookups/*.a auths/*.o auths/*.a \
 	routers/*.o routers/*.a transports/*.o transports/*.a \
-	pcre/*.o pcre/*.a
+	pcre/*.o pcre/*.a lookups/*.so
 
 clean_exim:; cd build-$(buildname); \
 	 $(RM_COMMAND) -f *.o lookups/*.o lookups/*.a auths/*.o auths/*.a \
-	routers/*.o routers/*.a transports/*.o transports/*.a
+	routers/*.o routers/*.a transports/*.o transports/*.a lookups/*.so
 
 distclean:; $(RM_COMMAND) -rf build-*
 
diff -uNr exim-4.69-old/OS/Makefile-Base exim-4.69/OS/Makefile-Base
--- exim-4.69-old/OS/Makefile-Base	2008-08-13 15:29:21.000000000 +0100
+++ exim-4.69/OS/Makefile-Base	2008-08-13 15:30:05.000000000 +0100
@@ -311,6 +311,7 @@
         rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \
         route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \
         store.o string.o tls.o tod.o transport.o tree.o verify.o \
+        lookups/lf_quote.o lookups/lf_check_file.o lookups/lf_sqlperform.o \
         local_scan.o $(EXIM_PERL) $(OBJ_WITH_CONTENT_SCAN) \
         $(OBJ_WITH_OLD_DEMIME) $(OBJ_EXPERIMENTAL)
 
diff -uNr exim-4.69-old/scripts/Configure-Makefile exim-4.69/scripts/Configure-Makefile
--- exim-4.69-old/scripts/Configure-Makefile	2008-08-13 15:29:21.000000000 +0100
+++ exim-4.69/scripts/Configure-Makefile	2008-08-13 15:30:05.000000000 +0100
@@ -107,7 +107,7 @@
             echo "# End of $f"
             echo ""
      fi
-done >> $mft || exit 1
+done | sed 's/^LOOKUP_/export LOOKUP_/' >> $mft || exit 1
 
 # See if there is a definition of EXIM_PERL in what we have built so far.
 # If so, run Perl to find the default values for PERL_CC, PERL_CCOPTS,
diff -uNr exim-4.69-old/scripts/MakeLinks exim-4.69/scripts/MakeLinks
--- exim-4.69-old/scripts/MakeLinks	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/scripts/MakeLinks	2008-08-13 15:30:05.000000000 +0100
@@ -204,6 +204,7 @@
 ln -s ../src/osfunctions.h     osfunctions.h
 ln -s ../src/store.h           store.h
 ln -s ../src/structs.h         structs.h
+ln -s ../src/lookupapi.h       lookupapi.h
 
 ln -s ../src/acl.c             acl.c
 ln -s ../src/buildconfig.c     buildconfig.c
diff -uNr exim-4.69-old/src/config.h.defaults exim-4.69/src/config.h.defaults
--- exim-4.69-old/src/config.h.defaults	2008-08-13 15:29:21.000000000 +0100
+++ exim-4.69/src/config.h.defaults	2008-08-13 15:30:05.000000000 +0100
@@ -92,6 +92,8 @@
 #define LOOKUP_WILDLSEARCH
 #define LOOKUP_NWILDLSEARCH
 
+#define LOOKUP_MODULE_DIR
+
 #define MAX_FILTER_SIZE           (1024*1024)
 #define MAX_LOCALHOST_NUMBER        256
 #define MAX_INCLUDE_SIZE          (1024*1024)
diff -uNr exim-4.69-old/src/drtables.c exim-4.69/src/drtables.c
--- exim-4.69-old/src/drtables.c	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/src/drtables.c	2008-08-13 15:30:05.000000000 +0100
@@ -10,6 +10,8 @@
 
 #include "exim.h"
 
+#include <dlfcn.h>
+#include <string.h>
 
 /* This module contains tables that define the lookup methods and drivers
 that are actually included in the binary. Its contents are controlled by
@@ -31,535 +33,8 @@
 
 static void dummy(int x) { dummy(x-1); }
 
-
-/* Table of information about all possible lookup methods. The entries are
-always present, but the "open" and "find" functions are set to NULL for those
-that are not compiled into the binary. The "check" and "close" functions can
-be NULL for methods that don't need them. */
-
-#ifdef LOOKUP_CDB
-#include "lookups/cdb.h"
-#endif
-
-#ifdef LOOKUP_DBM
-#include "lookups/dbmdb.h"
-#endif
-
-#ifdef LOOKUP_DNSDB
-#include "lookups/dnsdb.h"
-#endif
-
-#ifdef LOOKUP_DSEARCH
-#include "lookups/dsearch.h"
-#endif
-
-#ifdef LOOKUP_IBASE
-#include "lookups/ibase.h"
-#endif
-
-#ifdef LOOKUP_LDAP
-#include "lookups/ldap.h"
-#endif
-
-#ifdef LOOKUP_LSEARCH
-#include "lookups/lsearch.h"
-#endif
-
-#ifdef LOOKUP_MYSQL
-#include "lookups/mysql.h"
-#endif
-
-#ifdef LOOKUP_NIS
-#include "lookups/nis.h"
-#endif
-
-#ifdef LOOKUP_NISPLUS
-#include "lookups/nisplus.h"
-#endif
-
-#ifdef LOOKUP_ORACLE
-#include "lookups/oracle.h"
-#endif
-
-#ifdef LOOKUP_PASSWD
-#include "lookups/passwd.h"
-#endif
-
-#ifdef LOOKUP_PGSQL
-#include "lookups/pgsql.h"
-#endif
-
-#ifdef EXPERIMENTAL_SPF
-#include "lookups/spf.h"
-#endif
-
-#ifdef LOOKUP_SQLITE
-#include "lookups/sqlite.h"
-#endif
-
-#ifdef LOOKUP_TESTDB
-#include "lookups/testdb.h"
-#endif
-
-#ifdef LOOKUP_WHOSON
-#include "lookups/whoson.h"
-#endif
-
-#ifdef EXPERIMENTAL_DKIM
-#include "lookups/dkim.h"
-#endif
-
-
-/* The second field in each item below is a set of bit flags:
-
-  lookup_querystyle     => this is a query-style lookup,
-                             else single-key (+ file) style
-  lookup_absfile        => an absolute file name is required,
-                             (for single-key style only)
-
-This list must be in alphabetical order of lookup name because it is
-searched by binary chop, having got rather large for the original linear
-searching. */
-
-lookup_info lookup_list[] = {
-
-/* cdb lookup in single file */
-
-  {
-  US"cdb",                       /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_CDB
-  cdb_open,                      /* open function */
-  cdb_check,                     /* check function */
-  cdb_find,                      /* find function */
-  cdb_close,                     /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* DBM file lookup; called "dbm" because that is the name in Exim,
-but the code is called dbmdb to avoid name clashes. */
-
-  {
-  US"dbm",                       /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_DBM
-  dbmdb_open,                    /* open function */
-  dbmdb_check,                   /* check function */
-  dbmdb_find,                    /* find function */
-  dbmdb_close,                   /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* This variant of DBM does not include the binary zero on the end
-of the key strings. */
-
-  {
-  US"dbmnz",                     /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_DBM
-  dbmdb_open,      /* sic */     /* open function */
-  dbmdb_check,     /* sic */     /* check function */
-  dbmnz_find,                    /* find function */
-  dbmdb_close,     /* sic */     /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* DKIM lookups */
-
-  {
-  US"dkim",                      /* lookup name */
-  lookup_querystyle,             /* query style */
-#ifdef EXPERIMENTAL_DKIM
-  dkim_open,                     /* open function */
-  NULL,                          /* check function */
-  dkim_find,                     /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Using DNS TXT records as a database */
-
-  {
-  US"dnsdb",                     /* lookup name */
-  lookup_querystyle,             /* query style */
-#ifdef LOOKUP_DNSDB
-  dnsdb_open,                    /* open function */
-  NULL,                          /* check function */
-  dnsdb_find,                    /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Search of files in a directory */
-
-  {
-  US"dsearch",                   /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_DSEARCH
-  dsearch_open,                  /* open function */
-  dsearch_check,                 /* check function */
-  dsearch_find,                  /* find function */
-  dsearch_close,                 /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Interbase lookup */
-
-  {
-  US"ibase",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_IBASE
-  ibase_open,                    /* open function */
-  NULL,                          /* no check function */
-  ibase_find,                    /* find function */
-  NULL,                          /* no close function */
-  ibase_tidy,                    /* tidy function */
-  ibase_quote                    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Linear search of single file with ip-addresses and networks; shares many
-functions with lsearch. */
-
-  {
-  US"iplsearch",                 /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_LSEARCH
-  lsearch_open,                  /* open function */
-  lsearch_check,                 /* check function */
-  iplsearch_find,                /* find function */
-  lsearch_close,                 /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* LDAP lookup, allowing data from only one entry to be returned */
-
-  {
-  US"ldap",                      /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_LDAP
-  eldap_open,                    /* open function */
-  NULL,                          /* check function */
-  eldap_find,                    /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,                    /* tidy function */
-  eldap_quote                    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* LDAP lookup, allowing the DN from more one entry to be returned */
-
-  {
-  US"ldapdn",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_LDAP
-  eldap_open,       /* sic */    /* open function */
-  NULL,                          /* check function */
-  eldapdn_find,                  /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,       /* sic */    /* tidy function */
-  eldap_quote       /* sic */    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* LDAP lookup, allowing data from more than one entry to be returned */
-
-  {
-  US"ldapm",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_LDAP
-  eldap_open,       /* sic */    /* open function */
-  NULL,                          /* check function */
-  eldapm_find,                   /* find function */
-  NULL,                          /* no close function */
-  eldap_tidy,       /* sic */    /* tidy function */
-  eldap_quote       /* sic */    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Linear search of single file */
-
-  {
-  US"lsearch",                   /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_LSEARCH
-  lsearch_open,                  /* open function */
-  lsearch_check,                 /* check function */
-  lsearch_find,                  /* find function */
-  lsearch_close,                 /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* MYSQL lookup */
-
-  {
-  US"mysql",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_MYSQL
-  mysql_open,                    /* open function */
-  NULL,                          /* no check function */
-  mysql_find,                    /* find function */
-  NULL,                          /* no close function */
-  mysql_tidy,                    /* tidy function */
-  mysql_quote                    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* NIS lookup, excluding trailing 0 from key */
-
-  {
-  US"nis",                       /* lookup name */
-  0,                             /* not abs file, not query style*/
-#ifdef LOOKUP_NIS
-  nis_open,                      /* open function */
-  NULL,                          /* check function */
-  nis_find,                      /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* NIS lookup, including trailing 0 in key */
-
-  {
-  US"nis0",                      /* lookup name */
-  0,                             /* not absfile, not query style */
-#ifdef LOOKUP_NIS
-  nis_open,    /* sic */         /* open function */
-  NULL,                          /* check function */
-  nis0_find,                     /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* NIS+ lookup */
-
-  {
-  US"nisplus",                   /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_NISPLUS
-  nisplus_open,                  /* open function */
-  NULL,                          /* check function */
-  nisplus_find,                  /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  nisplus_quote                  /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Linear search of single file, with wildcarding but no pattern expansion.
-Shares many functions with lsearch. */
-
-  {
-  US"nwildlsearch",              /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_LSEARCH
-  lsearch_open,                  /* open function */
-  lsearch_check,                 /* check function */
-  nwildlsearch_find,             /* find function */
-  lsearch_close,                 /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Oracle lookup */
-
-  {
-  US"oracle",                    /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_ORACLE
-  oracle_open,                   /* open function */
-  NULL,                          /* check function */
-  oracle_find,                   /* find function */
-  NULL,                          /* no close function */
-  oracle_tidy,                   /* tidy function */
-  oracle_quote                   /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* passwd lookup */
-
-  {
-  US"passwd",                    /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_PASSWD
-  passwd_open,                   /* open function */
-  NULL,                          /* no check function */
-  passwd_find,                   /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL   /* lookup not present */
-#endif
-  },
-
-/* PGSQL lookup */
-
-  {
-  US"pgsql",                     /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_PGSQL
-  pgsql_open,                    /* open function */
-  NULL,                          /* no check function */
-  pgsql_find,                    /* find function */
-  NULL,                          /* no close function */
-  pgsql_tidy,                    /* tidy function */
-  pgsql_quote                    /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL   /* lookup not present */
-#endif
-  },
-
-/* SPF lookup */
-
-  {
-  US"spf",                       /* lookup name */
-  0,                             /* not absfile, not query style */
-#ifdef EXPERIMENTAL_SPF
-  spf_open,                      /* open function */
-  NULL,                          /* no check function */
-  spf_find,                      /* find function */
-  spf_close,                     /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* sqlite lookup */
-
-  {
-  US"sqlite",                    /* lookup name */
-  lookup_absfilequery,           /* query-style lookup, starts with file name */
-#ifdef LOOKUP_SQLITE
-  sqlite_open,                   /* open function */
-  NULL,                          /* no check function */
-  sqlite_find,                   /* find function */
-  sqlite_close,                  /* close function */
-  NULL,                          /* no tidy function */
-  sqlite_quote                   /* quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  },
-
-/* Testdb lookup is for testing Exim, not useful for normal running.
-For that reason, we omit the entry entirely when not building it into
-the binary, so that attempts to use it give "unknown lookup type" instead
-of "lookup type not available". */
-
-#ifdef LOOKUP_TESTDB
-  {
-  US"testdb",                    /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-  testdb_open,                   /* open function */
-  NULL,                          /* check function */
-  testdb_find,                   /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-  },
-#endif
-
-/* "Whoson" lookup */
-
-  {
-  US"whoson",                    /* lookup name */
-  lookup_querystyle,             /* query-style lookup */
-#ifdef LOOKUP_WHOSON
-  whoson_open,                   /* open function */
-  NULL,                          /* check function */
-  whoson_find,                   /* find function */
-  NULL,                          /* no close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL   /* lookup not present */
-#endif
-  },
-
-/* Linear search of single file, with wildcarding and pattern expansion. Shares
-many functions with lsearch. */
-
-  {
-  US"wildlsearch",               /* lookup name */
-  lookup_absfile,                /* uses absolute file name */
-#ifdef LOOKUP_LSEARCH
-  lsearch_open,                  /* open function */
-  lsearch_check,                 /* check function */
-  wildlsearch_find,              /* find function */
-  lsearch_close,                 /* close function */
-  NULL,                          /* no tidy function */
-  NULL                           /* no quoting function */
-#else
-  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
-#endif
-  }
-};
-
-/* Number of entries in the list */
-
-int lookup_list_count = sizeof(lookup_list)/sizeof(lookup_info);
-
-
+lookup_info **lookup_list;
+int lookup_list_count = 0;
 
 /* Table of information about all possible authentication mechamisms. All
 entries are always present if any mechanism is declared, but the functions are
@@ -887,4 +362,226 @@
 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
 };
 
+struct lookupmodulestr
+{
+  void *dl;
+  struct lookup_module_info *info;
+  struct lookupmodulestr *next;
+};
+
+static struct lookupmodulestr *lookupmodules = NULL;
+
+static void addlookupmodule(void *dl, struct lookup_module_info *info)
+{
+  struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
+  p->dl = dl;
+  p->info = info;
+  p->next = lookupmodules;
+  lookupmodules = p;
+  lookup_list_count += info->lookupcount;
+}
+
+/* only valid after lookup_list and lookup_list_count are assigned */
+static void add_lookup_to_list(lookup_info *info)
+{
+  /* need to add the lookup to lookup_list, sorted */
+  int pos = 0;
+
+  /* strategy is to go through the list until we find
+   * either an empty spot or a name that is higher.
+   * this can't fail because we have enough space. */
+  while (lookup_list[pos]
+      && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0)) {
+    pos++;
+  }
+  if (lookup_list[pos]) {
+    /* need to insert it, so move all the other items up
+     * (last slot is still empty, of course) */
+    memmove(&lookup_list[pos+1],
+            &lookup_list[pos],
+            sizeof(lookup_info **) * (lookup_list_count-pos-1));
+  }
+  lookup_list[pos] = info;
+}
+
+void init_lookup_list(void)
+{
+  DIR *dd;
+  struct dirent *ent;
+  const pcre *regex_islookupmod = regex_must_compile("\\.so$", FALSE, TRUE);
+  int countmodules = 0;
+  int moduleerrors = 0;
+  struct lookupmodulestr *p;
+
+#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
+extern lookup_module_info cdb_lookup_module_info;
+  addlookupmodule(NULL, &cdb_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
+extern lookup_module_info dbmdb_lookup_module_info;
+  addlookupmodule(NULL, &dbmdb_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_DKIM) && LOOKUP_DKIM!=2
+extern lookup_module_info dkim_lookup_module_info;
+  addlookupmodule(NULL, &dkim_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
+extern lookup_module_info dnsdb_lookup_module_info;
+  addlookupmodule(NULL, &dnsdb_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
+extern lookup_module_info dsearch_lookup_module_info;
+  addlookupmodule(NULL, &dsearch_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
+extern lookup_module_info ibase_lookup_module_info;
+  addlookupmodule(NULL, &ibase_lookup_module_info);
+#endif
+
+#ifdef LOOKUP_LDAP
+extern lookup_module_info ldap_lookup_module_info;
+  addlookupmodule(NULL, &ldap_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
+extern lookup_module_info lsearch_lookup_module_info;
+  addlookupmodule(NULL, &lsearch_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
+extern lookup_module_info mysql_lookup_module_info;
+  addlookupmodule(NULL, &mysql_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
+extern lookup_module_info nis_lookup_module_info;
+  addlookupmodule(NULL, &nis_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
+extern lookup_module_info nisplus_lookup_module_info;
+  addlookupmodule(NULL, &nisplus_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
+extern lookup_module_info oracle_lookup_module_info;
+  addlookupmodule(NULL, &oracle_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
+extern lookup_module_info passwd_lookup_module_info;
+  addlookupmodule(NULL, &passwd_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
+extern lookup_module_info pgsql_lookup_module_info;
+  addlookupmodule(NULL, &pgsql_lookup_module_info);
+#endif
+
+#ifdef EXPERIMENTAL_SPF
+extern lookup_module_info spf_lookup_module_info;
+  addlookupmodule(NULL, &spf_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
+extern lookup_module_info sqlite_lookup_module_info;
+  addlookupmodule(NULL, &sqlite_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
+extern lookup_module_info testdb_lookup_module_info;
+  addlookupmodule(NULL, &testdb_lookup_module_info);
+#endif
+
+#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
+extern lookup_module_info whoson_lookup_module_info;
+  addlookupmodule(NULL, &whoson_lookup_module_info);
+#endif
+
+#ifdef LOOKUP_MODULE_DIR
+  dd = opendir(LOOKUP_MODULE_DIR);
+  if (dd == NULL) {
+    DEBUG(5) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
+  }
+  else {
+    DEBUG(9) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
+    while ((ent = readdir(dd)) != NULL) {
+      char *name = ent->d_name;
+      int len = (int)strlen(name);
+      if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
+        int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
+        void *dl;
+        struct lookup_module_info *info;
+        char *errormsg;
+
+        /* SRH: am I being paranoid here or what? */
+        if (pathnamelen > big_buffer_size) {
+          fprintf(stderr, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
+          continue;
+        }
+
+        /* SRH: snprintf here? */
+        sprintf(big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
+
+        dl = dlopen(big_buffer, RTLD_NOW);// TJ was LAZY
+        if (dl == NULL) {
+          fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
+          moduleerrors++;
+          continue;
+        }
+
+        info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
+        if ((errormsg = dlerror()) != NULL) {
+          fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
+          dlclose(dl);
+          moduleerrors++;
+          continue;
+        }
+        if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
+          fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
+          dlclose(dl);
+          moduleerrors++;
+          continue;
+        }
+
+        addlookupmodule(dl, info);
+        DEBUG(9) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
+        countmodules++;
+      }
+    }
+    closedir(dd);
+  }
+
+  DEBUG(9) debug_printf("Loaded %d lookup modules\n", countmodules);
+#endif
+
+  store_free((void*)regex_islookupmod);
+
+  DEBUG(4) debug_printf("Total %d lookups\n", lookup_list_count);
+
+  lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
+  memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
+
+  /* now add all lookups to the real list */
+  p = lookupmodules;
+  while (p) {
+    int j;
+    struct lookupmodulestr *pnext;
+
+    for (j = 0; j < p->info->lookupcount; j++)
+      add_lookup_to_list(p->info->lookups[j]);
+
+    pnext = p->next;
+    store_free(p);
+    p = pnext;
+  }
+  /* just to be sure */
+  lookupmodules = NULL;
+}
+
 /* End of drtables.c */
diff -uNr exim-4.69-old/src/EDITME exim-4.69/src/EDITME
--- exim-4.69-old/src/EDITME	2008-08-13 15:29:21.000000000 +0100
+++ exim-4.69/src/EDITME	2008-08-13 15:30:05.000000000 +0100
@@ -248,6 +248,9 @@
 SUPPORT_MAILSTORE=yes
 SUPPORT_MBX=yes
 
+#------------------------------------------------------------------------------
+# See below for dynamic lookup modules.
+# LOOKUP_MODULE_DIR=/usr/lib/exim/lookups/
 
 #------------------------------------------------------------------------------
 # These settings determine which file and database lookup methods are included
@@ -257,6 +260,18 @@
 # LOOKUP_DNSDB does *not* refer to general mail routing using the DNS. It is
 # for the specialist case of using the DNS as a general database facility (not
 # common).
+# If set to "2" instead of "yes" then the corresponding lookup will be
+# built as a module and must be installed into LOOKUP_MODULE_DIR. You need to
+# add -export-dynamic -rdynamic to EXTRALIBS. You may also need to add -ldl to
+# EXTRALIBS so that dlopen() is available to Exim. You need to define
+# LOOKUP_MODULE_DIR above so the exim binary actually loads dynamic lookup
+# modules.
+# Also, instead of adding all the libraries/includes to LOOKUP_INCLUDE and
+# LOOKUP_LIBS, add them to the respective LOOKUP_*_INCLUDE and LOOKUP_*_LIBS
+# (where * is the name as given here in this list). That ensures that only
+# the dynamic library and not the exim binary will be linked against the
+# library.
+# NOTE: LDAP cannot be built as a module!
 
 LOOKUP_DBM=yes
 LOOKUP_LSEARCH=yes
diff -uNr exim-4.69-old/src/exim.c exim-4.69/src/exim.c
--- exim-4.69-old/src/exim.c	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/src/exim.c	2008-08-13 15:30:05.000000000 +0100
@@ -925,53 +925,53 @@
 #endif
 fprintf(f, "\n");
 
-fprintf(f, "Lookups:");
-#ifdef LOOKUP_LSEARCH
+fprintf(f, "Lookups (built-in):");
+#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
   fprintf(f, " lsearch wildlsearch nwildlsearch iplsearch");
 #endif
-#ifdef LOOKUP_CDB
+#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
   fprintf(f, " cdb");
 #endif
-#ifdef LOOKUP_DBM
+#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
   fprintf(f, " dbm dbmnz");
 #endif
-#ifdef LOOKUP_DNSDB
+#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
   fprintf(f, " dnsdb");
 #endif
-#ifdef LOOKUP_DSEARCH
+#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
   fprintf(f, " dsearch");
 #endif
-#ifdef LOOKUP_IBASE
+#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
   fprintf(f, " ibase");
 #endif
-#ifdef LOOKUP_LDAP
+#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
   fprintf(f, " ldap ldapdn ldapm");
 #endif
-#ifdef LOOKUP_MYSQL
+#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
   fprintf(f, " mysql");
 #endif
-#ifdef LOOKUP_NIS
+#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
   fprintf(f, " nis nis0");
 #endif
-#ifdef LOOKUP_NISPLUS
+#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
   fprintf(f, " nisplus");
 #endif
-#ifdef LOOKUP_ORACLE
+#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
   fprintf(f, " oracle");
 #endif
-#ifdef LOOKUP_PASSWD
+#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
   fprintf(f, " passwd");
 #endif
-#ifdef LOOKUP_PGSQL
+#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
   fprintf(f, " pgsql");
 #endif
-#ifdef LOOKUP_SQLITE
+#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
   fprintf(f, " sqlite");
 #endif
-#ifdef LOOKUP_TESTDB
+#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
   fprintf(f, " testdb");
 #endif
-#ifdef LOOKUP_WHOSON
+#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
   fprintf(f, " whoson");
 #endif
 fprintf(f, "\n");
@@ -3424,6 +3424,9 @@
   }
 #endif /* EXIM_PERL */
 
+/* Initialise lookup_list */
+init_lookup_list();
+
 /* Log the arguments of the call if the configuration file said so. This is
 a debugging feature for finding out what arguments certain MUAs actually use.
 Don't attempt it if logging is disabled, or if listing variables or if
diff -uNr exim-4.69-old/src/expand.c exim-4.69/src/expand.c
--- exim-4.69-old/src/expand.c	2007-10-04 14:23:05.000000000 +0100
+++ exim-4.69/src/expand.c	2008-08-13 15:30:05.000000000 +0100
@@ -5373,8 +5373,8 @@
           goto EXPAND_FAILED;
           }
 
-        if (lookup_list[n].quote != NULL)
-          sub = (lookup_list[n].quote)(sub, opt);
+        if (lookup_list[n]->quote != NULL)
+          sub = (lookup_list[n]->quote)(sub, opt);
         else if (opt != NULL) sub = NULL;
 
         if (sub == NULL)
diff -uNr exim-4.69-old/src/globals.h exim-4.69/src/globals.h
--- exim-4.69-old/src/globals.h	2008-08-13 15:29:21.000000000 +0100
+++ exim-4.69/src/globals.h	2008-08-13 15:30:05.000000000 +0100
@@ -432,7 +432,7 @@
 extern BOOL    log_timezone;           /* TRUE to include the timezone in log lines */
 extern unsigned int log_write_selector;/* Bit map of logging options for log_write() */
 extern uschar *login_sender_address;   /* The actual sender address */
-extern lookup_info lookup_list[];      /* Vector of available lookups */
+extern lookup_info **lookup_list;      /* Array of pointers to available lookups */
 extern int     lookup_list_count;      /* Number of entries in the list */
 extern int     lookup_open_max;        /* Max lookup files to cache */
 extern uschar *lookup_value;           /* Value looked up from file */
diff -uNr exim-4.69-old/src/lookupapi.h exim-4.69/src/lookupapi.h
--- exim-4.69-old/src/lookupapi.h	1970-01-01 01:00:00.000000000 +0100
+++ exim-4.69/src/lookupapi.h	2008-08-13 15:30:05.000000000 +0100
@@ -0,0 +1,45 @@
+/* The "type" field in each item is a set of bit flags:
+
+  lookup_querystyle     => this is a query-style lookup,
+                             else single-key (+ file) style
+  lookup_absfile        => an absolute file name is required,
+                             (for single-key style only)
+*/
+
+typedef struct lookup_info {
+  uschar *name;                   /* e.g. "lsearch" */
+  int type;                       /* query/singlekey/abs-file */
+  void *(*open)(                  /* open function */
+    uschar *,                     /* file name for those that have one */
+    uschar **);                   /* for error message */
+  BOOL (*check)(                  /* file checking function */
+    void *,                       /* handle */
+    uschar *,                     /* file name */
+    int,                          /* modemask for file checking */
+    uid_t *,                      /* owners for file checking */
+    gid_t *,                      /* owngroups for file checking */
+    uschar **);                   /* for error messages */
+  int (*find)(                    /* find function */
+    void *,                       /* handle */
+    uschar *,                     /* file name or NULL */
+    uschar *,                     /* key or query */
+    int,                          /* length of key or query */
+    uschar **,                    /* for returning answer */
+    uschar **,                    /* for error message */
+    BOOL *);                      /* to request cache cleanup */
+  void (*close)(                  /* close function */
+    void *);                      /* handle */
+  void (*tidy)(void);             /* tidy function */
+  uschar *(*quote)(               /* quoting function */
+    uschar *,                     /* string to quote */
+    uschar *);                    /* additional data from quote name */
+} lookup_info;
+
+/* "LMM1" */
+#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4d31
+
+typedef struct lookup_module_info {
+  uint magic;
+  lookup_info **lookups;
+  uint lookupcount;
+} lookup_module_info;
diff -uNr exim-4.69-old/src/lookups/cdb.c exim-4.69/src/lookups/cdb.c
--- exim-4.69-old/src/lookups/cdb.c	2005-06-27 15:29:44.000000000 +0100
+++ exim-4.69/src/lookups/cdb.c	2008-08-13 15:30:05.000000000 +0100
@@ -56,7 +56,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "cdb.h"
 
 #ifdef HAVE_MMAP
 #  include <sys/mman.h>
@@ -144,7 +143,9 @@
   return num;
 }
 
-void *
+static void cdb_close(void *handle);
+
+static void *
 cdb_open(uschar *filename,
          uschar **errmsg)
 {
@@ -245,7 +246,7 @@
 *             Check entry point                  *
 *************************************************/
 
-BOOL
+static BOOL
 cdb_check(void *handle,
          uschar *filename,
          int modemask,
@@ -270,7 +271,7 @@
 *              Find entry point                  *
 *************************************************/
 
-int
+static int
 cdb_find(void *handle,
         uschar *filename,
         uschar *keystring,
@@ -418,7 +419,7 @@
 
 /* See local README for interface description */
 
-void
+static void
 cdb_close(void *handle)
 {
 struct cdb_state * cdbp = handle;
@@ -434,4 +435,22 @@
  (void)close(cdbp->fileno);
 }
 
+lookup_info cdb_lookup_info = {
+  US"cdb",                       /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  cdb_open,                      /* open function */
+  cdb_check,                     /* check function */
+  cdb_find,                      /* find function */
+  cdb_close,                     /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define cdb_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &cdb_lookup_info };
+lookup_module_info cdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/cdb.c */
diff -uNr exim-4.69-old/src/lookups/cdb.h exim-4.69/src/lookups/cdb.h
--- exim-4.69-old/src/lookups/cdb.h	2004-10-07 14:10:01.000000000 +0100
+++ exim-4.69/src/lookups/cdb.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,59 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/cdb.h,v 1.1 2004/10/07 13:10:01 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/*
- * $Id: cdb.h,v 1.2.2.1 1998/05/29 16:21:36 cvs Exp $
- *
- * Exim - CDB database lookup module
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd
- *
- * 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.
- *
- *
- * This code implements Dan Bernstein's Constant DataBase (cdb) spec.
- * Information, the spec and sample code for cdb can be obtained from
- *      http://www.pobox.com/~djb/cdb.html
- *
- * This implementation borrows some code from Dan Bernstein's
- * implementation (which has no license restrictions applied to it).
- * This (read-only) implementation is completely contained within
- * cdb.[ch] it does *not* link against an external cdb library.
- *
- *
- * There are 2 varients included within this code.  One uses MMAP and
- * should give better performance especially for multiple lookups on a
- * modern machine.  The other is the default implementation which is
- * used in the case where the MMAP fails or if MMAP was not compiled
- * in.  this implementation is the same as the original reference cdb
- * implementation.
- *
- */
-
-
-/* Functions for reading exim cdb files */
-
-extern void *cdb_open(uschar *, uschar **);
-extern BOOL  cdb_check(void *, uschar *, int, uid_t *, gid_t *, uschar **);
-extern int   cdb_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern void  cdb_close(void *);
-
-/* End of cdb.h */
diff -uNr exim-4.69-old/src/lookups/dbmdb.c exim-4.69/src/lookups/dbmdb.c
--- exim-4.69-old/src/lookups/dbmdb.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/dbmdb.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,7 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "dbmdb.h"
 
 
 /*************************************************
@@ -18,7 +17,7 @@
 
 /* See local README for interface description */
 
-void *
+static void *
 dbmdb_open(uschar *filename, uschar **errmsg)
 {
 EXIM_DB *yield;
@@ -45,7 +44,7 @@
 the same. Otherwise, for safety, we have to check for x.db or x.dir and x.pag.
 */
 
-BOOL
+static BOOL
 dbmdb_check(void *handle, uschar *filename, int modemask, uid_t *owners,
   gid_t *owngroups, uschar **errmsg)
 {
@@ -88,7 +87,7 @@
 /* See local README for interface description. This function adds 1 to
 the keylength in order to include the terminating zero. */
 
-int
+static int
 dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -121,7 +120,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -137,10 +136,39 @@
 
 /* See local README for interface description */
 
-void
+static void
 dbmdb_close(void *handle)
 {
 EXIM_DBCLOSE((EXIM_DB *)handle);
 }
 
+lookup_info dbm_lookup_info = {
+  US"dbm",                       /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  dbmdb_open,                    /* open function */
+  dbmdb_check,                   /* check function */
+  dbmdb_find,                    /* find function */
+  dbmdb_close,                   /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+lookup_info dbmz_lookup_info = {
+  US"dbmnz",                     /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  dbmdb_open,      /* sic */     /* open function */
+  dbmdb_check,     /* sic */     /* check function */
+  dbmnz_find,                    /* find function */
+  dbmdb_close,     /* sic */     /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define dbmdb_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &dbm_lookup_info, &dbmz_lookup_info };
+lookup_module_info dbmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 2 };
+
 /* End of lookups/dbmdb.c */
diff -uNr exim-4.69-old/src/lookups/dbmdb.h exim-4.69/src/lookups/dbmdb.h
--- exim-4.69-old/src/lookups/dbmdb.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/dbmdb.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/dbmdb.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the dbm lookup. Use dbmdb in the code to avoid name
-clashes with external library names. */
-
-extern void *dbmdb_open(uschar *, uschar **);
-extern BOOL  dbmdb_check(void *, uschar *, int, uid_t *, gid_t *, uschar **);
-extern int   dbmdb_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern int   dbmnz_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern void  dbmdb_close(void *);
-
-/* End of lookups/dbmdb.h */
diff -uNr exim-4.69-old/src/lookups/dkim.c exim-4.69/src/lookups/dkim.c
--- exim-4.69-old/src/lookups/dkim.c	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/src/lookups/dkim.c	2008-08-13 15:30:05.000000000 +0100
@@ -8,7 +8,6 @@
 /* See the file NOTICE for conditions of use and distribution. */
 
 #include "../exim.h"
-#include "dkim.h"
 
 
 
@@ -18,7 +17,7 @@
 
 /* See local README for interface description */
 
-void *
+static void *
 dkim_open(uschar *filename, uschar **errmsg)
 {
 filename = filename;     /* Keep picky compilers happy */
@@ -35,7 +34,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 dkim_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -49,4 +48,22 @@
 #endif
 }
 
+lookup_info cdb_lookup_info = {
+  US"dkim",                      /* lookup name */
+  lookup_querystyle,             /* query style */
+  dkim_open,                     /* open function */
+  NULL,                          /* check function */
+  dkim_find,                     /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define cdb_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &dkim_lookup_info };
+lookup_module_info cdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/dkim.c */
diff -uNr exim-4.69-old/src/lookups/dkim.h exim-4.69/src/lookups/dkim.h
--- exim-4.69-old/src/lookups/dkim.h	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/src/lookups/dkim.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/dkim.h,v 1.1 2007/09/28 12:21:57 tom Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the DKIM lookup */
-
-extern void *dkim_open(uschar *, uschar **);
-extern int   dkim_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/dkim.h */
diff -uNr exim-4.69-old/src/lookups/dnsdb.c exim-4.69/src/lookups/dnsdb.c
--- exim-4.69-old/src/lookups/dnsdb.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/dnsdb.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,8 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "dnsdb.h"
-
 
 
 /* Ancient systems (e.g. SunOS4) don't appear to have T_TXT defined in their
@@ -67,7 +65,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 dnsdb_open(uschar *filename, uschar **errmsg)
 {
 filename = filename;   /* Keep picky compilers happy */
@@ -102,7 +100,7 @@
 which may start with '<' in order to set a specific separator. The default
 separator, as always, is colon. */
 
-int
+static int
 dnsdb_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -394,4 +392,22 @@
 return OK;
 }
 
+static lookup_info _lookup_info = {
+  US"dnsdb",                     /* lookup name */
+  lookup_querystyle,             /* query style */
+  dnsdb_open,                    /* open function */
+  NULL,                          /* check function */
+  dnsdb_find,                    /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define dnsdb_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info dnsdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/dnsdb.c */
diff -uNr exim-4.69-old/src/lookups/dnsdb.h exim-4.69/src/lookups/dnsdb.h
--- exim-4.69-old/src/lookups/dnsdb.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/dnsdb.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/dnsdb.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the dnsdb lookup */
-
-extern void *dnsdb_open(uschar *, uschar **);
-extern int   dnsdb_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/dnsdb.h */
diff -uNr exim-4.69-old/src/lookups/dsearch.c exim-4.69/src/lookups/dsearch.c
--- exim-4.69-old/src/lookups/dsearch.c	2007-05-31 13:42:07.000000000 +0100
+++ exim-4.69/src/lookups/dsearch.c	2008-08-13 15:30:05.000000000 +0100
@@ -14,8 +14,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "dsearch.h"
-
 
 
 /*************************************************
@@ -27,7 +25,7 @@
 it open, because the "search" can be done by a call to lstat() rather than
 actually scanning through the list of files. */
 
-void *
+static void *
 dsearch_open(uschar *dirname, uschar **errmsg)
 {
 DIR *dp = opendir(CS dirname);
@@ -50,7 +48,7 @@
 /* The handle will always be (void *)(-1), but don't try casting it to an
 integer as this gives warnings on 64-bit systems. */
 
-BOOL
+static BOOL
 dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
   gid_t *owngroups, uschar **errmsg)
 {
@@ -68,7 +66,7 @@
 scanning the directory, as it is hopefully faster to let the OS do the scanning
 for us. */
 
-int
+static int
 dsearch_find(void *handle, uschar *dirname, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -114,10 +112,28 @@
 
 /* See local README for interface description */
 
-void
+static void
 dsearch_close(void *handle)
 {
 handle = handle;   /* Avoid compiler warning */
 }
 
+static lookup_info _lookup_info = {
+  US"dsearch",                   /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  dsearch_open,                  /* open function */
+  dsearch_check,                 /* check function */
+  dsearch_find,                  /* find function */
+  dsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define dsearch_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info dsearch_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/dsearch.c */
diff -uNr exim-4.69-old/src/lookups/dsearch.h exim-4.69/src/lookups/dsearch.h
--- exim-4.69-old/src/lookups/dsearch.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/dsearch.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/dsearch.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the dsearch lookup */
-
-extern void *dsearch_open(uschar *, uschar **);
-extern BOOL  dsearch_check(void *, uschar *, int, uid_t *, gid_t *, uschar **);
-extern int   dsearch_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern void  dsearch_close(void *);
-
-/* End of lookups/dsearch.h */
diff -uNr exim-4.69-old/src/lookups/ibase.c exim-4.69/src/lookups/ibase.c
--- exim-4.69-old/src/lookups/ibase.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/ibase.c	2008-08-13 15:30:05.000000000 +0100
@@ -11,14 +11,7 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "ibase.h"
 
-#ifndef LOOKUP_IBASE
-static void dummy(int x)
-{
-    dummy(x - 1);
-}
-#else
 #include <ibase.h>              /* The system header */
 
 /* Structure and anchor for caching connections. */
@@ -40,7 +33,7 @@
 
 /* See local README for interface description. */
 
-void *ibase_open(uschar * filename, uschar ** errmsg)
+static void *ibase_open(uschar * filename, uschar ** errmsg)
 {
     return (void *) (1);        /* Just return something non-null */
 }
@@ -53,7 +46,7 @@
 
 /* See local README for interface description. */
 
-void ibase_tidy(void)
+static void ibase_tidy(void)
 {
     ibase_connection *cn;
     ISC_STATUS status[20];
@@ -458,7 +451,7 @@
 arguments are not used. Loop through a list of servers while the query is
 deferred with a retryable error. */
 
-int
+static int
 ibase_find(void *handle, uschar * filename, uschar * query, int length,
            uschar ** result, uschar ** errmsg, BOOL *do_cache)
 {
@@ -510,7 +503,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *ibase_quote(uschar * s, uschar * opt)
+static uschar *ibase_quote(uschar * s, uschar * opt)
 {
     register int c;
     int count = 0;
@@ -553,6 +546,22 @@
     return quoted;
 }
 
+static lookup_info _lookup_info = {
+  US"ibase",                     /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  ibase_open,                    /* open function */
+  NULL,                          /* no check function */
+  ibase_find,                    /* find function */
+  NULL,                          /* no close function */
+  ibase_tidy,                    /* tidy function */
+  ibase_quote                    /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define ibase_lookup_module_info _lookup_module_info
 #endif
 
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info ibase_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/ibase.c */
diff -uNr exim-4.69-old/src/lookups/ibase.h exim-4.69/src/lookups/ibase.h
--- exim-4.69-old/src/lookups/ibase.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/ibase.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/ibase.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the Interbase lookup functions */
-
-extern void   *ibase_open(uschar *, uschar **);
-extern int     ibase_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-                 BOOL *);
-extern void    ibase_tidy(void);
-extern uschar *ibase_quote(uschar *, uschar *);
-
-/* End of lookups/ibase.h */
diff -uNr exim-4.69-old/src/lookups/ldap.c exim-4.69/src/lookups/ldap.c
--- exim-4.69-old/src/lookups/ldap.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/ldap.c	2008-08-13 15:30:05.000000000 +0100
@@ -15,21 +15,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "ldap.h"
-
-
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the LDAP headers
-available for compiling. Therefore, compile these functions only if LOOKUP_LDAP
-is defined. However, some compilers don't like compiling empty modules, so keep
-them happy with a dummy when skipping the rest. Make it reference itself to
-stop picky compilers complaining that it is unused, and put in a dummy argument
-to stop even pickier compilers complaining about infinite loops. */
-
-#ifndef LOOKUP_LDAP
-static void dummy(int x) { dummy(x-1); }
-#else
-
 
 /* Include LDAP headers. The code below uses some "old" LDAP interfaces that
 are deprecated in OpenLDAP. I don't know their status in other LDAP
@@ -1196,7 +1181,7 @@
 are handled by a common function, with a flag to differentiate between them.
 The handle and filename arguments are not used. */
 
-int
+static int
 eldap_find(void *handle, uschar *filename, uschar *ldap_url, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -1205,7 +1190,7 @@
 return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
 }
 
-int
+static int
 eldapm_find(void *handle, uschar *filename, uschar *ldap_url, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -1214,7 +1199,7 @@
 return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
 }
 
-int
+static int
 eldapdn_find(void *handle, uschar *filename, uschar *ldap_url, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -1240,7 +1225,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 eldap_open(uschar *filename, uschar **errmsg)
 {
 return (void *)(1);    /* Just return something non-null */
@@ -1255,7 +1240,7 @@
 /* See local README for interface description.
 Make sure that eldap_dn does not refer to reclaimed or worse, freed store */
 
-void
+static void
 eldap_tidy(void)
 {
 LDAP_CONNECTION *lcp = NULL;
@@ -1351,7 +1336,7 @@
 
 
 
-uschar *
+static uschar *
 eldap_quote(uschar *s, uschar *opt)
 {
 register int c;
@@ -1470,6 +1455,44 @@
 return quoted;
 }
 
-#endif  /* LOOKUP_LDAP */
+static lookup_info ldap_lookup_info = {
+  US"ldap",                      /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  eldap_open,                    /* open function */
+  NULL,                          /* check function */
+  eldap_find,                    /* find function */
+  NULL,                          /* no close function */
+  eldap_tidy,                    /* tidy function */
+  eldap_quote                    /* quoting function */
+};
+
+static lookup_info ldapdn_lookup_info = {
+  US"ldapdn",                     /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  eldap_open,       /* sic */    /* open function */
+  NULL,                          /* check function */
+  eldapdn_find,                  /* find function */
+  NULL,                          /* no close function */
+  eldap_tidy,       /* sic */    /* tidy function */
+  eldap_quote       /* sic */    /* quoting function */
+};
+
+static lookup_info ldapm_lookup_info = {
+  US"ldapm",                     /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  eldap_open,       /* sic */    /* open function */
+  NULL,                          /* check function */
+  eldapm_find,                   /* find function */
+  NULL,                          /* no close function */
+  eldap_tidy,       /* sic */    /* tidy function */
+  eldap_quote       /* sic */    /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define ldap_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &ldap_lookup_info, &ldapdn_lookup_info, &ldapm_lookup_info };
+lookup_module_info ldap_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 3 };
 
 /* End of lookups/ldap.c */
diff -uNr exim-4.69-old/src/lookups/ldap.h exim-4.69/src/lookups/ldap.h
--- exim-4.69-old/src/lookups/ldap.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/ldap.h	2008-08-13 15:30:05.000000000 +0100
@@ -7,18 +7,9 @@
 /* Copyright (c) University of Cambridge 1995 - 2007 */
 /* See the file NOTICE for conditions of use and distribution. */
 
-/* Header for the ldap lookups */
+/* Header for eldapauth_find */
 
-extern void   *eldap_open(uschar *, uschar **);
-extern int     eldap_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-                 BOOL *);
 extern int     eldapauth_find(void *, uschar *, uschar *, int, uschar **,
                  uschar **, BOOL *);
-extern int     eldapdn_find(void *, uschar *, uschar *, int, uschar **,
-                 uschar **, BOOL *);
-extern int     eldapm_find(void *, uschar *, uschar *, int, uschar **,
-                 uschar **, BOOL *);
-extern void    eldap_tidy(void);
-extern uschar *eldap_quote(uschar *, uschar *);
 
 /* End of lookups/ldap.h */
diff -uNr exim-4.69-old/src/lookups/lsearch.c exim-4.69/src/lookups/lsearch.c
--- exim-4.69-old/src/lookups/lsearch.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/lsearch.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,7 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "lsearch.h"
 
 /* Codes for the different kinds of lsearch that are supported */
 
@@ -28,7 +27,7 @@
 
 /* See local README for interface description */
 
-void *
+static void *
 lsearch_open(uschar *filename, uschar **errmsg)
 {
 FILE *f = Ufopen(filename, "rb");
@@ -48,7 +47,7 @@
 *             Check entry point                  *
 *************************************************/
 
-BOOL
+static BOOL
 lsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners,
   gid_t *owngroups, uschar **errmsg)
 {
@@ -320,7 +319,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 lsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -337,7 +336,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 wildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -354,7 +353,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 nwildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -372,7 +371,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -401,10 +400,64 @@
 
 /* See local README for interface description */
 
-void
+static void
 lsearch_close(void *handle)
 {
 (void)fclose((FILE *)handle);
 }
 
+static lookup_info iplsearch_lookup_info = {
+  US"iplsearch",                 /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  iplsearch_find,                /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+static lookup_info lsearch_lookup_info = {
+  US"lsearch",                   /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  lsearch_find,                  /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+static lookup_info nwildlsearch_lookup_info = {
+  US"nwildlsearch",              /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  nwildlsearch_find,             /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+static lookup_info wildlsearch_lookup_info = {
+  US"wildlsearch",               /* lookup name */
+  lookup_absfile,                /* uses absolute file name */
+  lsearch_open,                  /* open function */
+  lsearch_check,                 /* check function */
+  wildlsearch_find,              /* find function */
+  lsearch_close,                 /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define lsearch_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &iplsearch_lookup_info,
+                                       &lsearch_lookup_info,
+                                       &nwildlsearch_lookup_info,
+                                       &wildlsearch_lookup_info };
+lookup_module_info lsearch_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 4 };
+
 /* End of lookups/lsearch.c */
diff -uNr exim-4.69-old/src/lookups/lsearch.h exim-4.69/src/lookups/lsearch.h
--- exim-4.69-old/src/lookups/lsearch.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/lsearch.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,25 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/lsearch.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the lsearch and wildlsearch lookups */
-
-extern void *lsearch_open(uschar *, uschar **);
-extern BOOL  lsearch_check(void *, uschar *, int, uid_t *, gid_t *, uschar **);
-extern int   lsearch_find(void *, uschar *, uschar *, int, uschar **,
-               uschar **, BOOL *);
-extern void  lsearch_close(void *);
-
-extern int   wildlsearch_find(void *, uschar *, uschar *, int, uschar **,
-               uschar **, BOOL *);
-extern int   nwildlsearch_find(void *, uschar *, uschar *, int, uschar **,
-               uschar **, BOOL *);
-extern int   iplsearch_find(void *, uschar *, uschar *, int, uschar **,
-               uschar **, BOOL *);
-
-/* End of lookups/lsearch.h */
diff -uNr exim-4.69-old/src/lookups/Makefile exim-4.69/src/lookups/Makefile
--- exim-4.69-old/src/lookups/Makefile	2007-09-28 13:21:57.000000000 +0100
+++ exim-4.69/src/lookups/Makefile	2008-08-13 15:30:05.000000000 +0100
@@ -1,13 +1,181 @@
 # $Cambridge: exim/exim-src/src/lookups/Makefile,v 1.7 2007/09/28 12:21:57 tom Exp $
 
-# Make file for building a library containing all the available lookups and
-# calling it lookups.a. This is called from the main make file, after cd'ing
-# to the lookups subdirectory. When the relevant LOOKUP_ macros are not
-# defined, dummy modules get compiled.
-
-OBJ = cdb.o dbmdb.o dkim.o dnsdb.o dsearch.o ibase.o ldap.o lsearch.o mysql.o nis.o \
-      nisplus.o oracle.o passwd.o pgsql.o spf.o sqlite.o testdb.o whoson.o \
-      lf_check_file.o lf_quote.o lf_sqlperform.o
+# Make file for building all the available lookups.
+# This is called from the main make file, after cd'ing
+# to the lookups subdirectory.
+
+# because the variable is EXPERIMENTAL_SPF and not LOOKUP_SPF
+# we put this one here by default and compile a dummy if
+# EXPERIMENTAL_SPF is not defined
+OBJ=spf.o
+MODS=
+
+ifeq ($(LOOKUP_CDB),2)
+MODS += cdb.so
+LOOKUP_cdb_INCLUDE = $(LOOKUP_CDB_INCLUDE)
+LOOKUP_cdb_LIBS = $(LOOKUP_CDB_LIBS)
+else
+ifneq ($(LOOKUP_CDB),)
+OBJ += cdb.o
+endif
+endif
+
+ifeq ($(LOOKUP_DBM),2)
+MODS += dbmdb.so
+LOOKUP_dbmdb_INCLUDE = $(LOOKUP_DBM_INCLUDE)
+LOOKUP_dbmdb_LIBS = $(LOOKUP_DBM_LIBS)
+else
+ifneq ($(LOOKUP_DBM),)
+OBJ += dbmdb.o
+endif
+endif
+
+ifeq ($(LOOKUP_DKIM),2)
+MODS += dkim.so
+LOOKUP_dkim_INCLUDE = $(LOOKUP_DKIM_INCLUDE)
+LOOKUP_dkim_LIBS = $(LOOKUP_DKIM_LIBS)
+else
+ifneq ($(LOOKUP_DKIM),)
+OBJ += dkim.o
+endif
+endif
+
+ifeq ($(LOOKUP_DNSDB),2)
+MODS += dnsdb.so
+LOOKUP_dnsdb_INCLUDE = $(LOOKUP_DNSDB_INCLUDE)
+LOOKUP_dnsdb_LIBS = $(LOOKUP_DNSDB_LIBS)
+else
+ifneq ($(LOOKUP_DNSDB),)
+OBJ += dnsdb.o
+endif
+endif
+
+ifeq ($(LOOKUP_DSEARCH),2)
+MODS += dsearch.so
+LOOKUP_dsearch_INCLUDE = $(LOOKUP_DSEARCH_INCLUDE)
+LOOKUP_dsearch_LIBS = $(LOOKUP_DSEARCH_LIBS)
+else
+ifneq ($(LOOKUP_DSEARCH),)
+OBJ += dsearch.o
+endif
+endif
+
+ifeq ($(LOOKUP_IBASE),2)
+MODS += ibase.so
+LOOKUP_ibase_INCLUDE = $(LOOKUP_IBASE_INCLUDE)
+LOOKUP_ibase_LIBS = $(LOOKUP_IBASE_LIBS)
+else
+ifneq ($(LOOKUP_IBASE),)
+OBJ += ibase.o
+endif
+endif
+
+ifneq ($(LOOKUP_LDAP),)
+OBJ += ldap.o
+endif
+
+ifeq ($(LOOKUP_LSEARCH),2)
+MODS += lsearch.so
+LOOKUP_lsearch_INCLUDE = $(LOOKUP_LSEARCH_INCLUDE)
+LOOKUP_lsearch_LIBS = $(LOOKUP_LSEARCH_LIBS)
+else
+ifneq ($(LOOKUP_LSEARCH),)
+OBJ += lsearch.o
+endif
+endif
+
+ifeq ($(LOOKUP_MYSQL),2)
+MODS += mysql.so
+LOOKUP_mysql_INCLUDE = $(LOOKUP_MYSQL_INCLUDE)
+LOOKUP_mysql_LIBS = $(LOOKUP_MYSQL_LIBS)
+else
+ifneq ($(LOOKUP_MYSQL),)
+OBJ += mysql.o
+endif
+endif
+
+ifeq ($(LOOKUP_NIS),2)
+MODS += nis.so
+LOOKUP_nis_INCLUDE = $(LOOKUP_NIS_INCLUDE)
+LOOKUP_nis_LIBS = $(LOOKUP_NIS_LIBS)
+else
+ifneq ($(LOOKUP_NIS),)
+OBJ += nis.o
+endif
+endif
+
+ifeq ($(LOOKUP_NISPLUS),2)
+MODS += nisplus.so
+LOOKUP_nisplus_INCLUDE = $(LOOKUP_NISPLUS_INCLUDE)
+LOOKUP_nisplus_LIBS = $(LOOKUP_NISPLUS_LIBS)
+else
+ifneq ($(LOOKUP_NISPLUS),)
+OBJ += nisplus.o
+endif
+endif
+
+ifeq ($(LOOKUP_ORACLE),2)
+MODS += oracle.so
+LOOKUP_oracle_INCLUDE = $(LOOKUP_ORACLE_INCLUDE)
+LOOKUP_oracle_LIBS = $(LOOKUP_ORACLE_LIBS)
+else
+ifneq ($(LOOKUP_ORACLE),)
+OBJ += oracle.o
+endif
+endif
+
+ifeq ($(LOOKUP_PASSWD),2)
+MODS += passwd.so
+LOOKUP_passwd_INCLUDE = $(LOOKUP_PASSWD_INCLUDE)
+LOOKUP_passwd_LIBS = $(LOOKUP_PASSWD_LIBS)
+else
+ifneq ($(LOOKUP_PASSWD),)
+OBJ += passwd.o
+endif
+endif
+
+ifeq ($(LOOKUP_PGSQL),2)
+MODS += pgsql.so
+LOOKUP_pgsql_INCLUDE = $(LOOKUP_PGSQL_INCLUDE)
+LOOKUP_pgsql_LIBS = $(LOOKUP_PGSQL_LIBS)
+else
+ifneq ($(LOOKUP_PGSQL),)
+OBJ += pgsql.o
+endif
+endif
+
+ifeq ($(LOOKUP_SQLITE),2)
+MODS += sqlite.so
+LOOKUP_sqlite_INCLUDE = $(LOOKUP_SQLITE_INCLUDE)
+LOOKUP_sqlite_LIBS = $(LOOKUP_SQLITE_LIBS)
+else
+ifneq ($(LOOKUP_SQLITE),)
+OBJ += sqlite.o
+endif
+endif
+
+ifeq ($(LOOKUP_TESTDB),2)
+MODS += testdb.so
+LOOKUP_testdb_INCLUDE = $(LOOKUP_TESTDB_INCLUDE)
+LOOKUP_testdb_LIBS = $(LOOKUP_TESTDB_LIBS)
+else
+ifneq ($(LOOKUP_TESTDB),)
+OBJ += testdb.o
+endif
+endif
+
+ifeq ($(LOOKUP_WHOSON),2)
+MODS += whoson.so
+LOOKUP_whoson_INCLUDE = $(LOOKUP_WHOSON_INCLUDE)
+LOOKUP_whoson_LIBS = $(LOOKUP_WHOSON_LIBS)
+else
+ifneq ($(LOOKUP_WHOSON),)
+OBJ += whoson.o
+endif
+endif
+
+
+all:             lookups.a lf_quote.o lf_check_file.o lf_sqlperform.o $(MODS)
 
 lookups.a:       $(OBJ)
 		 @$(RM_COMMAND) -f lookups.a
@@ -16,31 +184,54 @@
 		 $(RANLIB) $@
 		 @$(RM_COMMAND) -rf ../drtables.o
 
-.SUFFIXES:       .o .c
+.SUFFIXES:       .o .c .so
 .c.o:;           @echo "$(CC) $*.c"
 		 $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c
 
+.c.so:;          @echo "$(CC) -shared $*.c"
+		 $(FE)$(CC) $(LOOKUP_$*_INCLUDE) $(LOOKUP_$*_LIBS) -DDYNLOOKUP -shared -rdynamic $(CFLAGS) $(INCLUDE) $(DLFLAGS) $*.c -o $@
+
 lf_check_file.o: $(HDRS) lf_check_file.c  lf_functions.h
 lf_quote.o:      $(HDRS) lf_quote.c       lf_functions.h
 lf_sqlperform.o: $(HDRS) lf_sqlperform.c  lf_functions.h
 
-cdb.o:           $(HDRS) cdb.c       cdb.h
-dbmdb.o:         $(HDRS) dbmdb.c     dbmdb.h
-dkim.o:		 $(HDRS) dkim.c      dkim.h
-dnsdb.o:         $(HDRS) dnsdb.c     dnsdb.h
-dsearch.o:       $(HDRS) dsearch.c   dsearch.h
-ibase.o:         $(HDRS) ibase.c     ibase.h
-ldap.o:          $(HDRS) ldap.c      ldap.h
-lsearch.o:       $(HDRS) lsearch.c   lsearch.h
-mysql.o:         $(HDRS) mysql.c     mysql.h
-nis.o:           $(HDRS) nis.c       nis.h
-nisplus.o:       $(HDRS) nisplus.c   nisplus.h
-oracle.o:        $(HDRS) oracle.c    oracle.h
-passwd.o:        $(HDRS) passwd.c    passwd.h
-pgsql.o:         $(HDRS) pgsql.c     pgsql.h
-spf.o:           $(HDRS) spf.c       spf.h
-sqlite.o:        $(HDRS) sqlite.c    sqlite.h
-testdb.o:        $(HDRS) testdb.c    testdb.h
-whoson.o:        $(HDRS) whoson.c    whoson.h
+cdb.o:           $(HDRS) cdb.c
+dbmdb.o:         $(HDRS) dbmdb.c
+dkim.o:          $(HDRS) dkim.c
+dnsdb.o:         $(HDRS) dnsdb.c
+dsearch.o:       $(HDRS) dsearch.c
+ibase.o:         $(HDRS) ibase.c
+ldap.o:          $(HDRS) ldap.c
+lsearch.o:       $(HDRS) lsearch.c
+mysql.o:         $(HDRS) mysql.c
+nis.o:           $(HDRS) nis.c
+nisplus.o:       $(HDRS) nisplus.c
+oracle.o:        $(HDRS) oracle.c
+passwd.o:        $(HDRS) passwd.c
+pgsql.o:         $(HDRS) pgsql.c
+spf.o:           $(HDRS) spf.c
+sqlite.o:        $(HDRS) sqlite.c
+testdb.o:        $(HDRS) testdb.c
+whoson.o:        $(HDRS) whoson.c
+
+cdb.so:           $(HDRS) cdb.c
+dbmdb.so:         $(HDRS) dbmdb.c
+dkim.so:          $(HDRS) dkim.c
+dnsdb.so:         $(HDRS) dnsdb.c
+dsearch.so:       $(HDRS) dsearch.c
+ibase.so:         $(HDRS) ibase.c
+ldap.so:          $(HDRS) ldap.c
+lsearch.so:       $(HDRS) lsearch.c
+mysql.so:         $(HDRS) mysql.c
+nis.so:           $(HDRS) nis.c
+nisplus.so:       $(HDRS) nisplus.c
+oracle.so:        $(HDRS) oracle.c
+passwd.so:        $(HDRS) passwd.c
+pgsql.so:         $(HDRS) pgsql.c
+spf.so:           $(HDRS) spf.c
+sqlite.so:        $(HDRS) sqlite.c
+testdb.so:        $(HDRS) testdb.c
+whoson.so:        $(HDRS) whoson.c
+
 
 # End
diff -uNr exim-4.69-old/src/lookups/mysql.c exim-4.69/src/lookups/mysql.c
--- exim-4.69-old/src/lookups/mysql.c	2007-08-23 11:16:51.000000000 +0100
+++ exim-4.69/src/lookups/mysql.c	2008-08-13 15:30:05.000000000 +0100
@@ -13,22 +13,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "mysql.h"       /* The local header */
-
-
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the MYSQL header
-available for compiling. Therefore, compile these functions only if
-LOOKUP_MYSQL is defined. However, some compilers don't like compiling empty
-modules, so keep them happy with a dummy when skipping the rest. Make it
-reference itself to stop picky compilers complaining that it is unused, and put
-in a dummy argument to stop even pickier compilers complaining about infinite
-loops. */
-
-#ifndef LOOKUP_MYSQL
-static void dummy(int x) { dummy(x-1); }
-#else
-
 
 #include <mysql.h>       /* The system header */
 
@@ -51,7 +35,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 mysql_open(uschar *filename, uschar **errmsg)
 {
 return (void *)(1);    /* Just return something non-null */
@@ -65,7 +49,7 @@
 
 /* See local README for interface description. */
 
-void
+static void
 mysql_tidy(void)
 {
 mysql_connection *cn;
@@ -342,7 +326,7 @@
 query is deferred with a retryable error is now in a separate function that is
 shared with other SQL lookups. */
 
-int
+static int
 mysql_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -372,7 +356,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *
+static uschar *
 mysql_quote(uschar *s, uschar *opt)
 {
 register int c;
@@ -414,7 +398,24 @@
 return quoted;
 }
 
+/* These are the lookup_info blocks for this driver */
+
+static lookup_info mysql_lookup_info = {
+  US"mysql",                     /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  mysql_open,                    /* open function */
+  NULL,                          /* no check function */
+  mysql_find,                    /* find function */
+  NULL,                          /* no close function */
+  mysql_tidy,                    /* tidy function */
+  mysql_quote                    /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define mysql_lookup_module_info _lookup_module_info
+#endif
 
-#endif  /* MYSQL_LOOKUP */
+static lookup_info *_lookup_list[] = { &mysql_lookup_info };
+lookup_module_info mysql_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/mysql.c */
diff -uNr exim-4.69-old/src/lookups/mysql.h exim-4.69/src/lookups/mysql.h
--- exim-4.69-old/src/lookups/mysql.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/mysql.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/mysql.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the mysql lookup functions */
-
-extern void *mysql_open(uschar *, uschar **);
-extern int   mysql_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern void  mysql_tidy(void);
-extern uschar *mysql_quote(uschar *, uschar *);
-
-/* End of lookups/mysql.h */
diff -uNr exim-4.69-old/src/lookups/nis.c exim-4.69/src/lookups/nis.c
--- exim-4.69-old/src/lookups/nis.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/nis.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,19 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "nis.h"
-
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the NIS header
-available for compiling. Therefore, compile these functions only if LOOKUP_NIS
-is defined. However, some compilers don't like compiling empty modules, so keep
-them happy with a dummy when skipping the rest. Make it reference itself to
-stop picky compilers complaining that it is unused, and put in a dummy argument
-to stop even pickier compilers complaining about infinite loops. */
-
-#ifndef LOOKUP_NIS
-static void dummy(int x) { dummy(x-1); }
-#else
 
 #include <rpcsvc/ypclnt.h>
 
@@ -33,7 +20,7 @@
 /* See local README for interface description. This serves for both
 the "nis" and "nis0" lookup types. */
 
-void *
+static void *
 nis_open(uschar *filename, uschar **errmsg)
 {
 char *nis_domain;
@@ -55,7 +42,7 @@
 for nis0 because they are so short it isn't worth trying to use any common
 code. */
 
-int
+static int
 nis_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -81,7 +68,7 @@
 
 /* See local README for interface description. */
 
-int
+static int
 nis0_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -99,6 +86,33 @@
 return (rc == YPERR_KEY || rc == YPERR_MAP)? FAIL : DEFER;
 }
 
-#endif  /* LOOKUP_NIS */
+static lookup_info nis_lookup_info = {
+  US"nis",                       /* lookup name */
+  0,                             /* not abs file, not query style*/
+  nis_open,                      /* open function */
+  NULL,                          /* check function */
+  nis_find,                      /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+static lookup_info nis0_lookup_info = {
+  US"nis0",                      /* lookup name */
+  0,                             /* not absfile, not query style */
+  nis_open,    /* sic */         /* open function */
+  NULL,                          /* check function */
+  nis0_find,                     /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define nis_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &nis_lookup_info, &nis0_lookup_info };
+lookup_module_info nis_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 2 };
 
 /* End of lookups/nis.c */
diff -uNr exim-4.69-old/src/lookups/nis.h exim-4.69/src/lookups/nis.h
--- exim-4.69-old/src/lookups/nis.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/nis.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/nis.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the nis and nis0 lookups */
-
-extern void *nis_open(uschar *, uschar **);
-extern int   nis_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern int   nis0_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/nis.h */
diff -uNr exim-4.69-old/src/lookups/nisplus.c exim-4.69/src/lookups/nisplus.c
--- exim-4.69-old/src/lookups/nisplus.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/nisplus.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,21 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "nisplus.h"
-
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the NIS+ header
-available for compiling. Therefore, compile these functions only if
-LOOKUP_NISPLUS is defined. However, some compilers don't like compiling empty
-modules, so keep them happy with a dummy when skipping the rest. Make it
-reference itself to stop picky compilers complaining that it is unused, and put
-in a dummy argument to stop even pickier compilers complaining about infinite
-loops. */
-
-#ifndef LOOKUP_NISPLUS
-static void dummy(int x) { dummy(x-1); }
-#else
-
 
 #include <rpcsvc/nis.h>
 
@@ -34,7 +19,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 nisplus_open(uschar *filename, uschar **errmsg)
 {
 return (void *)(1);    /* Just return something non-null */
@@ -58,7 +43,7 @@
 yield is the concatenation of all the fields, preceded by their names and an
 equals sign. */
 
-int
+static int
 nisplus_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -250,7 +235,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *
+static uschar *
 nisplus_quote(uschar *s, uschar *opt)
 {
 int count = 0;
@@ -274,6 +259,22 @@
 return quoted;
 }
 
-#endif  /* LOOKUP_NISPLUS */
+static lookup_info _lookup_info = {
+  US"nisplus",                   /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  nisplus_open,                  /* open function */
+  NULL,                          /* check function */
+  nisplus_find,                  /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  nisplus_quote                  /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define nisplus_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info nisplus_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/nisplus.c */
diff -uNr exim-4.69-old/src/lookups/nisplus.h exim-4.69/src/lookups/nisplus.h
--- exim-4.69-old/src/lookups/nisplus.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/nisplus.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/nisplus.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the nisplus lookup */
-
-extern void   *nisplus_open(uschar *, uschar **);
-extern int     nisplus_find(void *, uschar *, uschar *, int, uschar **,
-                 uschar **, BOOL *);
-extern uschar *nisplus_quote(uschar *, uschar *);
-
-/* End of lookups/nisplus.h */
diff -uNr exim-4.69-old/src/lookups/oracle.c exim-4.69/src/lookups/oracle.c
--- exim-4.69-old/src/lookups/oracle.c	2007-03-13 09:59:07.000000000 +0000
+++ exim-4.69/src/lookups/oracle.c	2008-08-13 15:30:05.000000000 +0100
@@ -15,27 +15,12 @@
 #include "../exim.h"
 
 
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the ORACLE headers
-available for compiling. Therefore, compile these functions only if
-LOOKUP_ORACLE is defined. However, some compilers don't like compiling empty
-modules, so keep them happy with a dummy when skipping the rest. Make it
-reference itself to stop picky compilers complaining that it is unused, and put
-in a dummy argument to stop even pickier compilers complaining about infinite
-loops. */
-
-#ifndef LOOKUP_ORACLE
-static void dummy(int x) { dummy(x-1); }
-#else
-
 /* The Oracle system headers */
 
 #include <oratypes.h>
 #include <ocidfn.h>
 #include <ocikpr.h>
 
-#include "oracle.h"                    /* The local header */
-
 #define PARSE_NO_DEFER           0     /* parse straight away */
 #define PARSE_V7_LNG             2
 #define MAX_ITEM_BUFFER_SIZE  1024     /* largest size of a cell of data */
@@ -212,7 +197,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 oracle_open(uschar *filename, uschar **errmsg)
 {
 return (void *)(1);    /* Just return something non-null */
@@ -226,7 +211,7 @@
 
 /* See local README for interface description. */
 
-void
+static void
 oracle_tidy(void)
 {
 oracle_connection *cn;
@@ -532,7 +517,7 @@
 arguments are not used. Loop through a list of servers while the query is
 deferred with a retryable error. */
 
-int
+static int
 oracle_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -577,7 +562,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *
+static uschar *
 oracle_quote(uschar *s, uschar *opt)
 {
 register int c;
@@ -619,6 +604,22 @@
 return quoted;
 }
 
-#endif  /* LOOKUP_ORACLE */
+static lookup_info _lookup_info = {
+  US"oracle",                    /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  oracle_open,                   /* open function */
+  NULL,                          /* check function */
+  oracle_find,                   /* find function */
+  NULL,                          /* no close function */
+  oracle_tidy,                   /* tidy function */
+  oracle_quote                   /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define oracle_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info oracle_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/oracle.c */
diff -uNr exim-4.69-old/src/lookups/oracle.h exim-4.69/src/lookups/oracle.h
--- exim-4.69-old/src/lookups/oracle.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/oracle.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/oracle.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the Oracle lookup functions */
-
-extern void   *oracle_open(uschar *, uschar **);
-extern int     oracle_find(void *, uschar *, uschar *, int, uschar **,
-                 uschar **, BOOL *);
-extern void    oracle_tidy(void);
-extern uschar *oracle_quote(uschar *, uschar *);
-
-/* End of lookups/oracle.h */
diff -uNr exim-4.69-old/src/lookups/passwd.c exim-4.69/src/lookups/passwd.c
--- exim-4.69-old/src/lookups/passwd.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/passwd.c	2008-08-13 15:30:05.000000000 +0100
@@ -8,8 +8,6 @@
 /* See the file NOTICE for conditions of use and distribution. */
 
 #include "../exim.h"
-#include "passwd.h"
-
 
 
 /*************************************************
@@ -18,7 +16,7 @@
 
 /* See local README for interface description */
 
-void *
+static void *
 passwd_open(uschar *filename, uschar **errmsg)
 {
 filename = filename;     /* Keep picky compilers happy */
@@ -35,7 +33,7 @@
 
 /* See local README for interface description */
 
-int
+static int
 passwd_find(void *handle, uschar *filename, uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -53,4 +51,22 @@
 return OK;
 }
 
+static lookup_info _lookup_info = {
+  US"passwd",                    /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  passwd_open,                   /* open function */
+  NULL,                          /* no check function */
+  passwd_find,                   /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define passwd_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info passwd_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/passwd.c */
diff -uNr exim-4.69-old/src/lookups/passwd.h exim-4.69/src/lookups/passwd.h
--- exim-4.69-old/src/lookups/passwd.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/passwd.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/passwd.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the passwd lookup */
-
-extern void *passwd_open(uschar *, uschar **);
-extern int   passwd_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/passwd.h */
diff -uNr exim-4.69-old/src/lookups/pgsql.c exim-4.69/src/lookups/pgsql.c
--- exim-4.69-old/src/lookups/pgsql.c	2007-08-23 11:16:51.000000000 +0100
+++ exim-4.69/src/lookups/pgsql.c	2008-08-13 15:30:05.000000000 +0100
@@ -13,21 +13,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "pgsql.h"       /* The local header */
-
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the PGSQL header
-available for compiling. Therefore, compile these functions only if
-LOOKUP_PGSQL is defined. However, some compilers don't like compiling empty
-modules, so keep them happy with a dummy when skipping the rest. Make it
-reference itself to stop picky compilers complaining that it is unused, and put
-in a dummy argument to stop even pickier compilers complaining about infinite
-loops. */
-
-#ifndef LOOKUP_PGSQL
-static void dummy(int x) { dummy(x-1); }
-#else
-
 
 #include <libpq-fe.h>       /* The system header */
 
@@ -49,7 +34,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 pgsql_open(uschar *filename, uschar **errmsg)
 {
 return (void *)(1);    /* Just return something non-null */
@@ -63,7 +48,7 @@
 
 /* See local README for interface description. */
 
-void
+static void
 pgsql_tidy(void)
 {
 pgsql_connection *cn;
@@ -414,7 +399,7 @@
 query is deferred with a retryable error is now in a separate function that is
 shared with other SQL lookups. */
 
-int
+static int
 pgsql_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -454,7 +439,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *
+static uschar *
 pgsql_quote(uschar *s, uschar *opt)
 {
 register int c;
@@ -501,6 +486,22 @@
 return quoted;
 }
 
-#endif  /* PGSQL_LOOKUP */
+static lookup_info _lookup_info = {
+  US"pgsql",                     /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  pgsql_open,                    /* open function */
+  NULL,                          /* no check function */
+  pgsql_find,                    /* find function */
+  NULL,                          /* no close function */
+  pgsql_tidy,                    /* tidy function */
+  pgsql_quote                    /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define pgsql_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info pgsql_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/pgsql.c */
diff -uNr exim-4.69-old/src/lookups/pgsql.h exim-4.69/src/lookups/pgsql.h
--- exim-4.69-old/src/lookups/pgsql.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/pgsql.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/pgsql.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the pgsql lookup functions */
-
-extern void *pgsql_open(uschar *, uschar **);
-extern int   pgsql_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-extern void  pgsql_tidy(void);
-extern uschar *pgsql_quote(uschar *, uschar *);
-
-/* End of lookups/pgsql.h */
diff -uNr exim-4.69-old/src/lookups/spf.c exim-4.69/src/lookups/spf.c
--- exim-4.69-old/src/lookups/spf.c	2005-06-27 19:01:02.000000000 +0100
+++ exim-4.69/src/lookups/spf.c	2008-08-13 15:30:05.000000000 +0100
@@ -24,7 +24,6 @@
 #else
 
 #include "lf_functions.h"
-#include "spf.h"
 #ifndef HAVE_NS_TYPE
 #define HAVE_NS_TYPE
 #endif
@@ -32,7 +31,7 @@
 #include <spf2/spf_dns_resolv.h>
 #include <spf2/spf_dns_cache.h>
 
-void *spf_open(uschar *filename, uschar **errmsg) {
+static void *spf_open(uschar *filename, uschar **errmsg) {
   SPF_server_t *spf_server = NULL;
   spf_server = SPF_server_new(SPF_DNS_CACHE, 0);
   if (spf_server == NULL) {
@@ -42,13 +41,14 @@
   return (void *) spf_server;
 }
 
-void spf_close(void *handle) {
+static void spf_close(void *handle) {
   SPF_server_t *spf_server = handle;
   if (spf_server) SPF_server_free(spf_server);
 }
 
-int spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
-             uschar **result, uschar **errmsg, BOOL *do_cache) {
+static int
+spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
+         uschar **result, uschar **errmsg, BOOL *do_cache) {
   SPF_server_t *spf_server = handle;
   SPF_request_t *spf_request = NULL;
   SPF_response_t *spf_response = NULL;
@@ -75,4 +75,22 @@
   return OK;
 }
 
+static lookup_info _lookup_info = {
+  US"spf",                       /* lookup name */
+  0,                             /* not absfile, not query style */
+  spf_open,                      /* open function */
+  NULL,                          /* no check function */
+  spf_find,                      /* find function */
+  spf_close,                     /* close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define spf_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info spf_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 #endif /* EXPERIMENTAL_SPF */
diff -uNr exim-4.69-old/src/lookups/spf.h exim-4.69/src/lookups/spf.h
--- exim-4.69-old/src/lookups/spf.h	2005-05-25 21:07:55.000000000 +0100
+++ exim-4.69/src/lookups/spf.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,26 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/spf.h,v 1.1 2005/05/25 20:07:55 tom Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/*
- * Exim - SPF lookup module using libspf2
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Copyright (c) 2005 Chris Webb, Arachsys Internet Services Ltd
- *
- * 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.
- *
-*/
-
-
-
-extern void *spf_open(uschar *, uschar **);
-extern void spf_close(void *);
-extern int spf_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-                    BOOL *);
-
diff -uNr exim-4.69-old/src/lookups/sqlite.c exim-4.69/src/lookups/sqlite.c
--- exim-4.69-old/src/lookups/sqlite.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/sqlite.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,11 +9,7 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "sqlite.h"
 
-#ifndef LOOKUP_SQLITE
-static void dummy(int x) { dummy(x-1); }
-#else
 #include <sqlite3.h>
 
 
@@ -23,7 +19,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 sqlite_open(uschar *filename, uschar **errmsg)
 {
 sqlite3 *db = NULL;
@@ -85,7 +81,7 @@
 }
 
 
-int
+static int
 sqlite_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -113,7 +109,7 @@
 
 /* See local README for interface description. */
 
-void sqlite_close(void *handle)
+static void sqlite_close(void *handle)
 {
 sqlite3_close(handle);
 }
@@ -134,7 +130,7 @@
 Returns:     the processed string or NULL for a bad option
 */
 
-uschar *
+static uschar *
 sqlite_quote(uschar *s, uschar *opt)
 {
 register int c;
@@ -159,6 +155,22 @@
 return quoted;
 }
 
-#endif /* LOOKUP_SQLITE */
+static lookup_info _lookup_info = {
+  US"sqlite",                    /* lookup name */
+  lookup_absfilequery,           /* query-style lookup, starts with file name */
+  sqlite_open,                   /* open function */
+  NULL,                          /* no check function */
+  sqlite_find,                   /* find function */
+  sqlite_close,                  /* close function */
+  NULL,                          /* no tidy function */
+  sqlite_quote                   /* quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define sqlite_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info sqlite_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/sqlite.c */
diff -uNr exim-4.69-old/src/lookups/sqlite.h exim-4.69/src/lookups/sqlite.h
--- exim-4.69-old/src/lookups/sqlite.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/sqlite.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/sqlite.h,v 1.3 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the sqlite lookup */
-
-extern void   *sqlite_open(uschar *, uschar **);
-extern int     sqlite_find(void *, uschar *, uschar *, int, uschar **,
-                 uschar **, BOOL *);
-extern void    sqlite_close(void *);
-extern uschar *sqlite_quote(uschar *, uschar *);
-
-/* End of lookups/sqlite.h */
diff -uNr exim-4.69-old/src/lookups/testdb.c exim-4.69/src/lookups/testdb.c
--- exim-4.69-old/src/lookups/testdb.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/testdb.c	2008-08-13 15:30:05.000000000 +0100
@@ -9,8 +9,6 @@
 
 #include "../exim.h"
 #include "lf_functions.h"
-#include "testdb.h"
-
 
 /* These are not real lookup functions; they are just a way of testing the
 rest of Exim by providing an easy way of specifying particular yields from
@@ -23,7 +21,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 testdb_open(uschar *filename, uschar **errmsg)
 {
 filename = filename;   /* Keep picky compilers happy */
@@ -39,7 +37,7 @@
 
 /* See local README for interface description. */
 
-int
+static int
 testdb_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -66,4 +64,22 @@
 return OK;
 }
 
+static lookup_info _lookup_info = {
+  US"testdb",                    /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  testdb_open,                   /* open function */
+  NULL,                          /* check function */
+  testdb_find,                   /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define testdb_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info testdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
+
 /* End of lookups/testdb.c */
diff -uNr exim-4.69-old/src/lookups/testdb.h exim-4.69/src/lookups/testdb.h
--- exim-4.69-old/src/lookups/testdb.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/testdb.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/testdb.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the testdb lookup */
-
-extern void *testdb_open(uschar *, uschar **);
-extern int   testdb_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/testdb.h */
diff -uNr exim-4.69-old/src/lookups/whoson.c exim-4.69/src/lookups/whoson.c
--- exim-4.69-old/src/lookups/whoson.c	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/whoson.c	2008-08-13 15:30:05.000000000 +0100
@@ -12,23 +12,7 @@
 #include "../exim.h"
 
 
-/* We can't just compile this code and allow the library mechanism to omit the
-functions if they are not wanted, because we need to have the WHOSON headers
-available for compiling. Therefore, compile these functions only if
-LOOKUP_WHOSON is defined. However, some compilers don't like compiling empty
-modules, so keep them happy with a dummy when skipping the rest. Make it
-reference itself to stop picky compilers complaining that it is unused, and put
-in a dummy argument to stop even pickier compilers complaining about infinite
-loops. */
-
-#ifndef LOOKUP_WHOSON
-static void dummy(int x) { dummy(x-1); }
-#else
-
-
 #include <whoson.h>        /* Public header */
-#include "whoson.h"        /* Local header */
-
 
 /*************************************************
 *              Open entry point                  *
@@ -36,7 +20,7 @@
 
 /* See local README for interface description. */
 
-void *
+static void *
 whoson_open(uschar *filename, uschar **errmsg)
 {
 filename = filename;   /* Keep picky compilers happy */
@@ -51,7 +35,7 @@
 
 /* See local README for interface description. */
 
-int
+static int
 whoson_find(void *handle, uschar *filename, uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
@@ -77,6 +61,22 @@
   }
 }
 
-#endif  /* LOOKUP_WHOSON */
+static lookup_info _lookup_info = {
+  US"whoson",                    /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+  whoson_open,                   /* open function */
+  NULL,                          /* check function */
+  whoson_find,                   /* find function */
+  NULL,                          /* no close function */
+  NULL,                          /* no tidy function */
+  NULL                           /* no quoting function */
+};
+
+#ifdef DYNLOOKUP
+#define whoson_lookup_module_info _lookup_module_info
+#endif
+
+static lookup_info *_lookup_list[] = { &_lookup_info };
+lookup_module_info whoson_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 /* End of lookups/whoson.c */
diff -uNr exim-4.69-old/src/lookups/whoson.h exim-4.69/src/lookups/whoson.h
--- exim-4.69-old/src/lookups/whoson.h	2007-01-08 10:50:19.000000000 +0000
+++ exim-4.69/src/lookups/whoson.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-/* $Cambridge: exim/exim-src/src/lookups/whoson.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */
-
-/*************************************************
-*     Exim - an Internet mail transport agent    *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2007 */
-/* See the file NOTICE for conditions of use and distribution. */
-
-/* Header for the whoson lookup */
-
-extern void *whoson_open(uschar *, uschar **);
-extern int   whoson_find(void *, uschar *, uschar *, int, uschar **, uschar **,
-               BOOL *);
-
-/* End of lookups/whoson.h */
diff -uNr exim-4.69-old/src/macros.h exim-4.69/src/macros.h
--- exim-4.69-old/src/macros.h	2007-08-22 11:10:23.000000000 +0100
+++ exim-4.69/src/macros.h	2008-08-13 15:30:05.000000000 +0100
@@ -96,7 +96,7 @@
 
 /* A macro to simplify testing bits in lookup types */
 
-#define mac_islookup(a,b) ((lookup_list[a].type & (b)) != 0)
+#define mac_islookup(a,b) ((lookup_list[a]->type & (b)) != 0)
 
 /* Debugging control */
 
diff -uNr exim-4.69-old/src/search.c exim-4.69/src/search.c
--- exim-4.69-old/src/search.c	2007-08-29 15:02:22.000000000 +0100
+++ exim-4.69/src/search.c	2008-08-13 15:30:05.000000000 +0100
@@ -71,7 +71,7 @@
 while (top > bot)
   {
   int mid = (top + bot)/2;
-  int c = Ustrncmp(name, lookup_list[mid].name, len);
+  int c = Ustrncmp(name, lookup_list[mid]->name, len);
 
   /* If c == 0 we have matched the incoming name with the start of the search
   type name. However, some search types are substrings of others (e.g. nis and
@@ -81,9 +81,9 @@
   are testing. By leaving c == 0 when the lengths are different, and doing a
   > 0 test below, this all falls out correctly. */
 
-  if (c == 0 && Ustrlen(lookup_list[mid].name) == len)
+  if (c == 0 && Ustrlen(lookup_list[mid]->name) == len)
     {
-    if (lookup_list[mid].find != NULL) return mid;
+    if (lookup_list[mid]->find != NULL) return mid;
     search_error_message  = string_sprintf("lookup type \"%.*s\" is not "
       "available (not in the binary - check buildtime LOOKUP configuration)",
       len, name);
@@ -237,8 +237,8 @@
 if (t->right != NULL) tidyup_subtree(t->right);
 if (c != NULL &&
     c->handle != NULL &&
-    lookup_list[c->search_type].close != NULL)
-  lookup_list[c->search_type].close(c->handle);
+    lookup_list[c->search_type]->close != NULL)
+  lookup_list[c->search_type]->close(c->handle);
 }
 
 
@@ -270,7 +270,7 @@
 /* Call the general tidyup entry for any drivers that have one. */
 
 for (i = 0; i < lookup_list_count; i++)
-  if (lookup_list[i].tidy != NULL) (lookup_list[i].tidy)();
+  if (lookup_list[i]->tidy != NULL) (lookup_list[i]->tidy)();
 
 if (search_reset_point != NULL) store_reset(search_reset_point);
 search_reset_point = NULL;
@@ -335,7 +335,7 @@
 void *handle;
 tree_node *t;
 search_cache *c;
-lookup_info *lk = lookup_list + search_type;
+lookup_info *lk = lookup_list[search_type];
 uschar keybuffer[256];
 int old_pool = store_pool;
 
@@ -388,7 +388,7 @@
       ((search_cache *)(open_bot->data.ptr))->down = NULL;
     else
       open_top = NULL;
-    ((lookup_list + c->search_type)->close)(c->handle);
+    ((lookup_list[c->search_type])->close)(c->handle);
     c->handle = NULL;
     open_filecount--;
     }
@@ -480,7 +480,7 @@
 
 DEBUG(D_lookup) debug_printf("internal_search_find: file=\"%s\"\n  "
   "type=%s key=\"%s\"\n", filename,
-  lookup_list[search_type].name, keystring);
+  lookup_list[search_type]->name, keystring);
 
 /* Insurance. If the keystring is empty, just fail. */
 
@@ -511,7 +511,7 @@
   like FAIL, except that search_find_defer is set so the caller can
   distinguish if necessary. */
 
-  if (lookup_list[search_type].find(c->handle, filename, keystring, keylength,
+  if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength,
       &data, &search_error_message, &do_cache) == DEFER)
     {
     search_find_defer = TRUE;
@@ -622,7 +622,7 @@
 that opens real files. */
 
 if (open_top != (tree_node *)handle &&
-    lookup_list[t->name[0]-'0'].type == lookup_absfile)
+    lookup_list[t->name[0]-'0']->type == lookup_absfile)
   {
   search_cache *c = (search_cache *)(t->data.ptr);
   tree_node *up = c->up;
diff -uNr exim-4.69-old/src/structs.h exim-4.69/src/structs.h
--- exim-4.69-old/src/structs.h	2007-06-18 14:57:50.000000000 +0100
+++ exim-4.69/src/structs.h	2008-08-13 15:30:05.000000000 +0100
@@ -322,34 +322,7 @@
 
 /* Structure for holding information about a lookup type. */
 
-typedef struct lookup_info {
-  uschar *name;                   /* e.g. "lsearch" */
-  int type;                       /* query/singlekey/abs-file */
-  void *(*open)(                  /* open function */
-    uschar *,                     /* file name for those that have one */
-    uschar **);                   /* for error message */
-  BOOL (*check)(                  /* file checking function */
-    void *,                       /* handle */
-    uschar *,                     /* file name */
-    int,                          /* modemask for file checking */
-    uid_t *,                      /* owners for file checking */
-    gid_t *,                      /* owngroups for file checking */
-    uschar **);                   /* for error messages */
-  int (*find)(                    /* find function */
-    void *,                       /* handle */
-    uschar *,                     /* file name or NULL */
-    uschar *,                     /* key or query */
-    int,                          /* length of key or query */
-    uschar **,                    /* for returning answer */
-    uschar **,                    /* for error message */
-    BOOL *);                      /* to request cache cleanup */
-  void (*close)(                  /* close function */
-    void *);                      /* handle */
-  void (*tidy)(void);             /* tidy function */
-  uschar *(*quote)(               /* quoting function */
-    uschar *,                     /* string to quote */
-    uschar *);                    /* additional data from quote name */
-} lookup_info;
+#include "lookupapi.h"
 
 
 /* Structure for holding information about the configured authentication
diff -uNr exim-4.69-old/src/verify.c exim-4.69/src/verify.c
--- exim-4.69-old/src/verify.c	2007-06-14 15:18:19.000000000 +0100
+++ exim-4.69/src/verify.c	2008-08-13 15:30:05.000000000 +0100
@@ -2219,7 +2219,7 @@
     }
   else   /* Single-key style */
     {
-    int sep = (Ustrcmp(lookup_list[search_type].name, "iplsearch") == 0)?
+    int sep = (Ustrcmp(lookup_list[search_type]->name, "iplsearch") == 0)?
       ':' : '.';
     insize = host_aton(cb->host_address, incoming);
     host_mask(insize, incoming, mlen);