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