uncrustify as demanded.
[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      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file peerinfo-tool/gnunet-peerinfo_plugins.c
23  * @brief plugin management
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet-peerinfo_plugins.h"
28 #include "gnunet_transport_plugin.h"
29 #include "gnunet_hello_lib.h"
30
31 /**
32  * Entry in doubly-linked list of all of our plugins.
33  */
34 struct TransportPlugin {
35   /**
36    * This is a doubly-linked list.
37    */
38   struct TransportPlugin *next;
39
40   /**
41    * This is a doubly-linked list.
42    */
43   struct TransportPlugin *prev;
44
45   /**
46    * API of the transport as returned by the plugin's
47    * initialization function.
48    */
49   struct GNUNET_TRANSPORT_PluginFunctions *api;
50
51   /**
52    * Short name for the plugin (i.e. "tcp").
53    */
54   char *short_name;
55
56   /**
57    * Name of the library (i.e. "gnunet_plugin_transport_tcp").
58    */
59   char *lib_name;
60
61   /**
62    * Environment this transport service is using
63    * for this plugin.
64    */
65   struct GNUNET_TRANSPORT_PluginEnvironment env;
66 };
67
68 /**
69  * Head of DLL of all loaded plugins.
70  */
71 static struct TransportPlugin *plugins_head;
72
73 /**
74  * Head of DLL of all loaded plugins.
75  */
76 static struct TransportPlugin *plugins_tail;
77
78
79
80 /**
81  * Load and initialize all plugins.  The respective functions will be
82  * invoked by the plugins when the respective events happen.  The
83  * closure will be set to a 'const char*' containing the name of the
84  * plugin that caused the call.
85  *
86  * @param cfg configuration to use
87  */
88 void
89 GPI_plugins_load(const struct GNUNET_CONFIGURATION_Handle *cfg)
90 {
91   struct TransportPlugin *plug;
92   struct TransportPlugin *next;
93   char *libname;
94   char *plugs;
95   char *pos;
96
97   if (NULL != plugins_head)
98     return; /* already loaded */
99   if (GNUNET_OK !=
100       GNUNET_CONFIGURATION_get_value_string(cfg, "TRANSPORT", "PLUGINS",
101                                             &plugs))
102     return;
103   GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Starting transport plugins `%s'\n"),
104              plugs);
105   for (pos = strtok(plugs, " "); pos != NULL; pos = strtok(NULL, " "))
106     {
107       GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Loading `%s' transport plugin\n"),
108                  pos);
109       GNUNET_asprintf(&libname, "libgnunet_plugin_transport_%s", pos);
110       plug = GNUNET_new(struct TransportPlugin);
111       plug->short_name = GNUNET_strdup(pos);
112       plug->lib_name = libname;
113       plug->env.cfg = cfg;
114       plug->env.cls = plug->short_name;
115       GNUNET_CONTAINER_DLL_insert(plugins_head, plugins_tail, plug);
116     }
117   GNUNET_free(plugs);
118   next = plugins_head;
119   while (next != NULL)
120     {
121       plug = next;
122       next = plug->next;
123       plug->api = GNUNET_PLUGIN_load(plug->lib_name, &plug->env);
124       if (plug->api == NULL)
125         {
126           GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
127                      _("Failed to load transport plugin for `%s'\n"),
128                      plug->lib_name);
129           GNUNET_CONTAINER_DLL_remove(plugins_head, plugins_tail, plug);
130           GNUNET_free(plug->short_name);
131           GNUNET_free(plug->lib_name);
132           GNUNET_free(plug);
133         }
134     }
135 }
136
137
138 /**
139  * Unload all plugins
140  */
141 void
142 GPI_plugins_unload()
143 {
144   struct TransportPlugin *plug;
145
146   while (NULL != (plug = plugins_head))
147     {
148       GNUNET_break(NULL == GNUNET_PLUGIN_unload(plug->lib_name, plug->api));
149       GNUNET_free(plug->lib_name);
150       GNUNET_free(plug->short_name);
151       GNUNET_CONTAINER_DLL_remove(plugins_head, plugins_tail, plug);
152       GNUNET_free(plug);
153     }
154 }
155
156
157 /**
158  * Obtain the plugin API based on a plugin name.
159  *
160  * @param name name of the plugin
161  * @return the plugin's API, NULL if the plugin is not loaded
162  */
163 struct GNUNET_TRANSPORT_PluginFunctions *
164 GPI_plugins_find(const char *name)
165 {
166   struct TransportPlugin *head = plugins_head;
167
168   char *stripped = GNUNET_strdup(name);
169   char *head_stripped;
170   char *sep = strchr(stripped, '_');
171
172   if (NULL != sep)
173     sep[0] = '\0';
174
175   while (head != NULL)
176     {
177       head_stripped = GNUNET_strdup(head->short_name);
178       char *head_sep = strchr(head_stripped, '_');
179       if (NULL != head_sep)
180         head_sep[0] = '\0';
181       if (0 == strcmp(head_stripped, stripped))
182         {
183           GNUNET_free(head_stripped);
184           break;
185         }
186       GNUNET_free(head_stripped);
187       head = head->next;
188     }
189   GNUNET_free(stripped);
190   if (NULL == head)
191     return NULL;
192   return head->api;
193 }
194
195
196 /* end of file gnunet-peerinfo_plugins.c */