Commit d7e72b0c d7e72b0c0ca03b9fc303aefc3b9785f6923f31c4 by Sergey Poznyakoff

Support for loadable extensions for sieve

1 parent cb7515a6
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #ifdef HAVE_LIBLTDL
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <sieve.h>
28 #include <ltdl.h>
29
30 typedef int (*sieve_module_init_t) __PMT((sieve_machine_t mach));
31
32 static int inited = 0;
33
34 static void
35 _free_loaded_module (void *data)
36 {
37 lt_dlclose ((lt_dlhandle)data);
38 }
39
40 int wd ()
41 {
42 int volatile _s=0;
43 while (!_s);
44 }
45
46 static lt_dlhandle
47 load_module (sieve_machine_t mach, const char *name)
48 {
49 lt_dlhandle handle;
50 if (!inited)
51 {
52 if (lt_dlinit ())
53 return NULL;
54 inited++;
55 }
56 handle = lt_dlopenext (name);
57 if (handle)
58 {
59 sieve_module_init_t init = (sieve_module_init_t)
60 lt_dlsym (handle, "init");
61 if (init)
62 {
63 init (mach);
64 sieve_machine_add_destructor (mach, _free_loaded_module, handle);
65 return handle;
66 }
67 else
68 {
69 lt_dlclose (handle);
70 handle = NULL;
71 }
72 }
73
74 if (!handle)
75 {
76 sieve_error (mach, "%s", lt_dlerror ());
77 }
78 return handle;
79 }
80
81 static void
82 fix_module_name (char *name)
83 {
84 for (; *name; name++)
85 {
86 if (isalnum (*name) || *name == '.' || *name == ',')
87 continue;
88 *name = '-';
89 }
90 }
91
92 int
93 sieve_load_ext (sieve_machine_t mach, const char *name)
94 {
95 lt_dlhandle handle;
96 char *modname;
97
98 modname = strdup (name);
99 if (!modname)
100 return 1;
101 fix_module_name (modname);
102 handle = load_module (mach, modname);
103 free (modname);
104 return handle == NULL;
105 }
106
107 #else
108
109 int
110 sieve_load_ext (sieve_machine_t mach, const char *name)
111 {
112 return 1;
113 }
114
115 #endif /* HAVE_LIBLTDL */