tidying
[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
4c04137d 24/* Table of information about all possible authentication mechanisms. All
059ec3d9
PH
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
3369a853
ACK
231#ifdef EXPERIMENTAL_QUEUEFILE
232#include "transports/queuefile.h"
233#endif
234
059ec3d9
PH
235#ifdef TRANSPORT_SMTP
236#include "transports/smtp.h"
237#endif
238
239
240/* Now set up the structures, terminated by an entry with a null name. */
241
242router_info routers_available[] = {
243#ifdef ROUTER_ACCEPT
244 {
245 US"accept",
246 accept_router_options,
247 &accept_router_options_count,
248 &accept_router_option_defaults,
249 sizeof(accept_router_options_block),
250 accept_router_init,
251 accept_router_entry,
252 NULL, /* no tidyup entry */
253 ri_yestransport
254 },
255#endif
256#ifdef ROUTER_DNSLOOKUP
257 {
258 US"dnslookup",
259 dnslookup_router_options,
260 &dnslookup_router_options_count,
261 &dnslookup_router_option_defaults,
262 sizeof(dnslookup_router_options_block),
263 dnslookup_router_init,
264 dnslookup_router_entry,
265 NULL, /* no tidyup entry */
266 ri_yestransport
267 },
268#endif
269#ifdef ROUTER_IPLITERAL
270 {
271 US"ipliteral",
272 ipliteral_router_options,
273 &ipliteral_router_options_count,
274 &ipliteral_router_option_defaults,
275 sizeof(ipliteral_router_options_block),
276 ipliteral_router_init,
277 ipliteral_router_entry,
278 NULL, /* no tidyup entry */
279 ri_yestransport
280 },
281#endif
282#ifdef ROUTER_IPLOOKUP
283 {
284 US"iplookup",
285 iplookup_router_options,
286 &iplookup_router_options_count,
287 &iplookup_router_option_defaults,
288 sizeof(iplookup_router_options_block),
289 iplookup_router_init,
290 iplookup_router_entry,
291 NULL, /* no tidyup entry */
292 ri_notransport
293 },
294#endif
295#ifdef ROUTER_MANUALROUTE
296 {
297 US"manualroute",
298 manualroute_router_options,
299 &manualroute_router_options_count,
300 &manualroute_router_option_defaults,
301 sizeof(manualroute_router_options_block),
302 manualroute_router_init,
303 manualroute_router_entry,
304 NULL, /* no tidyup entry */
305 0
306 },
307#endif
308#ifdef ROUTER_QUERYPROGRAM
309 {
310 US"queryprogram",
311 queryprogram_router_options,
312 &queryprogram_router_options_count,
313 &queryprogram_router_option_defaults,
314 sizeof(queryprogram_router_options_block),
315 queryprogram_router_init,
316 queryprogram_router_entry,
317 NULL, /* no tidyup entry */
318 0
319 },
320#endif
321#ifdef ROUTER_REDIRECT
322 {
323 US"redirect",
324 redirect_router_options,
325 &redirect_router_options_count,
326 &redirect_router_option_defaults,
327 sizeof(redirect_router_options_block),
328 redirect_router_init,
329 redirect_router_entry,
330 NULL, /* no tidyup entry */
331 ri_notransport
332 },
333#endif
334{ US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
335};
336
337
338
339transport_info transports_available[] = {
340#ifdef TRANSPORT_APPENDFILE
341 {
342 US"appendfile", /* driver name */
343 appendfile_transport_options, /* local options table */
344 &appendfile_transport_options_count, /* number of entries */
345 &appendfile_transport_option_defaults, /* private options defaults */
346 sizeof(appendfile_transport_options_block), /* size of private block */
347 appendfile_transport_init, /* init entry point */
348 appendfile_transport_entry, /* main entry point */
349 NULL, /* no tidyup entry */
350 NULL, /* no closedown entry */
351 TRUE, /* local flag */
352 },
353#endif
354#ifdef TRANSPORT_AUTOREPLY
355 {
356 US"autoreply", /* driver name */
357 autoreply_transport_options, /* local options table */
358 &autoreply_transport_options_count, /* number of entries */
359 &autoreply_transport_option_defaults, /* private options defaults */
360 sizeof(autoreply_transport_options_block), /* size of private block */
361 autoreply_transport_init, /* init entry point */
362 autoreply_transport_entry, /* main entry point */
363 NULL, /* no tidyup entry */
364 NULL, /* no closedown entry */
365 TRUE /* local flag */
366 },
367#endif
368#ifdef TRANSPORT_LMTP
369 {
370 US"lmtp", /* driver name */
371 lmtp_transport_options, /* local options table */
372 &lmtp_transport_options_count, /* number of entries */
373 &lmtp_transport_option_defaults, /* private options defaults */
374 sizeof(lmtp_transport_options_block), /* size of private block */
375 lmtp_transport_init, /* init entry point */
376 lmtp_transport_entry, /* main entry point */
377 NULL, /* no tidyup entry */
378 NULL, /* no closedown entry */
379 TRUE /* local flag */
380 },
381#endif
382#ifdef TRANSPORT_PIPE
383 {
384 US"pipe", /* driver name */
385 pipe_transport_options, /* local options table */
386 &pipe_transport_options_count, /* number of entries */
387 &pipe_transport_option_defaults, /* private options defaults */
388 sizeof(pipe_transport_options_block), /* size of private block */
389 pipe_transport_init, /* init entry point */
390 pipe_transport_entry, /* main entry point */
391 NULL, /* no tidyup entry */
392 NULL, /* no closedown entry */
393 TRUE /* local flag */
394 },
395#endif
3369a853
ACK
396#ifdef EXPERIMENTAL_QUEUEFILE
397 {
398 US"queuefile", /* driver name */
399 queuefile_transport_options, /* local options table */
400 &queuefile_transport_options_count, /* number of entries */
401 &queuefile_transport_option_defaults, /* private options defaults */
402 sizeof(queuefile_transport_options_block), /* size of private block */
403 queuefile_transport_init, /* init entry point */
404 queuefile_transport_entry, /* main entry point */
405 NULL, /* no tidyup entry */
406 NULL, /* no closedown entry */
407 TRUE /* local flag */
408 },
409#endif
059ec3d9
PH
410#ifdef TRANSPORT_SMTP
411 {
412 US"smtp", /* driver name */
413 smtp_transport_options, /* local options table */
414 &smtp_transport_options_count, /* number of entries */
415 &smtp_transport_option_defaults, /* private options defaults */
416 sizeof(smtp_transport_options_block), /* size of private block */
417 smtp_transport_init, /* init entry point */
418 smtp_transport_entry, /* main entry point */
419 NULL, /* no tidyup entry */
420 smtp_transport_closedown, /* close down passed channel */
421 FALSE /* local flag */
422 },
423#endif
424{ US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
425};
426
d185889f
JH
427
428#ifndef MACRO_PREDEF
429
e6d225ae
DW
430struct lookupmodulestr
431{
432 void *dl;
433 struct lookup_module_info *info;
434 struct lookupmodulestr *next;
435};
436
437static struct lookupmodulestr *lookupmodules = NULL;
438
96f5fe4c
JH
439static void
440addlookupmodule(void *dl, struct lookup_module_info *info)
e6d225ae 441{
96f5fe4c
JH
442struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
443
444p->dl = dl;
445p->info = info;
446p->next = lookupmodules;
447lookupmodules = p;
448lookup_list_count += info->lookupcount;
e6d225ae
DW
449}
450
451/* only valid after lookup_list and lookup_list_count are assigned */
96f5fe4c
JH
452static void
453add_lookup_to_list(lookup_info *info)
e6d225ae 454{
96f5fe4c
JH
455/* need to add the lookup to lookup_list, sorted */
456int pos = 0;
457
458/* strategy is to go through the list until we find
459either an empty spot or a name that is higher.
460this can't fail because we have enough space. */
461
462while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
463 pos++;
464
465if (lookup_list[pos])
466 {
467 /* need to insert it, so move all the other items up
468 (last slot is still empty, of course) */
469
470 memmove(&lookup_list[pos+1],
471 &lookup_list[pos],
472 sizeof(lookup_info *) * (lookup_list_count-pos-1));
e6d225ae 473 }
96f5fe4c 474lookup_list[pos] = info;
e6d225ae
DW
475}
476
4d805ee9
PP
477
478/* These need to be at file level for old versions of gcc (2.95.2 reported),
479 * which give parse errors on an extern in function scope. Each entry needs
480 * to also be invoked in init_lookup_list() below */
481
78f72498
JH
482#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
483extern lookup_module_info cdb_lookup_module_info;
4d805ee9 484#endif
78f72498
JH
485#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
486extern lookup_module_info dbmdb_lookup_module_info;
4d805ee9 487#endif
78f72498
JH
488#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
489extern lookup_module_info dnsdb_lookup_module_info;
4d805ee9 490#endif
78f72498
JH
491#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
492extern lookup_module_info dsearch_lookup_module_info;
4d805ee9 493#endif
78f72498
JH
494#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
495extern lookup_module_info ibase_lookup_module_info;
4d805ee9 496#endif
78f72498
JH
497#if defined(LOOKUP_LDAP)
498extern lookup_module_info ldap_lookup_module_info;
de78e2d5 499#endif
78f72498
JH
500#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
501extern lookup_module_info lsearch_lookup_module_info;
4d805ee9 502#endif
78f72498
JH
503#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
504extern lookup_module_info mysql_lookup_module_info;
4d805ee9
PP
505#endif
506#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
507extern lookup_module_info nis_lookup_module_info;
508#endif
78f72498
JH
509#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
510extern lookup_module_info nisplus_lookup_module_info;
4d805ee9 511#endif
78f72498
JH
512#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
513extern lookup_module_info oracle_lookup_module_info;
4d805ee9 514#endif
78f72498
JH
515#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
516extern lookup_module_info passwd_lookup_module_info;
4d805ee9 517#endif
78f72498
JH
518#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
519extern lookup_module_info pgsql_lookup_module_info;
4d805ee9 520#endif
78f72498
JH
521#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
522extern lookup_module_info redis_lookup_module_info;
4d805ee9 523#endif
5bde3efa
ACK
524#if defined(EXPERIMENTAL_LMDB)
525extern lookup_module_info lmdb_lookup_module_info;
526#endif
78f72498
JH
527#if defined(EXPERIMENTAL_SPF)
528extern lookup_module_info spf_lookup_module_info;
4d805ee9 529#endif
78f72498
JH
530#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
531extern lookup_module_info sqlite_lookup_module_info;
4d805ee9 532#endif
78f72498
JH
533#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
534extern lookup_module_info testdb_lookup_module_info;
535#endif
536#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
537extern lookup_module_info whoson_lookup_module_info;
4d805ee9
PP
538#endif
539
96f5fe4c
JH
540
541void
542init_lookup_list(void)
e6d225ae 543{
fb2bba55 544#ifdef LOOKUP_MODULE_DIR
e6d225ae
DW
545 DIR *dd;
546 struct dirent *ent;
e6d225ae
DW
547 int countmodules = 0;
548 int moduleerrors = 0;
fb2bba55 549#endif
e6d225ae
DW
550 struct lookupmodulestr *p;
551
6545de78
PP
552 if (lookup_list_init_done)
553 return;
554 lookup_list_init_done = 1;
555
e6d225ae 556#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
e6d225ae
DW
557 addlookupmodule(NULL, &cdb_lookup_module_info);
558#endif
559
560#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
e6d225ae
DW
561 addlookupmodule(NULL, &dbmdb_lookup_module_info);
562#endif
563
564#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
e6d225ae
DW
565 addlookupmodule(NULL, &dnsdb_lookup_module_info);
566#endif
567
568#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
e6d225ae
DW
569 addlookupmodule(NULL, &dsearch_lookup_module_info);
570#endif
571
572#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
e6d225ae
DW
573 addlookupmodule(NULL, &ibase_lookup_module_info);
574#endif
575
576#ifdef LOOKUP_LDAP
e6d225ae
DW
577 addlookupmodule(NULL, &ldap_lookup_module_info);
578#endif
579
580#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
e6d225ae
DW
581 addlookupmodule(NULL, &lsearch_lookup_module_info);
582#endif
583
584#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
e6d225ae
DW
585 addlookupmodule(NULL, &mysql_lookup_module_info);
586#endif
587
588#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
e6d225ae
DW
589 addlookupmodule(NULL, &nis_lookup_module_info);
590#endif
591
592#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
e6d225ae
DW
593 addlookupmodule(NULL, &nisplus_lookup_module_info);
594#endif
595
596#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
e6d225ae
DW
597 addlookupmodule(NULL, &oracle_lookup_module_info);
598#endif
599
600#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
e6d225ae
DW
601 addlookupmodule(NULL, &passwd_lookup_module_info);
602#endif
603
604#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
e6d225ae
DW
605 addlookupmodule(NULL, &pgsql_lookup_module_info);
606#endif
607
de78e2d5 608#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
9bdd29ad
TL
609 addlookupmodule(NULL, &redis_lookup_module_info);
610#endif
611
5bde3efa
ACK
612#ifdef EXPERIMENTAL_LMDB
613 addlookupmodule(NULL, &lmdb_lookup_module_info);
614#endif
615
e6d225ae 616#ifdef EXPERIMENTAL_SPF
e6d225ae
DW
617 addlookupmodule(NULL, &spf_lookup_module_info);
618#endif
619
620#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
e6d225ae
DW
621 addlookupmodule(NULL, &sqlite_lookup_module_info);
622#endif
623
624#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
e6d225ae
DW
625 addlookupmodule(NULL, &testdb_lookup_module_info);
626#endif
627
628#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
e6d225ae
DW
629 addlookupmodule(NULL, &whoson_lookup_module_info);
630#endif
631
632#ifdef LOOKUP_MODULE_DIR
633 dd = opendir(LOOKUP_MODULE_DIR);
634 if (dd == NULL) {
1594a79a 635 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
636 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
637 }
638 else {
f322340b
JH
639 const pcre *regex_islookupmod = regex_must_compile(
640 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
641
1594a79a 642 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
643 while ((ent = readdir(dd)) != NULL) {
644 char *name = ent->d_name;
645 int len = (int)strlen(name);
646 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
647 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
648 void *dl;
649 struct lookup_module_info *info;
1ba28e2b 650 const char *errormsg;
e6d225ae
DW
651
652 /* SRH: am I being paranoid here or what? */
653 if (pathnamelen > big_buffer_size) {
654 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
655 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
656 continue;
657 }
658
659 /* SRH: snprintf here? */
660 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
661
662 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
663 if (dl == NULL) {
664 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
665 moduleerrors++;
666 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
667 continue;
668 }
669
56e0c4ce
PP
670 /* FreeBSD nsdispatch() can trigger dlerror() errors about
671 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
672 * state before calling dlsym(), so that any error afterwards only
673 * comes from dlsym().
674 */
675 errormsg = dlerror();
676
e6d225ae
DW
677 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
678 if ((errormsg = dlerror()) != NULL) {
679 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
680 dlclose(dl);
681 moduleerrors++;
682 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
683 continue;
684 }
685 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
686 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
687 dlclose(dl);
688 moduleerrors++;
689 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
690 continue;
691 }
692
693 addlookupmodule(dl, info);
1594a79a 694 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
e6d225ae
DW
695 countmodules++;
696 }
697 }
f322340b 698 store_free((void*)regex_islookupmod);
e6d225ae
DW
699 closedir(dd);
700 }
701
1594a79a 702 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
e6d225ae
DW
703#endif
704
1594a79a 705 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
e6d225ae
DW
706
707 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
708 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
709
710 /* now add all lookups to the real list */
711 p = lookupmodules;
712 while (p) {
713 int j;
714 struct lookupmodulestr *pnext;
715
716 for (j = 0; j < p->info->lookupcount; j++)
717 add_lookup_to_list(p->info->lookups[j]);
718
719 pnext = p->next;
720 store_free(p);
721 p = pnext;
722 }
723 /* just to be sure */
724 lookupmodules = NULL;
725}
726
d185889f 727#endif /*!MACRO_PREDEF*/
059ec3d9 728/* End of drtables.c */