Import Debian changes 4.92-8+deb10u3
[hcoop/debian/exim4.git] / src / drtables.c
CommitLineData
420a0d19
CE
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
2ea97746 5/* Copyright (c) University of Cambridge 1995 - 2018 */
420a0d19
CE
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9#include "exim.h"
10
11#include <string.h>
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
19lookup_info **lookup_list;
20int lookup_list_count = 0;
21
2ea97746 22/* Table of information about all possible authentication mechanisms. All
420a0d19
CE
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
34#ifdef AUTH_DOVECOT
35#include "auths/dovecot.h"
36#endif
37
38#ifdef AUTH_GSASL
39#include "auths/gsasl_exim.h"
40#endif
41
42#ifdef AUTH_HEIMDAL_GSSAPI
43#include "auths/heimdal_gssapi.h"
44#endif
45
46#ifdef AUTH_PLAINTEXT
47#include "auths/plaintext.h"
48#endif
49
50#ifdef AUTH_SPA
51#include "auths/spa.h"
52#endif
53
2ea97746
CE
54#ifdef AUTH_TLS
55#include "auths/tls.h"
56#endif
57
420a0d19
CE
58auth_info auths_available[] = {
59
60/* Checking by an expansion condition on plain text */
61
62#ifdef AUTH_CRAM_MD5
63 {
2ea97746
CE
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
420a0d19
CE
73 },
74#endif
75
76#ifdef AUTH_CYRUS_SASL
77 {
2ea97746
CE
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
420a0d19
CE
87 },
88#endif
89
90#ifdef AUTH_DOVECOT
91 {
2ea97746
CE
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
420a0d19
CE
101 },
102#endif
103
104#ifdef AUTH_GSASL
105 {
2ea97746
CE
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
420a0d19
CE
115 },
116#endif
117
118#ifdef AUTH_HEIMDAL_GSSAPI
119 {
2ea97746
CE
120 .driver_name = US"heimdal_gssapi",
121 .options = auth_heimdal_gssapi_options,
122 .options_count = &auth_heimdal_gssapi_options_count,
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
420a0d19
CE
129 },
130#endif
131
132#ifdef AUTH_PLAINTEXT
133 {
2ea97746
CE
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
420a0d19
CE
143 },
144#endif
145
146#ifdef AUTH_SPA
147 {
2ea97746
CE
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
157 },
158#endif
159
160#ifdef AUTH_TLS
161 {
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
420a0d19
CE
171 },
172#endif
173
2ea97746 174 { .driver_name = US"" } /* end marker */
420a0d19
CE
175};
176
2ea97746
CE
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
420a0d19
CE
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
2ea97746
CE
239#ifdef EXPERIMENTAL_QUEUEFILE
240#include "transports/queuefile.h"
241#endif
242
420a0d19
CE
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 {
2ea97746
CE
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
420a0d19
CE
262 },
263#endif
264#ifdef ROUTER_DNSLOOKUP
265 {
2ea97746
CE
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
420a0d19
CE
275 },
276#endif
277#ifdef ROUTER_IPLITERAL
278 {
2ea97746
CE
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
420a0d19
CE
288 },
289#endif
290#ifdef ROUTER_IPLOOKUP
291 {
2ea97746
CE
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
420a0d19
CE
301 },
302#endif
303#ifdef ROUTER_MANUALROUTE
304 {
2ea97746
CE
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
420a0d19
CE
314 },
315#endif
316#ifdef ROUTER_QUERYPROGRAM
317 {
2ea97746
CE
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
420a0d19
CE
327 },
328#endif
329#ifdef ROUTER_REDIRECT
330 {
2ea97746
CE
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
420a0d19
CE
340 },
341#endif
2ea97746 342 { US"" }
420a0d19
CE
343};
344
345
2ea97746
CE
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
420a0d19
CE
358
359transport_info transports_available[] = {
360#ifdef TRANSPORT_APPENDFILE
361 {
2ea97746
CE
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
420a0d19
CE
372 },
373#endif
374#ifdef TRANSPORT_AUTOREPLY
375 {
2ea97746
CE
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
420a0d19
CE
386 },
387#endif
388#ifdef TRANSPORT_LMTP
389 {
2ea97746
CE
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
420a0d19
CE
400 },
401#endif
402#ifdef TRANSPORT_PIPE
403 {
2ea97746
CE
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
414 },
415#endif
416#ifdef EXPERIMENTAL_QUEUEFILE
417 {
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
420a0d19
CE
428 },
429#endif
430#ifdef TRANSPORT_SMTP
431 {
2ea97746
CE
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
420a0d19
CE
442 },
443#endif
2ea97746 444 { US"" }
420a0d19
CE
445};
446
2ea97746
CE
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
481
482#ifndef MACRO_PREDEF
483
420a0d19
CE
484struct lookupmodulestr
485{
486 void *dl;
487 struct lookup_module_info *info;
488 struct lookupmodulestr *next;
489};
490
491static struct lookupmodulestr *lookupmodules = NULL;
492
2ea97746
CE
493static void
494addlookupmodule(void *dl, struct lookup_module_info *info)
420a0d19 495{
2ea97746
CE
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;
420a0d19
CE
503}
504
505/* only valid after lookup_list and lookup_list_count are assigned */
2ea97746
CE
506static void
507add_lookup_to_list(lookup_info *info)
420a0d19 508{
2ea97746
CE
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));
420a0d19 527 }
2ea97746 528lookup_list[pos] = info;
420a0d19
CE
529}
530
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
2ea97746
CE
536#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
537extern lookup_module_info cdb_lookup_module_info;
420a0d19 538#endif
2ea97746
CE
539#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
540extern lookup_module_info dbmdb_lookup_module_info;
420a0d19 541#endif
2ea97746
CE
542#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
543extern lookup_module_info dnsdb_lookup_module_info;
420a0d19 544#endif
2ea97746
CE
545#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
546extern lookup_module_info dsearch_lookup_module_info;
420a0d19 547#endif
2ea97746
CE
548#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
549extern lookup_module_info ibase_lookup_module_info;
420a0d19 550#endif
2ea97746
CE
551#if defined(LOOKUP_LDAP)
552extern lookup_module_info ldap_lookup_module_info;
420a0d19 553#endif
2ea97746
CE
554#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
555extern lookup_module_info lsearch_lookup_module_info;
420a0d19 556#endif
2ea97746
CE
557#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
558extern lookup_module_info mysql_lookup_module_info;
559#endif
560#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
561extern lookup_module_info nis_lookup_module_info;
420a0d19
CE
562#endif
563#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
564extern lookup_module_info nisplus_lookup_module_info;
565#endif
2ea97746
CE
566#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
567extern lookup_module_info oracle_lookup_module_info;
420a0d19 568#endif
2ea97746
CE
569#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
570extern lookup_module_info passwd_lookup_module_info;
420a0d19 571#endif
2ea97746
CE
572#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
573extern lookup_module_info pgsql_lookup_module_info;
420a0d19 574#endif
2ea97746
CE
575#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
576extern lookup_module_info redis_lookup_module_info;
420a0d19 577#endif
2ea97746
CE
578#if defined(EXPERIMENTAL_LMDB)
579extern lookup_module_info lmdb_lookup_module_info;
420a0d19 580#endif
2ea97746
CE
581#if defined(SUPPORT_SPF)
582extern lookup_module_info spf_lookup_module_info;
420a0d19 583#endif
2ea97746
CE
584#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
585extern lookup_module_info sqlite_lookup_module_info;
420a0d19 586#endif
2ea97746
CE
587#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
588extern lookup_module_info testdb_lookup_module_info;
420a0d19 589#endif
2ea97746
CE
590#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
591extern lookup_module_info whoson_lookup_module_info;
420a0d19
CE
592#endif
593
2ea97746
CE
594
595void
596init_lookup_list(void)
420a0d19
CE
597{
598#ifdef LOOKUP_MODULE_DIR
599 DIR *dd;
600 struct dirent *ent;
601 int countmodules = 0;
602 int moduleerrors = 0;
603#endif
604 struct lookupmodulestr *p;
2ea97746
CE
605 static BOOL lookup_list_init_done = FALSE;
606
420a0d19
CE
607
608 if (lookup_list_init_done)
609 return;
2ea97746 610 lookup_list_init_done = TRUE;
420a0d19
CE
611
612#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
613 addlookupmodule(NULL, &cdb_lookup_module_info);
614#endif
615
616#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
617 addlookupmodule(NULL, &dbmdb_lookup_module_info);
618#endif
619
620#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
621 addlookupmodule(NULL, &dnsdb_lookup_module_info);
622#endif
623
624#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
625 addlookupmodule(NULL, &dsearch_lookup_module_info);
626#endif
627
628#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
629 addlookupmodule(NULL, &ibase_lookup_module_info);
630#endif
631
632#ifdef LOOKUP_LDAP
633 addlookupmodule(NULL, &ldap_lookup_module_info);
634#endif
635
636#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
637 addlookupmodule(NULL, &lsearch_lookup_module_info);
638#endif
639
640#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
641 addlookupmodule(NULL, &mysql_lookup_module_info);
642#endif
643
644#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
645 addlookupmodule(NULL, &nis_lookup_module_info);
646#endif
647
648#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
649 addlookupmodule(NULL, &nisplus_lookup_module_info);
650#endif
651
652#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
653 addlookupmodule(NULL, &oracle_lookup_module_info);
654#endif
655
656#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
657 addlookupmodule(NULL, &passwd_lookup_module_info);
658#endif
659
660#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
661 addlookupmodule(NULL, &pgsql_lookup_module_info);
662#endif
663
2ea97746 664#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
420a0d19
CE
665 addlookupmodule(NULL, &redis_lookup_module_info);
666#endif
667
2ea97746
CE
668#ifdef EXPERIMENTAL_LMDB
669 addlookupmodule(NULL, &lmdb_lookup_module_info);
670#endif
671
672#ifdef SUPPORT_SPF
420a0d19
CE
673 addlookupmodule(NULL, &spf_lookup_module_info);
674#endif
675
676#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
677 addlookupmodule(NULL, &sqlite_lookup_module_info);
678#endif
679
680#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
681 addlookupmodule(NULL, &testdb_lookup_module_info);
682#endif
683
684#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
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) {
691 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
692 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
693 }
694 else {
2ea97746
CE
695 const pcre *regex_islookupmod = regex_must_compile(
696 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
697
420a0d19
CE
698 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
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;
706 const char *errormsg;
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
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
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);
750 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
751 countmodules++;
752 }
753 }
2ea97746 754 store_free((void*)regex_islookupmod);
420a0d19
CE
755 closedir(dd);
756 }
757
758 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
759#endif
760
420a0d19
CE
761 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
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
2ea97746 783#endif /*!MACRO_PREDEF*/
420a0d19 784/* End of drtables.c */