76e91c4a21afbcd5c2610ab4c04794eb035a1d69
[olsrd.git] / src / plugin_loader.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: plugin_loader.c,v 1.13 2004/11/21 11:28:56 kattemat Exp $
40  */
41
42 #include "plugin_loader.h"
43 #include "defs.h"
44 #include "plugin.h"
45
46 /* Local functions */
47
48 static void
49 init_olsr_plugin(struct olsr_plugin *);
50
51 static int
52 olsr_load_dl(char *, struct plugin_param *);
53
54
55
56
57 /**
58  *Function that loads all registered plugins
59  *
60  *@return the number of plugins loaded
61  */
62 int
63 olsr_load_plugins()
64 {
65   struct plugin_entry *entry;
66   int loaded;
67
68   entry = olsr_cnf->plugins;
69   loaded = 0;
70
71   olsr_printf(1, "Loading plugins...\n\n");
72
73   while(entry)
74     {  
75       if(olsr_load_dl(entry->name, entry->params) < 0)
76         olsr_printf(1, "-- PLUGIN LOADING FAILED! --\n\n");
77       else
78         loaded ++;
79
80       entry = entry->next;
81     }
82   return loaded;
83 }
84
85
86 /**
87  *Try to load a shared library and extract
88  *the required information
89  *
90  *@param libname the name of the library(file)
91  *
92  *@return negative on error
93  */
94 int
95 olsr_load_dl(char *libname, struct plugin_param *params)
96 {
97   struct olsr_plugin new_entry, *entry;
98   int (*get_interface_version)(void);
99   int *interface_version;
100
101   olsr_printf(1, "---------- Plugin loader ----------\nLibrary: %s\n", libname);
102
103   if((new_entry.dlhandle = dlopen(libname, RTLD_NOW)) == NULL)
104     {
105       olsr_printf(1, "DL loading failed: \"%s\"!\n", dlerror());
106       return -1;
107     }
108
109   /* Fetch the interface version function */
110   olsr_printf(1, "Checking plugin interface version....");
111   if((get_interface_version = dlsym(new_entry.dlhandle, "get_plugin_interface_version")) == NULL)
112     {
113       olsr_printf(1, "trying v1 detection...");
114       if((interface_version = dlsym(new_entry.dlhandle, "plugin_interface_version")) == NULL)
115         {
116           olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
117           dlclose(new_entry.dlhandle);
118           return -1;
119         }
120       else
121         {
122           olsr_printf(1, " %d - ", *interface_version);
123           if(*interface_version != PLUGIN_INTERFACE_VERSION)
124             olsr_printf(1, "WARNING: VERSION MISSMATCH!\n");
125           else
126             olsr_printf(1, "OK\n");
127         }
128     }
129   else
130     {
131       olsr_printf(1, " %d - ", get_interface_version());
132       if(get_interface_version() != PLUGIN_INTERFACE_VERSION)
133         olsr_printf(1, "WARNING: VERSION MISSMATCH!\n");
134       else
135         olsr_printf(1, "OK\n");
136     }
137
138   olsr_printf(1, "Trying to fetch register function....");
139   
140   if((new_entry.register_olsr_data = dlsym(new_entry.dlhandle, "register_olsr_data")) == NULL)
141     {
142       /* This function must be present */
143       olsr_printf(1, "\nCould not find function registration function in plugin!\n%s\nCRITICAL ERROR - aborting!\n", dlerror());
144       dlclose(new_entry.dlhandle);
145       return -1;
146     }
147   olsr_printf(1, "OK\n");
148
149
150   /* Fetch the multipurpose function */
151   olsr_printf(1, "Trying to fetch plugin IO function....");
152   if((new_entry.plugin_io = dlsym(new_entry.dlhandle, "plugin_io")) == NULL)
153     olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
154   else
155     olsr_printf(1, "OK\n");
156
157   /* Fetch the parameter function */
158   olsr_printf(1, "Trying to fetch param function....");
159   if((new_entry.register_param = dlsym(new_entry.dlhandle, "register_olsr_param")) == NULL)
160     olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
161   else
162     olsr_printf(1, "OK\n");
163
164
165   entry = olsr_malloc(sizeof(struct olsr_plugin), "Plugin entry");
166
167   memcpy(entry, &new_entry, sizeof(struct olsr_plugin));
168
169   entry->params = params;
170
171   /* Initialize the plugin */
172   init_olsr_plugin(entry);
173
174   /* queue */
175   entry->next = olsr_plugins;
176   olsr_plugins = entry;
177
178   olsr_printf(1, "---------- LIBRARY LOADED ----------\n\n");
179
180   return 0;
181 }
182
183
184
185 /**
186  *Initialize a loaded plugin
187  *This includes sending information
188  *from olsrd to the plugin and
189  *register the functions from the flugin with olsrd
190  *
191  *@param entry the plugin to initialize
192  *
193  *@return nada
194  */
195 void
196 init_olsr_plugin(struct olsr_plugin *entry)
197 {
198   struct olsr_plugin_data plugin_data;
199   struct plugin_param *params = entry->params;
200   int retval;
201
202   if(entry->register_param)
203     {
204       olsr_printf(1, "Sending parameters...\n");
205       while(params)
206         {
207           olsr_printf(1, "\"%s\"/\"%s\".... ", params->key, params->value);
208           if((retval = entry->register_param(params->key, params->value)) < 0)
209             {
210               fprintf(stderr, "\nFatal error in plugin parameter \"%s\"/\"%s\"\n", params->key, params->value);
211               exit(EXIT_FAILURE);
212             }
213           retval == 0 ? olsr_printf(1, "FAILED\n") : olsr_printf(1, "OK\n");
214
215           params = params->next;
216         }
217     }
218
219   olsr_printf(1, "Running registration function...\n");
220   /* Fill struct */
221   plugin_data.ipversion = olsr_cnf->ip_version;
222   plugin_data.main_addr = &main_addr;
223
224   plugin_data.olsr_plugin_io = &olsr_plugin_io;
225
226   /* Register data with plugin */
227   entry->register_olsr_data(&plugin_data);
228
229 }
230
231
232
233 /**
234  *Close all loaded plugins
235  */
236 void
237 olsr_close_plugins()
238 {
239   struct olsr_plugin *entry;
240
241   olsr_printf(1, "Closing plugins...\n");
242   for(entry = olsr_plugins; 
243       entry != NULL ; 
244       entry = entry->next)
245     {
246       dlclose(&entry->dlhandle);
247     }
248
249 }