General cleanups in header files
[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.15 2005/02/20 18:52:18 kattemat Exp $
40  */
41
42 #include "plugin_loader.h"
43 #include "defs.h"
44
45 /* Local functions */
46
47 static void
48 init_olsr_plugin(struct olsr_plugin *);
49
50 static int
51 olsr_load_dl(char *, struct plugin_param *);
52
53 /* Extern */
54
55 extern int
56 olsr_plugin_io(int, void *, size_t);
57
58
59 static struct olsr_plugin *olsr_plugins;
60
61
62 /**
63  *Function that loads all registered plugins
64  *
65  *@return the number of plugins loaded
66  */
67 int
68 olsr_load_plugins()
69 {
70   struct plugin_entry *entry;
71   int loaded;
72
73   entry = olsr_cnf->plugins;
74   loaded = 0;
75
76   olsr_printf(1, "Loading plugins...\n\n");
77
78   while(entry)
79     {  
80       if(olsr_load_dl(entry->name, entry->params) < 0)
81         olsr_printf(1, "-- PLUGIN LOADING FAILED! --\n\n");
82       else
83         loaded ++;
84
85       entry = entry->next;
86     }
87   return loaded;
88 }
89
90
91 /**
92  *Try to load a shared library and extract
93  *the required information
94  *
95  *@param libname the name of the library(file)
96  *
97  *@return negative on error
98  */
99 int
100 olsr_load_dl(char *libname, struct plugin_param *params)
101 {
102   struct olsr_plugin new_entry, *entry;
103   int (*get_interface_version)(void);
104   int *interface_version;
105
106   olsr_printf(1, "---------- Plugin loader ----------\nLibrary: %s\n", libname);
107
108   if((new_entry.dlhandle = dlopen(libname, RTLD_NOW)) == NULL)
109     {
110       olsr_printf(1, "DL loading failed: \"%s\"!\n", dlerror());
111       return -1;
112     }
113
114   /* Fetch the interface version function */
115   olsr_printf(1, "Checking plugin interface version....");
116   if((get_interface_version = dlsym(new_entry.dlhandle, "get_plugin_interface_version")) == NULL)
117     {
118       olsr_printf(1, "trying v1 detection...");
119       if((interface_version = dlsym(new_entry.dlhandle, "plugin_interface_version")) == NULL)
120         {
121           olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
122           dlclose(new_entry.dlhandle);
123           return -1;
124         }
125       else
126         {
127           olsr_printf(1, " %d - ", *interface_version);
128           if(*interface_version != PLUGIN_INTERFACE_VERSION)
129             olsr_printf(1, "WARNING: VERSION MISSMATCH!\n");
130           else
131             olsr_printf(1, "OK\n");
132         }
133     }
134   else
135     {
136       olsr_printf(1, " %d - ", get_interface_version());
137       if(get_interface_version() != PLUGIN_INTERFACE_VERSION)
138         olsr_printf(1, "WARNING: VERSION MISSMATCH!\n");
139       else
140         olsr_printf(1, "OK\n");
141     }
142
143   olsr_printf(1, "Trying to fetch register function....");
144   
145   if((new_entry.register_olsr_data = dlsym(new_entry.dlhandle, "register_olsr_data")) == NULL)
146     {
147       /* This function must be present */
148       olsr_printf(1, "\nCould not find function registration function in plugin!\n%s\nCRITICAL ERROR - aborting!\n", dlerror());
149       dlclose(new_entry.dlhandle);
150       return -1;
151     }
152   olsr_printf(1, "OK\n");
153
154
155   /* Fetch the multipurpose function */
156   olsr_printf(1, "Trying to fetch plugin IO function....");
157   if((new_entry.plugin_io = dlsym(new_entry.dlhandle, "plugin_io")) == NULL)
158     olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
159   else
160     olsr_printf(1, "OK\n");
161
162   /* Fetch the parameter function */
163   olsr_printf(1, "Trying to fetch param function....");
164   if((new_entry.register_param = dlsym(new_entry.dlhandle, "register_olsr_param")) == NULL)
165     olsr_printf(1, "FAILED: \"%s\"\n", dlerror());
166   else
167     olsr_printf(1, "OK\n");
168
169
170   entry = olsr_malloc(sizeof(struct olsr_plugin), "Plugin entry");
171
172   memcpy(entry, &new_entry, sizeof(struct olsr_plugin));
173
174   entry->params = params;
175
176   /* Initialize the plugin */
177   init_olsr_plugin(entry);
178
179   /* queue */
180   entry->next = olsr_plugins;
181   olsr_plugins = entry;
182
183   olsr_printf(1, "---------- LIBRARY LOADED ----------\n\n");
184
185   return 0;
186 }
187
188
189
190 /**
191  *Initialize a loaded plugin
192  *This includes sending information
193  *from olsrd to the plugin and
194  *register the functions from the flugin with olsrd
195  *
196  *@param entry the plugin to initialize
197  *
198  *@return nada
199  */
200 void
201 init_olsr_plugin(struct olsr_plugin *entry)
202 {
203   struct olsr_plugin_data plugin_data;
204   struct plugin_param *params = entry->params;
205   int retval;
206
207   if(entry->register_param)
208     {
209       olsr_printf(1, "Sending parameters...\n");
210       while(params)
211         {
212           olsr_printf(1, "\"%s\"/\"%s\".... ", params->key, params->value);
213           if((retval = entry->register_param(params->key, params->value)) < 0)
214             {
215               fprintf(stderr, "\nFatal error in plugin parameter \"%s\"/\"%s\"\n", params->key, params->value);
216               exit(EXIT_FAILURE);
217             }
218           retval == 0 ? olsr_printf(1, "FAILED\n") : olsr_printf(1, "OK\n");
219
220           params = params->next;
221         }
222     }
223
224   olsr_printf(1, "Running registration function...\n");
225   /* Fill struct */
226   plugin_data.ipversion = olsr_cnf->ip_version;
227   plugin_data.main_addr = &main_addr;
228
229   plugin_data.olsr_plugin_io = &olsr_plugin_io;
230
231   /* Register data with plugin */
232   entry->register_olsr_data(&plugin_data);
233
234 }
235
236
237
238 /**
239  *Close all loaded plugins
240  */
241 void
242 olsr_close_plugins()
243 {
244   struct olsr_plugin *entry;
245
246   olsr_printf(1, "Closing plugins...\n");
247   for(entry = olsr_plugins; 
248       entry != NULL ; 
249       entry = entry->next)
250     {
251       dlclose(&entry->dlhandle);
252     }
253
254 }