We always HAVE_CONFIG_H so don't bother checking whether we have it or not.
[metze/wireshark/wip.git] / epan / plugins.c
1 /* plugins.c
2  * plugin routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 #include "plugins.h"
28 #include <stdio.h>
29
30 /* linked list of Lua plugins */
31 wslua_plugin *wslua_plugin_list = NULL;
32
33 #ifdef HAVE_PLUGINS
34
35 #include <time.h>
36
37 #ifdef HAVE_DIRENT_H
38 #include <dirent.h>
39 #endif
40
41 #ifdef HAVE_DIRECT_H
42 #include <direct.h>
43 #endif
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include <errno.h>
48
49 #ifdef HAVE_UNISTD_H
50 #include <unistd.h>
51 #endif
52
53 #include "filesystem.h"
54 #include <wsutil/privileges.h>
55 #include <wsutil/file_util.h>
56 #include "report_err.h"
57
58 /* linked list of all plugins */
59 plugin *plugin_list = NULL;
60
61 static void register_all_wiretap_modules(void);
62 static void register_all_codecs(void);
63
64 /*
65  * add a new plugin to the list
66  * returns :
67  * - 0 : OK
68  * - ENOMEM : memory allocation problem
69  * - EEXIST : the same plugin (i.e. name/version) was already registered.
70  */
71 static int
72 add_plugin(void *handle, gchar *name, gchar *version,
73            void (*register_protoinfo)(void),
74            void (*reg_handoff)(void),
75            void (*register_tap_listener)(void),
76            void (*register_wtap_module)(void),
77            void (*register_codec_module)(void))
78 {
79     plugin *new_plug, *pt_plug;
80
81     pt_plug = plugin_list;
82     if (!pt_plug) /* the list is empty */
83     {
84         new_plug = (plugin *)g_malloc(sizeof(plugin));
85         if (new_plug == NULL)
86             return ENOMEM;
87         plugin_list = new_plug;
88     }
89     else
90     {
91         while (1)
92         {
93             /* check if the same name/version is already registered */
94             if (!strcmp(pt_plug->name, name) &&
95                 !strcmp(pt_plug->version, version))
96             {
97                 return EEXIST;
98             }
99
100             /* we found the last plugin in the list */
101             if (pt_plug->next == NULL)
102                 break;
103
104             pt_plug = pt_plug->next;
105         }
106         new_plug = (plugin *)g_malloc(sizeof(plugin));
107         if (new_plug == NULL)
108             return ENOMEM;
109         pt_plug->next = new_plug;
110     }
111
112     new_plug->handle = handle;
113     new_plug->name = name;
114     new_plug->version = version;
115     new_plug->register_protoinfo = register_protoinfo;
116     new_plug->reg_handoff = reg_handoff;
117     new_plug->register_tap_listener = register_tap_listener;
118     new_plug->register_wtap_module = register_wtap_module;
119     new_plug->register_codec_module = register_codec_module;
120     new_plug->next = NULL;
121
122     return 0;
123 }
124
125 /*
126  * XXX - when we remove support for old-style plugins (which we should
127  * probably do eventually, as all plugins should be written as new-style
128  * ones), we may want to have "init_plugins()" merely save a pointer
129  * to the plugin's "init" routine, just as we save a pointer to its
130  * "reg_handoff" routine, and have a "register_all_plugins()" routine
131  * to go through the list of plugins and call all of them.
132  *
133  * Then we'd have "epan_init()", or perhaps even something higher up
134  * in the call tree, call "init_plugins()", and have "proto_init()"
135  * call "register_all_plugins()" right after calling "register_all_protocols()";
136  * this might be a bit cleaner.
137  */
138 static void
139 plugins_scan_dir(const char *dirname)
140 {
141 #define FILENAME_LEN        1024
142     WS_DIR        *dir;             /* scanned directory */
143     WS_DIRENT     *file;            /* current file */
144     const char    *name;
145     gchar          filename[FILENAME_LEN];   /* current file name */
146     GModule       *handle;          /* handle returned by g_module_open */
147     gchar         *version;
148     gpointer       gp;
149     void         (*register_protoinfo)(void);
150     void         (*reg_handoff)(void);
151     void         (*register_tap_listener)(void);
152     void         (*register_wtap_module)(void);
153     void         (*register_codec_module)(void);
154
155     gchar         *dot;
156     int            cr;
157
158     if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL)
159     {
160         while ((file = ws_dir_read_name(dir)) != NULL)
161         {
162             name = ws_dir_get_name(file);
163
164             /*
165              * GLib 2.x defines G_MODULE_SUFFIX as the extension used on
166              * this platform for loadable modules.
167              */
168             /* skip anything but files with G_MODULE_SUFFIX */
169             dot = strrchr(name, '.');
170             if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0)
171                 continue;
172
173             g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s",
174                        dirname, name);
175             if ((handle = g_module_open(filename, 0)) == NULL)
176             {
177                 report_failure("Couldn't load module %s: %s", filename,
178                                g_module_error());
179                 continue;
180             }
181
182             if (!g_module_symbol(handle, "version", &gp))
183             {
184                 report_failure("The plugin %s has no version symbol", name);
185                 g_module_close(handle);
186                 continue;
187             }
188             version = gp;
189
190             /*
191              * Do we have a register routine?
192              */
193             if (g_module_symbol(handle, "plugin_register", &gp))
194             {
195                 /*
196                  * Yes - this plugin includes one or more dissectors.
197                  */
198                 register_protoinfo = gp;
199             }
200             else
201             {
202                 /*
203                  * No - no dissectors.
204                  */
205                 register_protoinfo = NULL;
206             }
207
208             /*
209              * Do we have a reg_handoff routine?
210              */
211             if (g_module_symbol(handle, "plugin_reg_handoff", &gp))
212             {
213                 /*
214                  * Yes.
215                  */
216                 reg_handoff = gp;
217             }
218             else
219             {
220                 /*
221                  * No - that's OK even if we have dissectors, as long
222                  * as the plugin registers by name *and* there's
223                  * a caller looking for that name.
224                  */
225                 reg_handoff = NULL;
226             }
227
228             /*
229              * Do we have a register_tap_listener routine?
230              */
231             if (g_module_symbol(handle, "plugin_register_tap_listener", &gp))
232             {
233                 /*
234                  * Yes - this plugin includes one or more taps.
235                  */
236                 register_tap_listener = gp;
237             }
238             else
239             {
240                 /*
241                  * No - no taps here.
242                  */
243                 register_tap_listener = NULL;
244             }
245
246             /*
247              * Do we have an old-style init routine?
248              */
249             if (g_module_symbol(handle, "plugin_init", &gp))
250             {
251                 /*
252                  * Yes - do we also have a register routine or a
253                  * register_tap_listener routine?  If so, this is a bogus
254                  * hybrid of an old-style and new-style plugin.
255                  */
256                 if (register_protoinfo != NULL || register_tap_listener != NULL)
257                 {
258                     report_failure("The plugin '%s' has an old plugin init routine\nand a new register or register_tap_listener routine.",
259                                    name);
260                     g_module_close(handle);
261                     continue;
262                 }
263
264                 /*
265                  * It's just an unsupported old-style plugin;
266                  */
267                 report_failure("The plugin '%s' has an old plugin init routine. Support has been dropped.\n Information on how to update your plugin is available at \nhttp://anonsvn.wireshark.org/wireshark/trunk/doc/README.plugins",
268                                name);
269                 g_module_close(handle);
270                 continue;
271             }
272
273             /*
274              * Do we have a register_wtap_module routine?
275              */
276             if (g_module_symbol(handle, "register_wtap_module", &gp))
277             {
278                 register_wtap_module = gp;
279             }
280             else
281             {
282                 register_wtap_module = NULL;
283             }
284
285             /*
286              * Do we have a register_codec_module routine?
287              */
288             if (g_module_symbol(handle, "register_codec_module", &gp))
289             {
290                 register_codec_module = gp;
291             }
292             else
293             {
294                 register_codec_module = NULL;
295             }
296
297             /*
298              * Does this dissector do anything useful?
299              */
300             if (register_protoinfo == NULL &&
301                 register_tap_listener == NULL &&
302                 register_wtap_module == NULL &&
303                 register_codec_module == NULL )
304             {
305                 /*
306                  * No.
307                  */
308                 report_failure("The plugin '%s' has neither a register routine, "
309                                "a register_tap_listener or a register_wtap_module or a register_codec_module routine",
310                                name);
311                 g_module_close(handle);
312                 continue;
313             }
314
315             /*
316              * OK, attempt to add it to the list of plugins.
317              */
318             if ((cr = add_plugin(handle, g_strdup(name), version,
319                                  register_protoinfo, reg_handoff,
320                                  register_tap_listener,register_wtap_module,register_codec_module)))
321             {
322                 if (cr == EEXIST)
323                     fprintf(stderr, "The plugin %s, version %s\n"
324                             "was found in multiple directories\n", name, version);
325                 else
326                     fprintf(stderr, "Memory allocation problem\n"
327                             "when processing plugin %s, version %s\n",
328                             name, version);
329                 g_module_close(handle);
330                 continue;
331             }
332
333         }
334         ws_dir_close(dir);
335     }
336 }
337
338
339 /*
340  * init plugins
341  */
342 void
343 init_plugins(void)
344 {
345     const char *plugin_dir;
346     const char *name;
347     char *plugin_dir_path;
348     char *plugins_pers_dir;
349     WS_DIR *dir;                /* scanned directory */
350     WS_DIRENT *file;                /* current file */
351
352     if (plugin_list == NULL)      /* ensure init_plugins is only run once */
353     {
354         /*
355          * Scan the global plugin directory.
356          * If we're running from a build directory, scan the subdirectories
357          * of that directory, as the global plugin directory is the
358          * "plugins" directory of the source tree, and the subdirectories
359          * are the source directories for the plugins, with the plugins
360          * built in those subdirectories.
361          */
362         plugin_dir = get_plugin_dir();
363         if (running_in_build_directory())
364         {
365             if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL)
366             {
367                 while ((file = ws_dir_read_name(dir)) != NULL)
368                 {
369                     name = ws_dir_get_name(file);
370                     if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
371                         continue;        /* skip "." and ".." */
372                     /*
373                      * Get the full path of a ".libs" subdirectory of that
374                      * directory.
375                      */
376                     plugin_dir_path = g_strdup_printf(
377                         "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs",
378                         plugin_dir, name);
379                     if (test_for_directory(plugin_dir_path) != EISDIR) {
380                         /*
381                          * Either it doesn't refer to a directory or it
382                          * refers to something that doesn't exist.
383                          *
384                          * Assume that means that the plugins are in
385                          * the subdirectory of the plugin directory, not
386                          * a ".libs" subdirectory of that subdirectory.
387                          */
388                         g_free(plugin_dir_path);
389                         plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
390                             plugin_dir, name);
391                     }
392                     plugins_scan_dir(plugin_dir_path);
393                     g_free(plugin_dir_path);
394                 }
395                 ws_dir_close(dir);
396             }
397         }
398         else
399             plugins_scan_dir(plugin_dir);
400
401         /*
402          * If the program wasn't started with special privileges,
403          * scan the users plugin directory.  (Even if we relinquish
404          * them, plugins aren't safe unless we've *permanently*
405          * relinquished them, and we can't do that in Wireshark as,
406          * if we need privileges to start capturing, we'd need to
407          * reclaim them before each time we start capturing.)
408          */
409         if (!started_with_special_privs())
410         {
411             plugins_pers_dir = get_plugins_pers_dir();
412             plugins_scan_dir(plugins_pers_dir);
413             g_free(plugins_pers_dir);
414         }
415     }
416
417     register_all_wiretap_modules();
418     register_all_codecs();
419 }
420
421 void
422 register_all_plugin_registrations(void)
423 {
424     plugin *pt_plug;
425
426     /*
427      * For all plugins with register-handoff routines, call the routines.
428      * This is called from "proto_init()"; it must be called after
429      * "register_all_protocols()" and "init_plugins()" are called,
430      * in case one plugin registers itself either with a built-in
431      * dissector or with another plugin; we must first register all
432      * dissectors, whether built-in or plugin, so their dissector tables
433      * are initialized, and only then register all handoffs.
434      */
435     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
436     {
437         if (pt_plug->register_protoinfo)
438             (pt_plug->register_protoinfo)();
439     }
440 }
441
442 void
443 register_all_plugin_handoffs(void)
444 {
445     plugin *pt_plug;
446
447     /*
448      * For all plugins with register-handoff routines, call the routines.
449      * This is called from "proto_init()"; it must be called after
450      * "register_all_protocols()" and "init_plugins()" are called,
451      * in case one plugin registers itself either with a built-in
452      * dissector or with another plugin; we must first register all
453      * dissectors, whether built-in or plugin, so their dissector tables
454      * are initialized, and only then register all handoffs.
455      */
456     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
457     {
458         if (pt_plug->reg_handoff)
459             (pt_plug->reg_handoff)();
460     }
461 }
462
463 void
464 register_all_plugin_tap_listeners(void)
465 {
466     plugin *pt_plug;
467
468     /*
469      * For all plugins with register-tap-listener routines, call the
470      * routines.
471      */
472     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
473     {
474         if (pt_plug->register_tap_listener)
475             (pt_plug->register_tap_listener)();
476     }
477 }
478
479 static void
480 register_all_wiretap_modules(void)
481 {
482     plugin *pt_plug;
483
484     /*
485      * For all plugins with register_wtap_module routines, call the
486      * routines.
487      */
488     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
489     {
490         if (pt_plug->register_wtap_module)
491             (pt_plug->register_wtap_module)();
492     }
493 }
494
495 static void
496 register_all_codecs(void)
497 {
498     plugin *pt_plug;
499
500     /*
501      * For all plugins with register_wtap_module routines, call the
502      * routines.
503      */
504     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
505     {
506         if (pt_plug->register_codec_module)
507               (pt_plug->register_codec_module)();
508     }
509 }
510
511 #endif  /* big HAVE_PLUGINS */
512
513 /*
514  * Dump plugin info to stdout. Copied from ui/gtk/plugins_dlg.c:plugins_scan.
515  */
516 void
517 plugins_dump_all(void)
518 {
519 #ifdef HAVE_PLUGINS
520     plugin     *pt_plug;
521     const char *sep;
522 #endif
523 #ifdef HAVE_LUA
524     wslua_plugin  *lua_plug;
525 #endif
526
527 #ifdef HAVE_PLUGINS
528     for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
529     {
530         sep = "";
531
532         printf("%s\t%s\t", pt_plug->name, pt_plug->version);
533         if (pt_plug->register_protoinfo)
534         {
535             printf("dissector");
536             sep = ", ";
537         }
538         if (pt_plug->register_tap_listener)
539         {
540             printf("%stap", sep);
541             sep = ", ";
542         }
543         if (pt_plug->register_wtap_module)
544         {
545             printf("%sfile format", sep);
546             sep = ", ";
547         }
548         if (pt_plug->register_codec_module)
549         {
550             printf("%scodec", sep);
551         }
552         printf("\t%s\n", g_module_name(pt_plug->handle));
553     }
554 #endif
555
556 #ifdef HAVE_LUA
557     for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
558     {
559         printf("%s\t%s\tlua script\t%s\n", lua_plug->name, lua_plug->version, lua_plug->filename);
560     }
561 #endif
562 }
563