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