Prebuild the data structure for builtin macros
[exim.git] / src / src / drtables.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2016 */
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
14 that are actually included in the binary. Its contents are controlled by
15 various macros in config.h that ultimately come from Local/Makefile. They are
16 all described in src/EDITME. */
17
18
19 lookup_info **lookup_list;
20 int lookup_list_count = 0;
21
22 static int lookup_list_init_done = 0;
23
24 /* Table of information about all possible authentication mechanisms. All
25 entries are always present if any mechanism is declared, but the functions are
26 set 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
36 #ifdef AUTH_DOVECOT
37 #include "auths/dovecot.h"
38 #endif
39
40 #ifdef AUTH_GSASL
41 #include "auths/gsasl_exim.h"
42 #endif
43
44 #ifdef AUTH_HEIMDAL_GSSAPI
45 #include "auths/heimdal_gssapi.h"
46 #endif
47
48 #ifdef AUTH_PLAINTEXT
49 #include "auths/plaintext.h"
50 #endif
51
52 #ifdef AUTH_SPA
53 #include "auths/spa.h"
54 #endif
55
56 #ifdef AUTH_TLS
57 #include "auths/tls.h"
58 #endif
59
60 auth_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 */
73   auth_cram_md5_client,                      /* client function */
74   NULL                                       /* diagnostic function */
75   },
76 #endif
77
78 #ifdef AUTH_CYRUS_SASL
79   {
80   US"cyrus_sasl",           /* lookup name */
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 */
87   NULL,                                      /* client function */
88   auth_cyrus_sasl_version_report             /* diagnostic function */
89   },
90 #endif
91
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 */
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 */
117   },
118 #endif
119
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
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 */
143   auth_plaintext_client,                     /* client function */
144   NULL                                       /* diagnostic function */
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 */
157   auth_spa_client,                           /* client function */
158   NULL                                       /* diagnostic function */
159   },
160 #endif
161
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
176 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL  }
177 };
178
179
180 /* Tables of information about which routers and transports are included in the
181 exim 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 EXPERIMENTAL_QUEUEFILE
232 #include "transports/queuefile.h"
233 #endif
234
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
242 router_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
339 transport_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
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
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
427
428 #ifndef MACRO_PREDEF
429
430 struct lookupmodulestr
431 {
432   void *dl;
433   struct lookup_module_info *info;
434   struct lookupmodulestr *next;
435 };
436
437 static struct lookupmodulestr *lookupmodules = NULL;
438
439 static void
440 addlookupmodule(void *dl, struct lookup_module_info *info)
441 {
442 struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
443
444 p->dl = dl;
445 p->info = info;
446 p->next = lookupmodules;
447 lookupmodules = p;
448 lookup_list_count += info->lookupcount;
449 }
450
451 /* only valid after lookup_list and lookup_list_count are assigned */
452 static void
453 add_lookup_to_list(lookup_info *info)
454 {
455 /* need to add the lookup to lookup_list, sorted */
456 int pos = 0;
457
458 /* strategy is to go through the list until we find
459 either an empty spot or a name that is higher.
460 this can't fail because we have enough space. */
461
462 while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
463   pos++;
464
465 if (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));
473   }
474 lookup_list[pos] = info;
475 }
476
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
482 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
483 extern lookup_module_info cdb_lookup_module_info;
484 #endif
485 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
486 extern lookup_module_info dbmdb_lookup_module_info;
487 #endif
488 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
489 extern lookup_module_info dnsdb_lookup_module_info;
490 #endif
491 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
492 extern lookup_module_info dsearch_lookup_module_info;
493 #endif
494 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
495 extern lookup_module_info ibase_lookup_module_info;
496 #endif
497 #if defined(LOOKUP_LDAP)
498 extern lookup_module_info ldap_lookup_module_info;
499 #endif
500 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
501 extern lookup_module_info lsearch_lookup_module_info;
502 #endif
503 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
504 extern lookup_module_info mysql_lookup_module_info;
505 #endif
506 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
507 extern lookup_module_info nis_lookup_module_info;
508 #endif
509 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
510 extern lookup_module_info nisplus_lookup_module_info;
511 #endif
512 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
513 extern lookup_module_info oracle_lookup_module_info;
514 #endif
515 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
516 extern lookup_module_info passwd_lookup_module_info;
517 #endif
518 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
519 extern lookup_module_info pgsql_lookup_module_info;
520 #endif
521 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
522 extern lookup_module_info redis_lookup_module_info;
523 #endif
524 #if defined(EXPERIMENTAL_LMDB)
525 extern lookup_module_info lmdb_lookup_module_info;
526 #endif
527 #if defined(EXPERIMENTAL_SPF)
528 extern lookup_module_info spf_lookup_module_info;
529 #endif
530 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
531 extern lookup_module_info sqlite_lookup_module_info;
532 #endif
533 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
534 extern lookup_module_info testdb_lookup_module_info;
535 #endif
536 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
537 extern lookup_module_info whoson_lookup_module_info;
538 #endif
539
540
541 void
542 init_lookup_list(void)
543 {
544 #ifdef LOOKUP_MODULE_DIR
545   DIR *dd;
546   struct dirent *ent;
547   int countmodules = 0;
548   int moduleerrors = 0;
549 #endif
550   struct lookupmodulestr *p;
551
552   if (lookup_list_init_done)
553     return;
554   lookup_list_init_done = 1;
555
556 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
557   addlookupmodule(NULL, &cdb_lookup_module_info);
558 #endif
559
560 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
561   addlookupmodule(NULL, &dbmdb_lookup_module_info);
562 #endif
563
564 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
565   addlookupmodule(NULL, &dnsdb_lookup_module_info);
566 #endif
567
568 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
569   addlookupmodule(NULL, &dsearch_lookup_module_info);
570 #endif
571
572 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
573   addlookupmodule(NULL, &ibase_lookup_module_info);
574 #endif
575
576 #ifdef LOOKUP_LDAP
577   addlookupmodule(NULL, &ldap_lookup_module_info);
578 #endif
579
580 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
581   addlookupmodule(NULL, &lsearch_lookup_module_info);
582 #endif
583
584 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
585   addlookupmodule(NULL, &mysql_lookup_module_info);
586 #endif
587
588 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
589   addlookupmodule(NULL, &nis_lookup_module_info);
590 #endif
591
592 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
593   addlookupmodule(NULL, &nisplus_lookup_module_info);
594 #endif
595
596 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
597   addlookupmodule(NULL, &oracle_lookup_module_info);
598 #endif
599
600 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
601   addlookupmodule(NULL, &passwd_lookup_module_info);
602 #endif
603
604 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
605   addlookupmodule(NULL, &pgsql_lookup_module_info);
606 #endif
607
608 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
609   addlookupmodule(NULL, &redis_lookup_module_info);
610 #endif
611
612 #ifdef EXPERIMENTAL_LMDB
613   addlookupmodule(NULL, &lmdb_lookup_module_info);
614 #endif
615
616 #ifdef EXPERIMENTAL_SPF
617   addlookupmodule(NULL, &spf_lookup_module_info);
618 #endif
619
620 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
621   addlookupmodule(NULL, &sqlite_lookup_module_info);
622 #endif
623
624 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
625   addlookupmodule(NULL, &testdb_lookup_module_info);
626 #endif
627
628 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
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) {
635     DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
636     log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
637   }
638   else {
639     const pcre *regex_islookupmod = regex_must_compile(
640       US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
641
642     DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
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;
650         const char *errormsg;
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
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
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);
694         DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
695         countmodules++;
696       }
697     }
698     store_free((void*)regex_islookupmod);
699     closedir(dd);
700   }
701
702   DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
703 #endif
704
705   DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
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
727 #endif  /*!MACRO_PREDEF*/
728 /* End of drtables.c */