Move notifier socket to general availability
[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
549 memmove(&lookup_list[pos+1],
550 &lookup_list[pos],
551 sizeof(lookup_info *) * (lookup_list_count-pos-1));
e6d225ae 552 }
96f5fe4c 553lookup_list[pos] = info;
e6d225ae
DW
554}
555
4d805ee9
PP
556
557/* These need to be at file level for old versions of gcc (2.95.2 reported),
558 * which give parse errors on an extern in function scope. Each entry needs
559 * to also be invoked in init_lookup_list() below */
560
78f72498
JH
561#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
562extern lookup_module_info cdb_lookup_module_info;
4d805ee9 563#endif
78f72498
JH
564#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
565extern lookup_module_info dbmdb_lookup_module_info;
4d805ee9 566#endif
78f72498
JH
567#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
568extern lookup_module_info dnsdb_lookup_module_info;
4d805ee9 569#endif
78f72498
JH
570#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
571extern lookup_module_info dsearch_lookup_module_info;
4d805ee9 572#endif
78f72498
JH
573#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
574extern lookup_module_info ibase_lookup_module_info;
4d805ee9 575#endif
ffc92d69
JH
576#if defined(LOOKUP_JSON)
577extern lookup_module_info json_lookup_module_info;
578#endif
78f72498
JH
579#if defined(LOOKUP_LDAP)
580extern lookup_module_info ldap_lookup_module_info;
de78e2d5 581#endif
78f72498
JH
582#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
583extern lookup_module_info lsearch_lookup_module_info;
4d805ee9 584#endif
78f72498
JH
585#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
586extern lookup_module_info mysql_lookup_module_info;
4d805ee9
PP
587#endif
588#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
589extern lookup_module_info nis_lookup_module_info;
590#endif
78f72498
JH
591#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
592extern lookup_module_info nisplus_lookup_module_info;
4d805ee9 593#endif
78f72498
JH
594#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
595extern lookup_module_info oracle_lookup_module_info;
4d805ee9 596#endif
78f72498
JH
597#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
598extern lookup_module_info passwd_lookup_module_info;
4d805ee9 599#endif
78f72498
JH
600#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
601extern lookup_module_info pgsql_lookup_module_info;
4d805ee9 602#endif
78f72498
JH
603#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
604extern lookup_module_info redis_lookup_module_info;
4d805ee9 605#endif
5bde3efa
ACK
606#if defined(EXPERIMENTAL_LMDB)
607extern lookup_module_info lmdb_lookup_module_info;
608#endif
7952eef9 609#if defined(SUPPORT_SPF)
78f72498 610extern lookup_module_info spf_lookup_module_info;
4d805ee9 611#endif
78f72498
JH
612#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
613extern lookup_module_info sqlite_lookup_module_info;
4d805ee9 614#endif
78f72498
JH
615#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
616extern lookup_module_info testdb_lookup_module_info;
617#endif
618#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
619extern lookup_module_info whoson_lookup_module_info;
4d805ee9
PP
620#endif
621
96f5fe4c
JH
622
623void
624init_lookup_list(void)
e6d225ae 625{
fb2bba55 626#ifdef LOOKUP_MODULE_DIR
2fa25efc
JH
627DIR *dd;
628struct dirent *ent;
629int countmodules = 0;
630int moduleerrors = 0;
fb2bba55 631#endif
2fa25efc
JH
632static BOOL lookup_list_init_done = FALSE;
633rmark reset_point;
e6d225ae 634
2fa25efc
JH
635if (lookup_list_init_done)
636 return;
637reset_point = store_mark();
638lookup_list_init_done = TRUE;
6545de78 639
e6d225ae 640#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
2fa25efc 641addlookupmodule(NULL, &cdb_lookup_module_info);
e6d225ae
DW
642#endif
643
644#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
2fa25efc 645addlookupmodule(NULL, &dbmdb_lookup_module_info);
e6d225ae
DW
646#endif
647
648#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
2fa25efc 649addlookupmodule(NULL, &dnsdb_lookup_module_info);
e6d225ae
DW
650#endif
651
652#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
2fa25efc 653addlookupmodule(NULL, &dsearch_lookup_module_info);
e6d225ae
DW
654#endif
655
656#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
2fa25efc 657addlookupmodule(NULL, &ibase_lookup_module_info);
e6d225ae
DW
658#endif
659
660#ifdef LOOKUP_LDAP
2fa25efc 661addlookupmodule(NULL, &ldap_lookup_module_info);
e6d225ae
DW
662#endif
663
ffc92d69 664#ifdef LOOKUP_JSON
2fa25efc 665addlookupmodule(NULL, &json_lookup_module_info);
ffc92d69
JH
666#endif
667
e6d225ae 668#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
2fa25efc 669addlookupmodule(NULL, &lsearch_lookup_module_info);
e6d225ae
DW
670#endif
671
672#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
2fa25efc 673addlookupmodule(NULL, &mysql_lookup_module_info);
e6d225ae
DW
674#endif
675
676#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
2fa25efc 677addlookupmodule(NULL, &nis_lookup_module_info);
e6d225ae
DW
678#endif
679
680#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
2fa25efc 681addlookupmodule(NULL, &nisplus_lookup_module_info);
e6d225ae
DW
682#endif
683
684#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
2fa25efc 685addlookupmodule(NULL, &oracle_lookup_module_info);
e6d225ae
DW
686#endif
687
688#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
2fa25efc 689addlookupmodule(NULL, &passwd_lookup_module_info);
e6d225ae
DW
690#endif
691
692#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
2fa25efc 693addlookupmodule(NULL, &pgsql_lookup_module_info);
e6d225ae
DW
694#endif
695
de78e2d5 696#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
2fa25efc 697addlookupmodule(NULL, &redis_lookup_module_info);
9bdd29ad
TL
698#endif
699
5bde3efa 700#ifdef EXPERIMENTAL_LMDB
2fa25efc 701addlookupmodule(NULL, &lmdb_lookup_module_info);
5bde3efa
ACK
702#endif
703
7952eef9 704#ifdef SUPPORT_SPF
2fa25efc 705addlookupmodule(NULL, &spf_lookup_module_info);
e6d225ae
DW
706#endif
707
708#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
2fa25efc 709addlookupmodule(NULL, &sqlite_lookup_module_info);
e6d225ae
DW
710#endif
711
712#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
2fa25efc 713addlookupmodule(NULL, &testdb_lookup_module_info);
e6d225ae
DW
714#endif
715
716#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
2fa25efc 717addlookupmodule(NULL, &whoson_lookup_module_info);
e6d225ae
DW
718#endif
719
720#ifdef LOOKUP_MODULE_DIR
2fa25efc
JH
721if (!(dd = opendir(LOOKUP_MODULE_DIR)))
722 {
723 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
724 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
e6d225ae 725 }
2fa25efc
JH
726else
727 {
728 const pcre *regex_islookupmod = regex_must_compile(
729 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
730
731 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
732 while ((ent = readdir(dd)))
733 {
734 char *name = ent->d_name;
735 int len = (int)strlen(name);
736 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0)
737 {
738 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
739 void *dl;
740 struct lookup_module_info *info;
741 const char *errormsg;
742
743 /* SRH: am I being paranoid here or what? */
744 if (pathnamelen > big_buffer_size)
745 {
746 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
747 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
748 continue;
749 }
750
751 /* SRH: snprintf here? */
752 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
753
754 if (!(dl = dlopen(CS big_buffer, RTLD_NOW)))
755 {
3fc07bd5
AM
756 errormsg = dlerror();
757 fprintf(stderr, "Error loading %s: %s\n", name, errormsg);
758 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, errormsg);
2fa25efc 759 moduleerrors++;
2fa25efc
JH
760 continue;
761 }
762
763 /* FreeBSD nsdispatch() can trigger dlerror() errors about
764 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
765 * state before calling dlsym(), so that any error afterwards only
766 * comes from dlsym().
767 */
768 errormsg = dlerror();
769
770 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
771 if ((errormsg = dlerror()))
772 {
773 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
3fc07bd5 774 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
2fa25efc
JH
775 dlclose(dl);
776 moduleerrors++;
2fa25efc
JH
777 continue;
778 }
779 if (info->magic != LOOKUP_MODULE_INFO_MAGIC)
780 {
781 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
3fc07bd5 782 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
2fa25efc
JH
783 dlclose(dl);
784 moduleerrors++;
2fa25efc
JH
785 continue;
786 }
787
788 addlookupmodule(dl, info);
789 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
790 countmodules++;
e6d225ae
DW
791 }
792 }
2fa25efc
JH
793 store_free((void*)regex_islookupmod);
794 closedir(dd);
e6d225ae
DW
795 }
796
2fa25efc 797DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
e6d225ae
DW
798#endif
799
2fa25efc 800DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
e6d225ae 801
2fa25efc
JH
802lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
803memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
e6d225ae 804
2fa25efc
JH
805/* now add all lookups to the real list */
806for (struct lookupmodulestr * p = lookupmodules; p; p = p->next)
807 for (int j = 0; j < p->info->lookupcount; j++)
808 add_lookup_to_list(p->info->lookups[j]);
809store_reset(reset_point);
810/* just to be sure */
811lookupmodules = NULL;
e6d225ae
DW
812}
813
d185889f 814#endif /*!MACRO_PREDEF*/
059ec3d9 815/* End of drtables.c */