Lines 5-64
Link Here
|
5 |
/* Copyright (c) University of Cambridge 1995 - 2004 */ |
5 |
/* Copyright (c) University of Cambridge 1995 - 2004 */ |
6 |
/* See the file NOTICE for conditions of use and distribution. */ |
6 |
/* See the file NOTICE for conditions of use and distribution. */ |
7 |
|
7 |
|
|
|
8 |
#include "exim.h" |
8 |
|
9 |
|
9 |
/****************************************************************************** |
10 |
#ifdef DLOPEN_LOCAL_SCAN |
10 |
This file contains a template local_scan() function that just returns ACCEPT. |
11 |
#include <dlfcn.h> |
11 |
If you want to implement your own version, you should copy this file to, say |
12 |
static int (*local_scan_fn)(int fd, uschar **return_text) = NULL; |
12 |
Local/local_scan.c, and edit the copy. To use your version instead of the |
13 |
static int load_local_scan_library(void); |
13 |
default, you must set |
14 |
#endif |
14 |
|
|
|
15 |
LOCAL_SCAN_SOURCE=Local/local_scan.c |
16 |
|
17 |
in your Local/Makefile. This makes it easy to copy your version for use with |
18 |
subsequent Exim releases. |
19 |
|
20 |
For a full description of the API to this function, see the Exim specification. |
21 |
******************************************************************************/ |
22 |
|
23 |
|
24 |
/* This is the only Exim header that you should include. The effect of |
25 |
including any other Exim header is not defined, and may change from release to |
26 |
release. Use only the documented interface! */ |
27 |
|
28 |
#include "local_scan.h" |
29 |
|
30 |
|
31 |
/* This is a "do-nothing" version of a local_scan() function. The arguments |
32 |
are: |
33 |
|
34 |
fd The file descriptor of the open -D file, which contains the |
35 |
body of the message. The file is open for reading and |
36 |
writing, but modifying it is dangerous and not recommended. |
37 |
|
38 |
return_text A pointer to an unsigned char* variable which you can set in |
39 |
order to return a text string. It is initialized to NULL. |
40 |
|
41 |
The return values of this function are: |
42 |
|
43 |
LOCAL_SCAN_ACCEPT |
44 |
The message is to be accepted. The return_text argument is |
45 |
saved in $local_scan_data. |
46 |
|
47 |
LOCAL_SCAN_REJECT |
48 |
The message is to be rejected. The returned text is used |
49 |
in the rejection message. |
50 |
|
51 |
LOCAL_SCAN_TEMPREJECT |
52 |
This specifies a temporary rejection. The returned text |
53 |
is used in the rejection message. |
54 |
*/ |
55 |
|
15 |
|
56 |
int |
16 |
int |
57 |
local_scan(int fd, uschar **return_text) |
17 |
local_scan(int fd, uschar **return_text) |
58 |
{ |
18 |
{ |
59 |
fd = fd; /* Keep picky compilers happy */ |
19 |
fd = fd; /* Keep picky compilers happy */ |
60 |
return_text = return_text; |
20 |
return_text = return_text; |
61 |
return LOCAL_SCAN_ACCEPT; |
21 |
#ifdef DLOPEN_LOCAL_SCAN |
|
|
22 |
/* local_scan_path is defined AND not the empty string */ |
23 |
if (local_scan_path && *local_scan_path) |
24 |
{ |
25 |
if (!local_scan_fn) |
26 |
{ |
27 |
if (!load_local_scan_library()) |
28 |
{ |
29 |
char *base_msg , *error_msg , *final_msg ; |
30 |
int final_length = -1 ; |
31 |
|
32 |
base_msg=US"Local configuration error - local_scan() library failure\n"; |
33 |
error_msg = dlerror() ; |
34 |
|
35 |
final_length = strlen(base_msg) + strlen(error_msg) + 1 ; |
36 |
final_msg = (char*)malloc( final_length*sizeof(char) ) ; |
37 |
*final_msg = '\0' ; |
38 |
|
39 |
strcat( final_msg , base_msg ) ; |
40 |
strcat( final_msg , error_msg ) ; |
41 |
|
42 |
*return_text = final_msg ; |
43 |
return LOCAL_SCAN_TEMPREJECT; |
44 |
} |
45 |
} |
46 |
return local_scan_fn(fd, return_text); |
47 |
} |
48 |
else |
49 |
#endif |
50 |
return LOCAL_SCAN_ACCEPT; |
51 |
} |
52 |
|
53 |
#ifdef DLOPEN_LOCAL_SCAN |
54 |
|
55 |
static int load_local_scan_library(void) |
56 |
{ |
57 |
/* No point in keeping local_scan_lib since we'll never dlclose() anyway */ |
58 |
void *local_scan_lib = NULL; |
59 |
int (*local_scan_version_fn)(void); |
60 |
int vers_maj; |
61 |
int vers_min; |
62 |
|
63 |
local_scan_lib = dlopen(local_scan_path, RTLD_NOW); |
64 |
if (!local_scan_lib) |
65 |
{ |
66 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - " |
67 |
"message temporarily rejected"); |
68 |
return FALSE; |
69 |
} |
70 |
|
71 |
local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major"); |
72 |
if (!local_scan_version_fn) |
73 |
{ |
74 |
dlclose(local_scan_lib); |
75 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain " |
76 |
"local_scan_version_major() function - message temporarily rejected"); |
77 |
return FALSE; |
78 |
} |
79 |
|
80 |
/* The major number is increased when the ABI is changed in a non |
81 |
backward compatible way. */ |
82 |
vers_maj = local_scan_version_fn(); |
83 |
|
84 |
local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor"); |
85 |
if (!local_scan_version_fn) |
86 |
{ |
87 |
dlclose(local_scan_lib); |
88 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain " |
89 |
"local_scan_version_minor() function - message temporarily rejected"); |
90 |
return FALSE; |
91 |
} |
92 |
|
93 |
/* The minor number is increased each time a new feature is added (in a |
94 |
way that doesn't break backward compatibility) -- Marc */ |
95 |
vers_min = local_scan_version_fn(); |
96 |
|
97 |
|
98 |
if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR) |
99 |
{ |
100 |
dlclose(local_scan_lib); |
101 |
local_scan_lib = NULL; |
102 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major" |
103 |
"version number, you need to recompile your module for this version" |
104 |
"of exim (The module was compiled for version %d.%d and this exim provides" |
105 |
"ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR, |
106 |
LOCAL_SCAN_ABI_VERSION_MINOR); |
107 |
return FALSE; |
108 |
} |
109 |
else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR) |
110 |
{ |
111 |
dlclose(local_scan_lib); |
112 |
local_scan_lib = NULL; |
113 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor" |
114 |
"version number, you need to recompile your module for this version" |
115 |
"of exim (The module was compiled for version %d.%d and this exim provides" |
116 |
"ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR, |
117 |
LOCAL_SCAN_ABI_VERSION_MINOR); |
118 |
return FALSE; |
119 |
} |
120 |
|
121 |
local_scan_fn = dlsym(local_scan_lib, "local_scan"); |
122 |
if (!local_scan_fn) |
123 |
{ |
124 |
dlclose(local_scan_lib); |
125 |
log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain " |
126 |
"local_scan() function - message temporarily rejected"); |
127 |
return FALSE; |
128 |
} |
129 |
|
130 |
return TRUE; |
62 |
} |
131 |
} |
63 |
|
132 |
|
|
|
133 |
#endif /* DLOPEN_LOCAL_SCAN */ |
134 |
|
64 |
/* End of local_scan.c */ |
135 |
/* End of local_scan.c */ |