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