]> git.pld-linux.org Git - packages/exim.git/blame - localscan_dlopen_exim_4.20_or_better.patch
- rel 5; update from git
[packages/exim.git] / localscan_dlopen_exim_4.20_or_better.patch
CommitLineData
4d241ba7
AM
1The initial version of this patch was originally posted David Woodhouse, and
2dman gets the credit for first integrating it with SA-Exim.
3
4I have since then maintained it by first making a few minor changes, and
5later switching it to a major/minor number scheme to support upgrades in
6the exim API that don't affect backward compatibility (you can rely on
7a feature denoted by the minor number and be compatible with future versions
8of exim until Philip has to break the API and increase the major number)
9
10Marc MERLIN <marc_soft@merlins.org>
11
12diff -urN exim-4.14-0/src/EDITME exim-4.14-1/src/EDITME
13--- exim-4.14-0/src/EDITME Tue Mar 11 04:20:18 2003
14+++ exim-4.14-1/src/EDITME Sun Mar 23 15:34:15 2003
15@@ -388,6 +388,20 @@
16
17
18 #------------------------------------------------------------------------------
19+# On systems which support dynamic loading of shared libraries, Exim can
20+# load a local_scan function specified in its config file instead of having
21+# to be recompiled with the desired local_scan function. For a full
22+# description of the API to this function, see the Exim specification.
23+
24+DLOPEN_LOCAL_SCAN=yes
25+
26+# If you set DLOPEN_LOCAL_SCAN, then you need to include -rdynamic in the
27+# linker flags. Without it, the loaded .so won't be able to access any
28+# functions from exim.
29+
30+LFLAGS=-rdynamic -ldl
31+
32+#------------------------------------------------------------------------------
33 # The default distribution of Exim contains only the plain text form of the
34 # documentation. Other forms are available separately. If you want to install
35 # the documentation in "info" format, first fetch the Texinfo documentation
36diff -urNad 50_localscan_dlopen.tmp/src/config.h.defaults 50_localscan_dlopen/src/config.h.defaults
37--- 50_localscan_dlopen.tmp/src/config.h.defaults Sun Dec 29 11:55:42 2002
38+++ 50_localscan_dlopen/src/config.h.defaults Sun Dec 29 11:56:44 2002
39@@ -17,6 +17,8 @@
40 #define AUTH_PLAINTEXT
41 #define AUTH_SPA
42
43+#define DLOPEN_LOCAL_SCAN
44+
45 #define BIN_DIRECTORY
46
47 #define CONFIGURE_FILE
48diff -urN exim-4.14-0/src/globals.c exim-4.14-1/src/globals.c
49--- exim-4.14-0/src/globals.c Tue Mar 11 04:20:20 2003
50+++ exim-4.14-1/src/globals.c Sun Mar 23 15:34:15 2003
51@@ -103,6 +103,9 @@
52 uschar *tls_verify_hosts = NULL;
53 #endif
54
55+#ifdef DLOPEN_LOCAL_SCAN
56+uschar *local_scan_path = NULL;
57+#endif
58
59 /* Input-reading functions for messages, so we can use special ones for
60 incoming TCP/IP. The defaults use stdin. We never need these for any
61diff -urN exim-4.14-0/src/globals.h exim-4.14-1/src/globals.h
62--- exim-4.14-0/src/globals.h Tue Mar 11 04:20:20 2003
63+++ exim-4.14-1/src/globals.h Sun Mar 23 15:34:15 2003
64@@ -67,6 +67,9 @@
65 extern uschar *tls_verify_hosts; /* Mandatory client verification */
66 #endif
67
68+#ifdef DLOPEN_LOCAL_SCAN
69+extern uschar *local_scan_path; /* Path to local_scan() library */
70+#endif
71
72 /* Input-reading functions for messages, so we can use special ones for
73 incoming TCP/IP. */
74diff -urN exim-4.14-0/src/local_scan.c exim-4.14-1/src/local_scan.c
75--- exim-4.14-0/src/local_scan.c Tue Mar 11 04:20:20 2003
76+++ exim-4.14-1/src/local_scan.c Sun Mar 23 15:34:15 2003
048ec4ef 77@@ -5,61 +5,131 @@
4d241ba7
AM
78 /* Copyright (c) University of Cambridge 1995 - 2003 */
79 /* See the file NOTICE for conditions of use and distribution. */
80
81+#include "exim.h"
82
83-/******************************************************************************
84-This file contains a template local_scan() function that just returns ACCEPT.
85-If you want to implement your own version, you should copy this file to, say
86-Local/local_scan.c, and edit the copy. To use your version instead of the
87-default, you must set
88-
048ec4ef 89-HAVE_LOCAL_SCAN=yes
4d241ba7
AM
90-LOCAL_SCAN_SOURCE=Local/local_scan.c
91-
92-in your Local/Makefile. This makes it easy to copy your version for use with
93-subsequent Exim releases.
94-
95-For a full description of the API to this function, see the Exim specification.
96-******************************************************************************/
97-
98-
99-/* This is the only Exim header that you should include. The effect of
100-including any other Exim header is not defined, and may change from release to
101-release. Use only the documented interface! */
102-
103-#include "local_scan.h"
104-
105-
106-/* This is a "do-nothing" version of a local_scan() function. The arguments
107-are:
108-
109- fd The file descriptor of the open -D file, which contains the
110- body of the message. The file is open for reading and
111- writing, but modifying it is dangerous and not recommended.
112-
113- return_text A pointer to an unsigned char* variable which you can set in
114- order to return a text string. It is initialized to NULL.
115-
116-The return values of this function are:
117-
118- LOCAL_SCAN_ACCEPT
119- The message is to be accepted. The return_text argument is
120- saved in $local_scan_data.
121-
122- LOCAL_SCAN_REJECT
123- The message is to be rejected. The returned text is used
124- in the rejection message.
125-
126- LOCAL_SCAN_TEMPREJECT
127- This specifies a temporary rejection. The returned text
128- is used in the rejection message.
129-*/
130+#ifdef DLOPEN_LOCAL_SCAN
131+#include <dlfcn.h>
132+static int (*local_scan_fn)(int fd, uschar **return_text) = NULL;
133+static int load_local_scan_library(void);
134+#endif
135
136 int
137 local_scan(int fd, uschar **return_text)
138 {
139 fd = fd; /* Keep picky compilers happy */
140 return_text = return_text;
141-return LOCAL_SCAN_ACCEPT;
142+#ifdef DLOPEN_LOCAL_SCAN
143+/* local_scan_path is defined AND not the empty string */
144+if (local_scan_path && *local_scan_path)
145+ {
146+ if (!local_scan_fn)
147+ {
148+ if (!load_local_scan_library())
149+ {
150+ char *base_msg , *error_msg , *final_msg ;
151+ int final_length = -1 ;
152+
153+ base_msg=US"Local configuration error - local_scan() library failure\n";
154+ error_msg = dlerror() ;
155+
156+ final_length = strlen(base_msg) + strlen(error_msg) + 1 ;
157+ final_msg = (char*)malloc( final_length*sizeof(char) ) ;
158+ *final_msg = '\0' ;
159+
160+ strcat( final_msg , base_msg ) ;
161+ strcat( final_msg , error_msg ) ;
162+
163+ *return_text = final_msg ;
164+ return LOCAL_SCAN_TEMPREJECT;
165+ }
166+ }
167+ return local_scan_fn(fd, return_text);
168+ }
169+else
170+#endif
171+ return LOCAL_SCAN_ACCEPT;
172+}
173+
174+#ifdef DLOPEN_LOCAL_SCAN
175+
176+static int load_local_scan_library(void)
177+{
178+/* No point in keeping local_scan_lib since we'll never dlclose() anyway */
179+void *local_scan_lib = NULL;
180+int (*local_scan_version_fn)(void);
181+int vers_maj;
182+int vers_min;
183+
184+local_scan_lib = dlopen(local_scan_path, RTLD_NOW);
185+if (!local_scan_lib)
186+ {
187+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - "
188+ "message temporarily rejected");
189+ return FALSE;
190+ }
191+
192+local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major");
193+if (!local_scan_version_fn)
194+ {
195+ dlclose(local_scan_lib);
196+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
197+ "local_scan_version_major() function - message temporarily rejected");
198+ return FALSE;
199+ }
200+
201+/* The major number is increased when the ABI is changed in a non
202+ backward compatible way. */
203+vers_maj = local_scan_version_fn();
204+
205+local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor");
206+if (!local_scan_version_fn)
207+ {
208+ dlclose(local_scan_lib);
209+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
210+ "local_scan_version_minor() function - message temporarily rejected");
211+ return FALSE;
212+ }
213+
214+/* The minor number is increased each time a new feature is added (in a
215+ way that doesn't break backward compatibility) -- Marc */
216+vers_min = local_scan_version_fn();
217+
218+
219+if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR)
220+ {
221+ dlclose(local_scan_lib);
222+ local_scan_lib = NULL;
223+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major"
224+ "version number, you need to recompile your module for this version"
225+ "of exim (The module was compiled for version %d.%d and this exim provides"
226+ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
227+ LOCAL_SCAN_ABI_VERSION_MINOR);
228+ return FALSE;
229+ }
230+else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR)
231+ {
232+ dlclose(local_scan_lib);
233+ local_scan_lib = NULL;
234+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor"
235+ "version number, you need to recompile your module for this version"
236+ "of exim (The module was compiled for version %d.%d and this exim provides"
237+ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
238+ LOCAL_SCAN_ABI_VERSION_MINOR);
239+ return FALSE;
240+ }
241+
242+local_scan_fn = dlsym(local_scan_lib, "local_scan");
243+if (!local_scan_fn)
244+ {
245+ dlclose(local_scan_lib);
246+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
247+ "local_scan() function - message temporarily rejected");
248+ return FALSE;
249+ }
250+
251+return TRUE;
252 }
253+
254+#endif /* DLOPEN_LOCAL_SCAN */
255
256 /* End of local_scan.c */
257diff -urN exim-4.14-0/src/readconf.c exim-4.14-1/src/readconf.c
258--- exim-4.14-0/src/readconf.c Tue Mar 11 04:20:22 2003
259+++ exim-4.14-1/src/readconf.c Sun Mar 23 15:34:15 2003
260@@ -182,6 +182,9 @@
261 { "local_from_prefix", opt_stringptr, &local_from_prefix },
262 { "local_from_suffix", opt_stringptr, &local_from_suffix },
263 { "local_interfaces", opt_stringptr, &local_interfaces },
264+#ifdef DLOPEN_LOCAL_SCAN
265+ { "local_scan_path", opt_stringptr, &local_scan_path },
266+#endif
906bd90b 267 #ifdef HAVE_LOCAL_SCAN
4d241ba7 268 { "local_scan_timeout", opt_time, &local_scan_timeout },
906bd90b 269 #endif
This page took 0.081561 seconds and 4 git commands to generate.