glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / peerinfo-tool / gnunet-peerinfo_plugins.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2010,2011 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15
16 /**
17  * @file peerinfo-tool/gnunet-peerinfo_plugins.c
18  * @brief plugin management
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet-peerinfo_plugins.h"
23 #include "gnunet_transport_plugin.h"
24 #include "gnunet_hello_lib.h"
25
26 /**
27  * Entry in doubly-linked list of all of our plugins.
28  */
29 struct TransportPlugin
30 {
31   /**
32    * This is a doubly-linked list.
33    */
34   struct TransportPlugin *next;
35
36   /**
37    * This is a doubly-linked list.
38    */
39   struct TransportPlugin *prev;
40
41   /**
42    * API of the transport as returned by the plugin's
43    * initialization function.
44    */
45   struct GNUNET_TRANSPORT_PluginFunctions *api;
46
47   /**
48    * Short name for the plugin (i.e. "tcp").
49    */
50   char *short_name;
51
52   /**
53    * Name of the library (i.e. "gnunet_plugin_transport_tcp").
54    */
55   char *lib_name;
56
57   /**
58    * Environment this transport service is using
59    * for this plugin.
60    */
61   struct GNUNET_TRANSPORT_PluginEnvironment env;
62
63 };
64
65 /**
66  * Head of DLL of all loaded plugins.
67  */
68 static struct TransportPlugin *plugins_head;
69
70 /**
71  * Head of DLL of all loaded plugins.
72  */
73 static struct TransportPlugin *plugins_tail;
74
75
76
77 /**
78  * Load and initialize all plugins.  The respective functions will be
79  * invoked by the plugins when the respective events happen.  The
80  * closure will be set to a 'const char*' containing the name of the
81  * plugin that caused the call.
82  *
83  * @param cfg configuration to use
84  */
85 void
86 GPI_plugins_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
87 {
88   struct TransportPlugin *plug;
89   struct TransportPlugin *next;
90   char *libname;
91   char *plugs;
92   char *pos;
93
94   if (NULL != plugins_head)
95     return; /* already loaded */
96   if (GNUNET_OK !=
97       GNUNET_CONFIGURATION_get_value_string (cfg, "TRANSPORT", "PLUGINS",
98                                              &plugs))
99     return;
100   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting transport plugins `%s'\n"),
101               plugs);
102   for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " "))
103   {
104     GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' transport plugin\n"),
105                 pos);
106     GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", pos);
107     plug = GNUNET_new (struct TransportPlugin);
108     plug->short_name = GNUNET_strdup (pos);
109     plug->lib_name = libname;
110     plug->env.cfg = cfg;
111     plug->env.cls = plug->short_name;
112     GNUNET_CONTAINER_DLL_insert (plugins_head, plugins_tail, plug);
113   }
114   GNUNET_free (plugs);
115   next = plugins_head;
116   while (next != NULL)
117   {
118     plug = next;
119     next = plug->next;
120     plug->api = GNUNET_PLUGIN_load (plug->lib_name, &plug->env);
121     if (plug->api == NULL)
122     {
123       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
124                   _("Failed to load transport plugin for `%s'\n"),
125                   plug->lib_name);
126       GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug);
127       GNUNET_free (plug->short_name);
128       GNUNET_free (plug->lib_name);
129       GNUNET_free (plug);
130     }
131   }
132 }
133
134
135 /**
136  * Unload all plugins
137  */
138 void
139 GPI_plugins_unload ()
140 {
141   struct TransportPlugin *plug;
142
143   while (NULL != (plug = plugins_head))
144   {
145     GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
146     GNUNET_free (plug->lib_name);
147     GNUNET_free (plug->short_name);
148     GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug);
149     GNUNET_free (plug);
150   }
151 }
152
153
154 /**
155  * Obtain the plugin API based on a plugin name.
156  *
157  * @param name name of the plugin
158  * @return the plugin's API, NULL if the plugin is not loaded
159  */
160 struct GNUNET_TRANSPORT_PluginFunctions *
161 GPI_plugins_find (const char *name)
162 {
163   struct TransportPlugin *head = plugins_head;
164
165   char *stripped = GNUNET_strdup (name);
166   char *head_stripped;
167   char *sep = strchr (stripped, '_');
168   if (NULL != sep)
169     sep[0] = '\0';
170
171   while (head != NULL)
172   {
173         head_stripped = GNUNET_strdup(head->short_name);
174     char *head_sep = strchr (head_stripped, '_');
175     if (NULL != head_sep)
176         head_sep[0] = '\0';
177     if (0 == strcmp (head_stripped, stripped))
178     {
179         GNUNET_free (head_stripped);
180       break;
181     }
182     GNUNET_free (head_stripped);
183     head = head->next;
184   }
185   GNUNET_free (stripped);
186   if (NULL == head)
187     return NULL;
188   return head->api;
189 }
190
191
192 /* end of file gnunet-peerinfo_plugins.c */