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