[exim-dev] [PATCH] loading libspf dynamically

Top Page
Delete this message
Reply to this message
Author: Robert Millan
Date:  
To: exim-dev
Subject: [exim-dev] [PATCH] loading libspf dynamically

This is a preliminar patch for loading libspf dynamically. It still needs
testing, cleanup and better integration with Exim coding style, etc; Before
I complete it, would be nice to get some feedback on:

  - Are you interested in other libraries having the same feature?  I tried
    to make the layout easily extensible, and maybe I could add other libs if
    time permits.


  - Should linkage of supported libraries just switch to this method, or keep
    both as a user option?


  - What to do when loading fails?  At least for now I guess the sane thing to
    do is fatal error, since Exim code is probably not fault tollerant to some
    libspf calls.  Should this be contemplated in the future?


--
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
diff -x EDITME -x os.h-Linux -Nur exim-4.69/OS/Makefile-Base exim-4.69.new/OS/Makefile-Base
--- exim-4.69/OS/Makefile-Base    2008-02-14 15:02:56.000000000 +0100
+++ exim-4.69.new/OS/Makefile-Base    2008-02-14 14:56:37.000000000 +0100
@@ -304,7 +304,7 @@
 # updated each time. We don't bother with that for the auxiliaries.


 OBJ_EXIM = acl.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
-        directory.o dns.o drtables.o enq.o exim.o expand.o filter.o \
+        directory.o dns.o drtables.o dynamic.o enq.o exim.o expand.o filter.o \
         filtertest.o globals.o \
         header.o host.o ip.o log.o lss.o match.o moan.o \
         os.o parse.o queue.o \
@@ -541,6 +541,7 @@
 deliver.o:       $(HDRS) deliver.c
 directory.o:     $(HDRS) directory.c
 dns.o:           $(HDRS) dns.c
+dynamic.o:       $(HDRS) dynamic.c
 enq.o:           $(HDRS) enq.c
 exim.o:          $(HDRS) exim.c
 expand.o:        $(HDRS) expand.c
diff -x EDITME -x os.h-Linux -Nur exim-4.69/scripts/MakeLinks exim-4.69.new/scripts/MakeLinks
--- exim-4.69/scripts/MakeLinks    2007-09-28 14:21:57.000000000 +0200
+++ exim-4.69.new/scripts/MakeLinks    2008-02-14 14:55:39.000000000 +0100
@@ -217,6 +217,7 @@
 ln -s ../src/dns.c             dns.c
 ln -s ../src/drtables.c        drtables.c
 ln -s ../src/dummies.c         dummies.c
+ln -s ../src/dynamic.c         dynamic.c
 ln -s ../src/enq.c             enq.c
 ln -s ../src/exim.c            exim.c
 ln -s ../src/exim_dbmbuild.c   exim_dbmbuild.c
diff -x EDITME -x os.h-Linux -Nur exim-4.69/src/dynamic.c exim-4.69.new/src/dynamic.c
--- exim-4.69/src/dynamic.c    1970-01-01 01:00:00.000000000 +0100
+++ exim-4.69.new/src/dynamic.c    2008-02-14 17:12:08.000000000 +0100
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2008 Robert Millan
+ *
+ * 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.
+ *
+ */
+
+#ifdef DYNAMIC_LOADER
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#include "exim.h"
+
+static struct { void *handle; char filename[]; } dltable[] =
+{
+#ifdef EXPERIMENTAL_SPF
+  { NULL, "libspf2.so.2" },
+#endif
+};
+
+enum dltable_members
+{
+#ifdef EXPERIMENTAL_SPF
+  LIBSPF,
+#endif
+};
+
+static void *
+load_so (char *so)
+{
+  void *ret;
+
+  ret = dlopen (so, RTLD_GLOBAL|RTLD_LAZY);
+  if (! ret)
+    {
+      fprintf (stderr, "%s\n", dlerror ());
+      exit (1);
+    }
+
+  return ret;
+}
+
+static void *
+load_sym (int id, char *sym)
+{
+  void *ret;
+  char *err;
+
+  if (! dltable[id].handle)
+    dltable[id].handle = load_so (dltable[id].filename);
+
+  dlerror (); /* Clear old error conditions.  */
+  ret = dlsym (dltable[id].handle, sym);
+  err = dlerror ();
+  if (err)
+    {
+      fprintf (stderr, "%s\n", err);
+      exit (1);
+    }
+
+  return ret;
+}
+
+
+
+#ifdef EXPERIMENTAL_SPF
+
+static SPF_request_t *(*fn_SPF_request_new_ptr) (SPF_server_t *) = NULL;
+SPF_request_t *
+SPF_request_new (SPF_server_t *spf_server)
+{
+  if (! fn_SPF_request_new_ptr)
+    fn_SPF_request_new_ptr = load_sym (LIBSPF, "SPF_request_new");
+  return (*fn_SPF_request_new_ptr) (spf_server);
+}
+
+int (*fn_SPF_request_set_env_from_ptr) (SPF_request_t *, const char *) = NULL;
+int
+SPF_request_set_env_from (SPF_request_t *sr, const char *from)
+{
+  if (! fn_SPF_request_set_env_from_ptr)
+    fn_SPF_request_set_env_from_ptr = load_sym (LIBSPF, "SPF_request_set_env_from");
+  return (*fn_SPF_request_set_env_from_ptr) (sr, from);
+}
+
+SPF_errcode_t (*fn_SPF_request_query_mailfrom_ptr) (SPF_request_t *, SPF_response_t **) = NULL;
+SPF_errcode_t
+SPF_request_query_mailfrom (SPF_request_t *spf_request, SPF_response_t **spf_responsep)
+{
+  if (! fn_SPF_request_query_mailfrom_ptr)
+    fn_SPF_request_query_mailfrom_ptr = load_sym (LIBSPF, "SPF_request_query_mailfrom");
+  return (*fn_SPF_request_query_mailfrom_ptr) (spf_request, spf_responsep);
+}
+
+SPF_errcode_t (*fn_SPF_request_set_ipv4_str_ptr) (SPF_request_t *, const char *) = NULL;
+SPF_errcode_t
+SPF_request_set_ipv4_str (SPF_request_t *sr, const char *astr)
+{
+  if (! fn_SPF_request_set_ipv4_str_ptr)
+    fn_SPF_request_set_ipv4_str_ptr = load_sym (LIBSPF, "SPF_request_set_ipv4_str");
+  return (*fn_SPF_request_set_ipv4_str_ptr) (sr, astr);
+}
+
+SPF_errcode_t (*fn_SPF_request_set_helo_dom_ptr) (SPF_request_t *, const char *) = NULL;
+SPF_errcode_t
+SPF_request_set_helo_dom (SPF_request_t *sr, const char *dom)
+{
+  if (! fn_SPF_request_set_helo_dom_ptr)
+    fn_SPF_request_set_helo_dom_ptr = load_sym (LIBSPF, "SPF_request_set_helo_dom");
+  return (*fn_SPF_request_set_helo_dom_ptr) (sr, dom);
+}
+
+void (*fn_SPF_request_free_ptr) (SPF_request_t *) = NULL;
+void
+SPF_request_free (SPF_request_t *sr)
+{
+  if (! fn_SPF_request_free_ptr)
+    fn_SPF_request_free_ptr = load_sym (LIBSPF, "SPF_request_free");
+  return (*fn_SPF_request_free_ptr) (sr);
+}
+
+const char *(*fn_SPF_response_get_header_comment_ptr) (SPF_response_t *) = NULL;
+const char *
+SPF_response_get_header_comment (SPF_response_t *rp)
+{
+  if (! fn_SPF_response_get_header_comment_ptr)
+    fn_SPF_response_get_header_comment_ptr = load_sym (LIBSPF, "SPF_response_get_header_comment");
+  return (*fn_SPF_response_get_header_comment_ptr) (rp);
+}
+
+const char *(*fn_SPF_response_get_smtp_comment_ptr) (SPF_response_t *) = NULL;
+const char *
+SPF_response_get_smtp_comment (SPF_response_t *rp)
+{
+  if (! fn_SPF_response_get_smtp_comment_ptr)
+    fn_SPF_response_get_smtp_comment_ptr = load_sym (LIBSPF, "SPF_response_get_smtp_comment");
+  return (*fn_SPF_response_get_smtp_comment_ptr) (rp);
+}
+
+const char *(*fn_SPF_response_get_received_spf_ptr) (SPF_response_t *) = NULL;
+const char *
+SPF_response_get_received_spf (SPF_response_t *rp)
+{
+  if (! fn_SPF_response_get_received_spf_ptr)
+    fn_SPF_response_get_received_spf_ptr = load_sym (LIBSPF, "SPF_response_get_received_spf");
+  return (*fn_SPF_response_get_received_spf_ptr) (rp);
+}
+
+SPF_result_t (*fn_SPF_response_result_ptr) (SPF_response_t *) = NULL;
+SPF_result_t
+SPF_response_result (SPF_response_t *rp)
+{
+  if (! fn_SPF_response_result_ptr)
+    fn_SPF_response_result_ptr = load_sym (LIBSPF, "SPF_response_result");
+  return (*fn_SPF_response_result_ptr) (rp);
+}
+
+void (*fn_SPF_response_free_ptr) (SPF_response_t *) = NULL;
+void
+SPF_response_free (SPF_response_t *rp)
+{
+  if (! fn_SPF_response_free_ptr)
+    fn_SPF_response_free_ptr = load_sym (LIBSPF, "SPF_response_free");
+  return (*fn_SPF_response_free_ptr) (rp);
+}
+
+const char *(*fn_SPF_strresult_ptr) (SPF_result_t) = NULL;
+const char *
+SPF_strresult (SPF_result_t result)
+{
+  if (! fn_SPF_strresult_ptr)
+    fn_SPF_strresult_ptr = load_sym (LIBSPF, "SPF_strresult");
+  return (*fn_SPF_strresult_ptr) (result);
+}
+
+
+SPF_server_t *(*fn_SPF_server_new_ptr) (SPF_server_dnstype_t, int) = NULL;
+SPF_server_t *
+SPF_server_new (SPF_server_dnstype_t dnstype, int debug)
+{
+  if (! fn_SPF_server_new_ptr)
+    fn_SPF_server_new_ptr = load_sym (LIBSPF, "SPF_server_new");
+  return (*fn_SPF_server_new_ptr) (dnstype, debug);
+}
+
+SPF_errcode_t (*fn_SPF_server_set_rec_dom_ptr) (SPF_server_t *, const char *) = NULL;
+SPF_errcode_t
+SPF_server_set_rec_dom (SPF_server_t *sp, const char *dom)
+{
+  if (! fn_SPF_server_set_rec_dom_ptr)
+    fn_SPF_server_set_rec_dom_ptr = load_sym (LIBSPF, "SPF_server_set_rec_dom");
+  return (*fn_SPF_server_set_rec_dom_ptr) (sp, dom);
+}
+
+void (*fn_SPF_server_free_ptr) (SPF_server_t *) = NULL;
+void
+SPF_server_free (SPF_server_t *sp)
+{
+  if (! fn_SPF_server_free_ptr)
+    fn_SPF_server_free_ptr = load_sym (LIBSPF, "SPF_server_free");
+  return (*fn_SPF_server_free_ptr) (sp);
+}
+
+#endif /* EXPERIMENTAL_SPF */
+
+#endif /* DYNAMIC_LOADER */