Logging: Add DT= to defer & fail message lines. Bug 322
[exim.git] / src / src / drtables.c
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
f9ba5e22 5/* Copyright (c) University of Cambridge 1995 - 2018 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9#include "exim.h"
10
e6d225ae 11#include <string.h>
059ec3d9
PH
12
13/* This module contains tables that define the lookup methods and drivers
14that are actually included in the binary. Its contents are controlled by
15various macros in config.h that ultimately come from Local/Makefile. They are
16all described in src/EDITME. */
17
18
e6d225ae
DW
19lookup_info **lookup_list;
20int lookup_list_count = 0;
059ec3d9 21
4c04137d 22/* Table of information about all possible authentication mechanisms. All
059ec3d9
PH
23entries are always present if any mechanism is declared, but the functions are
24set to NULL for those that are not compiled into the binary. */
25
26#ifdef AUTH_CRAM_MD5
27#include "auths/cram_md5.h"
28#endif
29
30#ifdef AUTH_CYRUS_SASL
31#include "auths/cyrus_sasl.h"
32#endif
33
14aa5a05
PH
34#ifdef AUTH_DOVECOT
35#include "auths/dovecot.h"
36#endif
37
b53c265b
JH
38#ifdef AUTH_EXTERNAL
39#include "auths/external.h"
40#endif
41
44bbabb5
PP
42#ifdef AUTH_GSASL
43#include "auths/gsasl_exim.h"
44#endif
45
dde3daac
PP
46#ifdef AUTH_HEIMDAL_GSSAPI
47#include "auths/heimdal_gssapi.h"
48#endif
49
059ec3d9
PH
50#ifdef AUTH_PLAINTEXT
51#include "auths/plaintext.h"
52#endif
53
54#ifdef AUTH_SPA
55#include "auths/spa.h"
56#endif
57
b3ef41c9
JH
58#ifdef AUTH_TLS
59#include "auths/tls.h"
60#endif
61
059ec3d9
PH
62auth_info auths_available[] = {
63
64/* Checking by an expansion condition on plain text */
65
66#ifdef AUTH_CRAM_MD5
67 {
f2ed27cf
JH
68 .driver_name = US"cram_md5", /* lookup name */
69 .options = auth_cram_md5_options,
70 .options_count = &auth_cram_md5_options_count,
71 .options_block = &auth_cram_md5_option_defaults,
72 .options_len = sizeof(auth_cram_md5_options_block),
73 .init = auth_cram_md5_init,
74 .servercode = auth_cram_md5_server,
75 .clientcode = auth_cram_md5_client,
76 .version_report = NULL
059ec3d9
PH
77 },
78#endif
79
80#ifdef AUTH_CYRUS_SASL
81 {
f2ed27cf
JH
82 .driver_name = US"cyrus_sasl",
83 .options = auth_cyrus_sasl_options,
84 .options_count = &auth_cyrus_sasl_options_count,
85 .options_block = &auth_cyrus_sasl_option_defaults,
86 .options_len = sizeof(auth_cyrus_sasl_options_block),
87 .init = auth_cyrus_sasl_init,
88 .servercode = auth_cyrus_sasl_server,
89 .clientcode = NULL,
90 .version_report = auth_cyrus_sasl_version_report
059ec3d9
PH
91 },
92#endif
93
14aa5a05
PH
94#ifdef AUTH_DOVECOT
95 {
f2ed27cf
JH
96 .driver_name = US"dovecot",
97 .options = auth_dovecot_options,
98 .options_count = &auth_dovecot_options_count,
99 .options_block = &auth_dovecot_option_defaults,
100 .options_len = sizeof(auth_dovecot_options_block),
101 .init = auth_dovecot_init,
102 .servercode = auth_dovecot_server,
103 .clientcode = NULL,
104 .version_report = NULL
44bbabb5
PP
105 },
106#endif
107
b53c265b
JH
108#ifdef AUTH_EXTERNAL
109 {
110 .driver_name = US"external",
111 .options = auth_external_options,
112 .options_count = &auth_external_options_count,
113 .options_block = &auth_external_option_defaults,
114 .options_len = sizeof(auth_external_options_block),
115 .init = auth_external_init,
116 .servercode = auth_external_server,
117 .clientcode = auth_external_client,
118 .version_report = NULL
119 },
120#endif
121
44bbabb5
PP
122#ifdef AUTH_GSASL
123 {
f2ed27cf
JH
124 .driver_name = US"gsasl",
125 .options = auth_gsasl_options,
126 .options_count = &auth_gsasl_options_count,
127 .options_block = &auth_gsasl_option_defaults,
128 .options_len = sizeof(auth_gsasl_options_block),
129 .init = auth_gsasl_init,
130 .servercode = auth_gsasl_server,
14a806d6 131 .clientcode = auth_gsasl_client,
f2ed27cf 132 .version_report = auth_gsasl_version_report
14aa5a05
PH
133 },
134#endif
135
dde3daac
PP
136#ifdef AUTH_HEIMDAL_GSSAPI
137 {
f2ed27cf
JH
138 .driver_name = US"heimdal_gssapi",
139 .options = auth_heimdal_gssapi_options,
7be14582 140 .options_count = &auth_heimdal_gssapi_options_count,
f2ed27cf
JH
141 .options_block = &auth_heimdal_gssapi_option_defaults,
142 .options_len = sizeof(auth_heimdal_gssapi_options_block),
143 .init = auth_heimdal_gssapi_init,
144 .servercode = auth_heimdal_gssapi_server,
145 .clientcode = NULL,
146 .version_report = auth_heimdal_gssapi_version_report
dde3daac
PP
147 },
148#endif
149
059ec3d9
PH
150#ifdef AUTH_PLAINTEXT
151 {
f2ed27cf
JH
152 .driver_name = US"plaintext",
153 .options = auth_plaintext_options,
154 .options_count = &auth_plaintext_options_count,
155 .options_block = &auth_plaintext_option_defaults,
156 .options_len = sizeof(auth_plaintext_options_block),
157 .init = auth_plaintext_init,
158 .servercode = auth_plaintext_server,
159 .clientcode = auth_plaintext_client,
160 .version_report = NULL
059ec3d9
PH
161 },
162#endif
163
164#ifdef AUTH_SPA
165 {
f2ed27cf
JH
166 .driver_name = US"spa",
167 .options = auth_spa_options,
168 .options_count = &auth_spa_options_count,
169 .options_block = &auth_spa_option_defaults,
170 .options_len = sizeof(auth_spa_options_block),
171 .init = auth_spa_init,
172 .servercode = auth_spa_server,
173 .clientcode = auth_spa_client,
174 .version_report = NULL
059ec3d9
PH
175 },
176#endif
177
b3ef41c9
JH
178#ifdef AUTH_TLS
179 {
f2ed27cf
JH
180 .driver_name = US"tls",
181 .options = auth_tls_options,
182 .options_count = &auth_tls_options_count,
183 .options_block = &auth_tls_option_defaults,
184 .options_len = sizeof(auth_tls_options_block),
185 .init = auth_tls_init,
186 .servercode = auth_tls_server,
187 .clientcode = NULL,
188 .version_report = NULL
b3ef41c9
JH
189 },
190#endif
191
adf73d37 192 { .driver_name = US"" } /* end marker */
059ec3d9
PH
193};
194
adf73d37
JH
195void
196auth_show_supported(FILE * f)
197{
adf73d37 198fprintf(f, "Authenticators:");
d7978c0f 199for (auth_info * ai = auths_available; ai->driver_name[0]; ai++)
adf73d37
JH
200 fprintf(f, " %s", ai->driver_name);
201fprintf(f, "\n");
202}
203
059ec3d9
PH
204
205/* Tables of information about which routers and transports are included in the
206exim binary. */
207
208/* Pull in the necessary header files */
209
210#include "routers/rf_functions.h"
211
212#ifdef ROUTER_ACCEPT
213#include "routers/accept.h"
214#endif
215
216#ifdef ROUTER_DNSLOOKUP
217#include "routers/dnslookup.h"
218#endif
219
220#ifdef ROUTER_MANUALROUTE
221#include "routers/manualroute.h"
222#endif
223
224#ifdef ROUTER_IPLITERAL
225#include "routers/ipliteral.h"
226#endif
227
228#ifdef ROUTER_IPLOOKUP
229#include "routers/iplookup.h"
230#endif
231
232#ifdef ROUTER_QUERYPROGRAM
233#include "routers/queryprogram.h"
234#endif
235
236#ifdef ROUTER_REDIRECT
237#include "routers/redirect.h"
238#endif
239
240#ifdef TRANSPORT_APPENDFILE
241#include "transports/appendfile.h"
242#endif
243
244#ifdef TRANSPORT_AUTOREPLY
245#include "transports/autoreply.h"
246#endif
247
248#ifdef TRANSPORT_LMTP
249#include "transports/lmtp.h"
250#endif
251
252#ifdef TRANSPORT_PIPE
253#include "transports/pipe.h"
254#endif
255
3369a853
ACK
256#ifdef EXPERIMENTAL_QUEUEFILE
257#include "transports/queuefile.h"
258#endif
259
059ec3d9
PH
260#ifdef TRANSPORT_SMTP
261#include "transports/smtp.h"
262#endif
263
264
265/* Now set up the structures, terminated by an entry with a null name. */
266
267router_info routers_available[] = {
268#ifdef ROUTER_ACCEPT
269 {
f2ed27cf
JH
270 .driver_name = US"accept",
271 .options = accept_router_options,
272 .options_count = &accept_router_options_count,
273 .options_block = &accept_router_option_defaults,
274 .options_len = sizeof(accept_router_options_block),
275 .init = accept_router_init,
276 .code = accept_router_entry,
277 .tidyup = NULL, /* no tidyup entry */
278 .ri_flags = ri_yestransport
059ec3d9
PH
279 },
280#endif
281#ifdef ROUTER_DNSLOOKUP
282 {
f2ed27cf
JH
283 .driver_name = US"dnslookup",
284 .options = dnslookup_router_options,
285 .options_count = &dnslookup_router_options_count,
286 .options_block = &dnslookup_router_option_defaults,
287 .options_len = sizeof(dnslookup_router_options_block),
288 .init = dnslookup_router_init,
289 .code = dnslookup_router_entry,
290 .tidyup = NULL, /* no tidyup entry */
291 .ri_flags = ri_yestransport
059ec3d9
PH
292 },
293#endif
294#ifdef ROUTER_IPLITERAL
295 {
f2ed27cf
JH
296 .driver_name = US"ipliteral",
297 .options = ipliteral_router_options,
298 .options_count = &ipliteral_router_options_count,
299 .options_block = &ipliteral_router_option_defaults,
300 .options_len = sizeof(ipliteral_router_options_block),
301 .init = ipliteral_router_init,
302 .code = ipliteral_router_entry,
303 .tidyup = NULL, /* no tidyup entry */
304 .ri_flags = ri_yestransport
059ec3d9
PH
305 },
306#endif
307#ifdef ROUTER_IPLOOKUP
308 {
f2ed27cf
JH
309 .driver_name = US"iplookup",
310 .options = iplookup_router_options,
311 .options_count = &iplookup_router_options_count,
312 .options_block = &iplookup_router_option_defaults,
313 .options_len = sizeof(iplookup_router_options_block),
314 .init = iplookup_router_init,
315 .code = iplookup_router_entry,
316 .tidyup = NULL, /* no tidyup entry */
317 .ri_flags = ri_notransport
059ec3d9
PH
318 },
319#endif
320#ifdef ROUTER_MANUALROUTE
321 {
f2ed27cf
JH
322 .driver_name = US"manualroute",
323 .options = manualroute_router_options,
324 .options_count = &manualroute_router_options_count,
325 .options_block = &manualroute_router_option_defaults,
326 .options_len = sizeof(manualroute_router_options_block),
327 .init = manualroute_router_init,
328 .code = manualroute_router_entry,
329 .tidyup = NULL, /* no tidyup entry */
330 .ri_flags = 0
059ec3d9
PH
331 },
332#endif
333#ifdef ROUTER_QUERYPROGRAM
334 {
f2ed27cf
JH
335 .driver_name = US"queryprogram",
336 .options = queryprogram_router_options,
337 .options_count = &queryprogram_router_options_count,
338 .options_block = &queryprogram_router_option_defaults,
339 .options_len = sizeof(queryprogram_router_options_block),
340 .init = queryprogram_router_init,
341 .code = queryprogram_router_entry,
342 .tidyup = NULL, /* no tidyup entry */
343 .ri_flags = 0
059ec3d9
PH
344 },
345#endif
346#ifdef ROUTER_REDIRECT
347 {
f2ed27cf
JH
348 .driver_name = US"redirect",
349 .options = redirect_router_options,
350 .options_count = &redirect_router_options_count,
351 .options_block = &redirect_router_option_defaults,
352 .options_len = sizeof(redirect_router_options_block),
353 .init = redirect_router_init,
354 .code = redirect_router_entry,
355 .tidyup = NULL, /* no tidyup entry */
356 .ri_flags = ri_notransport
059ec3d9
PH
357 },
358#endif
adf73d37 359 { US"" }
059ec3d9
PH
360};
361
362
adf73d37
JH
363void
364route_show_supported(FILE * f)
365{
adf73d37 366fprintf(f, "Routers:");
d7978c0f 367for (router_info * rr = routers_available; rr->driver_name[0]; rr++)
adf73d37
JH
368 fprintf(f, " %s", rr->driver_name);
369fprintf(f, "\n");
370}
371
372
373
059ec3d9
PH
374
375transport_info transports_available[] = {
376#ifdef TRANSPORT_APPENDFILE
377 {
f2ed27cf
JH
378 .driver_name = US"appendfile",
379 .options = appendfile_transport_options,
380 .options_count = &appendfile_transport_options_count,
381 .options_block = &appendfile_transport_option_defaults, /* private options defaults */
382 .options_len = sizeof(appendfile_transport_options_block),
383 .init = appendfile_transport_init,
384 .code = appendfile_transport_entry,
385 .tidyup = NULL,
386 .closedown = NULL,
387 .local = TRUE
059ec3d9
PH
388 },
389#endif
390#ifdef TRANSPORT_AUTOREPLY
391 {
f2ed27cf
JH
392 .driver_name = US"autoreply",
393 .options = autoreply_transport_options,
394 .options_count = &autoreply_transport_options_count,
395 .options_block = &autoreply_transport_option_defaults,
396 .options_len = sizeof(autoreply_transport_options_block),
397 .init = autoreply_transport_init,
398 .code = autoreply_transport_entry,
399 .tidyup = NULL,
400 .closedown = NULL,
401 .local = TRUE
059ec3d9
PH
402 },
403#endif
404#ifdef TRANSPORT_LMTP
405 {
f2ed27cf
JH
406 .driver_name = US"lmtp",
407 .options = lmtp_transport_options,
408 .options_count = &lmtp_transport_options_count,
409 .options_block = &lmtp_transport_option_defaults,
410 .options_len = sizeof(lmtp_transport_options_block),
411 .init = lmtp_transport_init,
412 .code = lmtp_transport_entry,
413 .tidyup = NULL,
414 .closedown = NULL,
415 .local = TRUE
059ec3d9
PH
416 },
417#endif
418#ifdef TRANSPORT_PIPE
419 {
f2ed27cf
JH
420 .driver_name = US"pipe",
421 .options = pipe_transport_options,
422 .options_count = &pipe_transport_options_count,
423 .options_block = &pipe_transport_option_defaults,
424 .options_len = sizeof(pipe_transport_options_block),
425 .init = pipe_transport_init,
426 .code = pipe_transport_entry,
427 .tidyup = NULL,
428 .closedown = NULL,
429 .local = TRUE
059ec3d9
PH
430 },
431#endif
3369a853
ACK
432#ifdef EXPERIMENTAL_QUEUEFILE
433 {
f2ed27cf
JH
434 .driver_name = US"queuefile",
435 .options = queuefile_transport_options,
436 .options_count = &queuefile_transport_options_count,
437 .options_block = &queuefile_transport_option_defaults,
438 .options_len = sizeof(queuefile_transport_options_block),
439 .init = queuefile_transport_init,
440 .code = queuefile_transport_entry,
441 .tidyup = NULL,
442 .closedown = NULL,
443 .local = TRUE
3369a853
ACK
444 },
445#endif
059ec3d9
PH
446#ifdef TRANSPORT_SMTP
447 {
f2ed27cf
JH
448 .driver_name = US"smtp",
449 .options = smtp_transport_options,
450 .options_count = &smtp_transport_options_count,
451 .options_block = &smtp_transport_option_defaults,
452 .options_len = sizeof(smtp_transport_options_block),
453 .init = smtp_transport_init,
454 .code = smtp_transport_entry,
455 .tidyup = NULL,
456 .closedown = smtp_transport_closedown,
457 .local = FALSE
059ec3d9
PH
458 },
459#endif
adf73d37 460 { US"" }
059ec3d9
PH
461};
462
adf73d37
JH
463void
464transport_show_supported(FILE * f)
465{
466fprintf(f, "Transports:");
467#ifdef TRANSPORT_APPENDFILE
468 fprintf(f, " appendfile");
469 #ifdef SUPPORT_MAILDIR
470 fprintf(f, "/maildir"); /* damn these subclasses */
471 #endif
472 #ifdef SUPPORT_MAILSTORE
473 fprintf(f, "/mailstore");
474 #endif
475 #ifdef SUPPORT_MBX
476 fprintf(f, "/mbx");
477 #endif
478#endif
479#ifdef TRANSPORT_AUTOREPLY
480 fprintf(f, " autoreply");
481#endif
482#ifdef TRANSPORT_LMTP
483 fprintf(f, " lmtp");
484#endif
485#ifdef TRANSPORT_PIPE
486 fprintf(f, " pipe");
487#endif
488#ifdef EXPERIMENTAL_QUEUEFILE
489 fprintf(f, " queuefile");
490#endif
491#ifdef TRANSPORT_SMTP
492 fprintf(f, " smtp");
493#endif
494fprintf(f, "\n");
495}
496
d185889f
JH
497
498#ifndef MACRO_PREDEF
499
e6d225ae
DW
500struct lookupmodulestr
501{
502 void *dl;
503 struct lookup_module_info *info;
504 struct lookupmodulestr *next;
505};
506
507static struct lookupmodulestr *lookupmodules = NULL;
508
96f5fe4c
JH
509static void
510addlookupmodule(void *dl, struct lookup_module_info *info)
e6d225ae 511{
f3ebb786 512struct lookupmodulestr *p = store_get(sizeof(struct lookupmodulestr), FALSE);
96f5fe4c
JH
513
514p->dl = dl;
515p->info = info;
516p->next = lookupmodules;
517lookupmodules = p;
518lookup_list_count += info->lookupcount;
e6d225ae
DW
519}
520
521/* only valid after lookup_list and lookup_list_count are assigned */
96f5fe4c
JH
522static void
523add_lookup_to_list(lookup_info *info)
e6d225ae 524{
96f5fe4c
JH
525/* need to add the lookup to lookup_list, sorted */
526int pos = 0;
527
528/* strategy is to go through the list until we find
529either an empty spot or a name that is higher.
530this can't fail because we have enough space. */
531
532while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
533 pos++;
534
535if (lookup_list[pos])
536 {
537 /* need to insert it, so move all the other items up
538 (last slot is still empty, of course) */
539
540 memmove(&lookup_list[pos+1],
541 &lookup_list[pos],
542 sizeof(lookup_info *) * (lookup_list_count-pos-1));
e6d225ae 543 }
96f5fe4c 544lookup_list[pos] = info;
e6d225ae
DW
545}
546
4d805ee9
PP
547
548/* These need to be at file level for old versions of gcc (2.95.2 reported),
549 * which give parse errors on an extern in function scope. Each entry needs
550 * to also be invoked in init_lookup_list() below */
551
78f72498
JH
552#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
553extern lookup_module_info cdb_lookup_module_info;
4d805ee9 554#endif
78f72498
JH
555#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
556extern lookup_module_info dbmdb_lookup_module_info;
4d805ee9 557#endif
78f72498
JH
558#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
559extern lookup_module_info dnsdb_lookup_module_info;
4d805ee9 560#endif
78f72498
JH
561#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
562extern lookup_module_info dsearch_lookup_module_info;
4d805ee9 563#endif
78f72498
JH
564#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
565extern lookup_module_info ibase_lookup_module_info;
4d805ee9 566#endif
ffc92d69
JH
567#if defined(LOOKUP_JSON)
568extern lookup_module_info json_lookup_module_info;
569#endif
78f72498
JH
570#if defined(LOOKUP_LDAP)
571extern lookup_module_info ldap_lookup_module_info;
de78e2d5 572#endif
78f72498
JH
573#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
574extern lookup_module_info lsearch_lookup_module_info;
4d805ee9 575#endif
78f72498
JH
576#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
577extern lookup_module_info mysql_lookup_module_info;
4d805ee9
PP
578#endif
579#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
580extern lookup_module_info nis_lookup_module_info;
581#endif
78f72498
JH
582#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
583extern lookup_module_info nisplus_lookup_module_info;
4d805ee9 584#endif
78f72498
JH
585#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
586extern lookup_module_info oracle_lookup_module_info;
4d805ee9 587#endif
78f72498
JH
588#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
589extern lookup_module_info passwd_lookup_module_info;
4d805ee9 590#endif
78f72498
JH
591#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
592extern lookup_module_info pgsql_lookup_module_info;
4d805ee9 593#endif
78f72498
JH
594#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
595extern lookup_module_info redis_lookup_module_info;
4d805ee9 596#endif
5bde3efa
ACK
597#if defined(EXPERIMENTAL_LMDB)
598extern lookup_module_info lmdb_lookup_module_info;
599#endif
7952eef9 600#if defined(SUPPORT_SPF)
78f72498 601extern lookup_module_info spf_lookup_module_info;
4d805ee9 602#endif
78f72498
JH
603#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
604extern lookup_module_info sqlite_lookup_module_info;
4d805ee9 605#endif
78f72498
JH
606#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
607extern lookup_module_info testdb_lookup_module_info;
608#endif
609#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
610extern lookup_module_info whoson_lookup_module_info;
4d805ee9
PP
611#endif
612
96f5fe4c
JH
613
614void
615init_lookup_list(void)
e6d225ae 616{
fb2bba55 617#ifdef LOOKUP_MODULE_DIR
e6d225ae
DW
618 DIR *dd;
619 struct dirent *ent;
e6d225ae
DW
620 int countmodules = 0;
621 int moduleerrors = 0;
fb2bba55 622#endif
cab0c277 623 static BOOL lookup_list_init_done = FALSE;
f3ebb786 624 rmark reset_point;
e6d225ae 625
6545de78
PP
626 if (lookup_list_init_done)
627 return;
f3ebb786 628 reset_point = store_mark();
cab0c277 629 lookup_list_init_done = TRUE;
6545de78 630
e6d225ae 631#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
e6d225ae
DW
632 addlookupmodule(NULL, &cdb_lookup_module_info);
633#endif
634
635#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
e6d225ae
DW
636 addlookupmodule(NULL, &dbmdb_lookup_module_info);
637#endif
638
639#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
e6d225ae
DW
640 addlookupmodule(NULL, &dnsdb_lookup_module_info);
641#endif
642
643#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
e6d225ae
DW
644 addlookupmodule(NULL, &dsearch_lookup_module_info);
645#endif
646
647#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
e6d225ae
DW
648 addlookupmodule(NULL, &ibase_lookup_module_info);
649#endif
650
651#ifdef LOOKUP_LDAP
e6d225ae
DW
652 addlookupmodule(NULL, &ldap_lookup_module_info);
653#endif
654
ffc92d69
JH
655#ifdef LOOKUP_JSON
656 addlookupmodule(NULL, &json_lookup_module_info);
657#endif
658
e6d225ae 659#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
e6d225ae
DW
660 addlookupmodule(NULL, &lsearch_lookup_module_info);
661#endif
662
663#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
e6d225ae
DW
664 addlookupmodule(NULL, &mysql_lookup_module_info);
665#endif
666
667#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
e6d225ae
DW
668 addlookupmodule(NULL, &nis_lookup_module_info);
669#endif
670
671#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
e6d225ae
DW
672 addlookupmodule(NULL, &nisplus_lookup_module_info);
673#endif
674
675#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
e6d225ae
DW
676 addlookupmodule(NULL, &oracle_lookup_module_info);
677#endif
678
679#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
e6d225ae
DW
680 addlookupmodule(NULL, &passwd_lookup_module_info);
681#endif
682
683#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
e6d225ae
DW
684 addlookupmodule(NULL, &pgsql_lookup_module_info);
685#endif
686
de78e2d5 687#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
9bdd29ad
TL
688 addlookupmodule(NULL, &redis_lookup_module_info);
689#endif
690
5bde3efa
ACK
691#ifdef EXPERIMENTAL_LMDB
692 addlookupmodule(NULL, &lmdb_lookup_module_info);
693#endif
694
7952eef9 695#ifdef SUPPORT_SPF
e6d225ae
DW
696 addlookupmodule(NULL, &spf_lookup_module_info);
697#endif
698
699#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
e6d225ae
DW
700 addlookupmodule(NULL, &sqlite_lookup_module_info);
701#endif
702
703#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
e6d225ae
DW
704 addlookupmodule(NULL, &testdb_lookup_module_info);
705#endif
706
707#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
e6d225ae
DW
708 addlookupmodule(NULL, &whoson_lookup_module_info);
709#endif
710
711#ifdef LOOKUP_MODULE_DIR
712 dd = opendir(LOOKUP_MODULE_DIR);
713 if (dd == NULL) {
1594a79a 714 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
715 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
716 }
717 else {
f322340b
JH
718 const pcre *regex_islookupmod = regex_must_compile(
719 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
720
1594a79a 721 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
722 while ((ent = readdir(dd)) != NULL) {
723 char *name = ent->d_name;
724 int len = (int)strlen(name);
725 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
726 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
727 void *dl;
728 struct lookup_module_info *info;
1ba28e2b 729 const char *errormsg;
e6d225ae
DW
730
731 /* SRH: am I being paranoid here or what? */
732 if (pathnamelen > big_buffer_size) {
733 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
734 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
735 continue;
736 }
737
738 /* SRH: snprintf here? */
739 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
740
741 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
742 if (dl == NULL) {
743 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
744 moduleerrors++;
745 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
746 continue;
747 }
748
56e0c4ce
PP
749 /* FreeBSD nsdispatch() can trigger dlerror() errors about
750 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
751 * state before calling dlsym(), so that any error afterwards only
752 * comes from dlsym().
753 */
754 errormsg = dlerror();
755
e6d225ae
DW
756 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
757 if ((errormsg = dlerror()) != NULL) {
758 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
759 dlclose(dl);
760 moduleerrors++;
761 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
762 continue;
763 }
764 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
765 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
766 dlclose(dl);
767 moduleerrors++;
768 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
769 continue;
770 }
771
772 addlookupmodule(dl, info);
1594a79a 773 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
e6d225ae
DW
774 countmodules++;
775 }
776 }
f322340b 777 store_free((void*)regex_islookupmod);
e6d225ae
DW
778 closedir(dd);
779 }
780
1594a79a 781 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
e6d225ae
DW
782#endif
783
1594a79a 784 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
e6d225ae
DW
785
786 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
787 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
788
789 /* now add all lookups to the real list */
f3ebb786 790 for (struct lookupmodulestr * p = lookupmodules; p; p = p->next)
d7978c0f 791 for (int j = 0; j < p->info->lookupcount; j++)
e6d225ae 792 add_lookup_to_list(p->info->lookups[j]);
f3ebb786 793 store_reset(reset_point);
e6d225ae
DW
794 /* just to be sure */
795 lookupmodules = NULL;
796}
797
d185889f 798#endif /*!MACRO_PREDEF*/
059ec3d9 799/* End of drtables.c */