More work on API dependencies
[oonf.git] / src-plugins / plugin_controller / plugin_controller.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2013, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #include "common/common_types.h"
43 #include "common/autobuf.h"
44 #include "common/netaddr.h"
45 #include "common/netaddr_acl.h"
46 #include "config/cfg_schema.h"
47 #include "core/olsr_logging.h"
48 #include "core/olsr_plugins.h"
49 #include "core/olsr_subsystem.h"
50
51 #include "tools/olsr_cfg.h"
52 #include "tools/olsr_telnet.h"
53
54 #include "plugin_controller/plugin_controller.h"
55
56 /* definitions */
57 struct _acl_config {
58   struct netaddr_acl acl;
59 };
60
61 /* prototypes */
62 static int _init(void);
63 static void _cleanup(void);
64
65 static enum olsr_telnet_result _cb_telnet_plugin(struct olsr_telnet_data *data);
66 static void _cb_config_changed(void);
67
68 struct olsr_telnet_command _telnet_commands[] = {
69   TELNET_CMD("plugin", _cb_telnet_plugin,
70         "control plugins dynamically, parameters are 'list',"
71         "'load <plugin>' and 'unload <plugin>'"),
72 };
73
74 /* configuration */
75 static struct cfg_schema_entry _plugin_controller_entries[] = {
76   CFG_MAP_ACL(_acl_config, acl, "acl", "+127.0.0.1 " ACL_DEFAULT_REJECT, "acl for plugin controller"),
77 };
78
79 static struct cfg_schema_section _plugin_controller_section = {
80   .type = OONF_PLUGIN_GET_NAME(),
81   .cb_delta_handler = _cb_config_changed,
82   .entries = _plugin_controller_entries,
83   .entry_count = ARRAYSIZE(_plugin_controller_entries),
84 };
85
86 struct _acl_config _config;
87
88 /* plugin declaration */
89 struct oonf_subsystem oonf_plugin_controller_subsystem = {
90   .name = OONF_PLUGIN_GET_NAME(),
91   .descr = "OLSRD plugin controller plugin",
92   .author = "Henning Rogge",
93
94   .cfg_section = &_plugin_controller_section,
95
96   .init = _init,
97   .cleanup = _cleanup,
98 };
99 DECLARE_OONF_PLUGIN(oonf_plugin_controller_subsystem);
100
101 /**
102  * Constructor of plugin
103  * @return 0 if initialization was successful, -1 otherwise
104  */
105 static int
106 _init(void) {
107   netaddr_acl_add(&_config.acl);
108   _telnet_commands[0].acl = &_config.acl;
109
110   olsr_telnet_add(&_telnet_commands[0]);
111   return 0;
112 }
113
114 /**
115  * Destructor of plugin
116  */
117 static void
118 _cleanup(void) {
119   olsr_telnet_remove(&_telnet_commands[0]);
120   netaddr_acl_remove(&_config.acl);
121 }
122
123 /**
124  * Telnet command 'plugin'
125  * @param data pointer to telnet data
126  * @return telnet command result
127  */
128 static enum olsr_telnet_result
129 _cb_telnet_plugin(struct olsr_telnet_data *data) {
130   struct oonf_subsystem *plugin;
131   const char *plugin_name = NULL;
132
133   if (data->parameter == NULL || strcasecmp(data->parameter, "list") == 0) {
134     abuf_puts(data->out, "Plugins:\n");
135
136     avl_for_each_element(&olsr_plugin_tree, plugin, _node) {
137       abuf_appendf(data->out, "\t%s\n", plugin->name);
138     }
139     return TELNET_RESULT_ACTIVE;
140   }
141
142   plugin_name = strchr(data->parameter, ' ');
143   if (plugin_name == NULL) {
144     abuf_appendf(data->out, "Error, missing or unknown parameter\n");
145   }
146
147   /* skip whitespaces */
148   while (isspace(*plugin_name)) {
149     plugin_name++;
150   }
151
152   plugin = olsr_plugins_get(plugin_name);
153   if (str_hasnextword(data->parameter, "load") == NULL) {
154     if (plugin != NULL) {
155       abuf_appendf(data->out, "Plugin %s already loaded\n", plugin_name);
156       return TELNET_RESULT_ACTIVE;
157     }
158     plugin = olsr_plugins_load(plugin_name);
159     if (plugin != NULL) {
160       abuf_appendf(data->out, "Plugin %s successfully loaded\n", plugin_name);
161     }
162     else {
163       abuf_appendf(data->out, "Could not load plugin %s\n", plugin_name);
164     }
165     return TELNET_RESULT_ACTIVE;
166   }
167
168   if (plugin == NULL) {
169     abuf_appendf(data->out, "Error, could not find plugin '%s'.\n", plugin_name);
170     return TELNET_RESULT_ACTIVE;
171   }
172
173   if (str_hasnextword(data->parameter, "unload") == NULL) {
174     if (olsr_plugins_unload(plugin)) {
175       abuf_appendf(data->out, "Could not unload plugin %s\n", plugin_name);
176     }
177     else {
178       abuf_appendf(data->out, "Plugin %s successfully unloaded\n", plugin_name);
179     }
180     return TELNET_RESULT_ACTIVE;
181   }
182
183   abuf_appendf(data->out, "Unknown command '%s %s %s'.\n",
184       data->command, data->parameter, plugin_name);
185   return TELNET_RESULT_ACTIVE;
186 }
187
188 /**
189  * Handler for configuration changes
190  */
191 static void
192 _cb_config_changed(void) {
193   /* generate binary config */
194   cfg_schema_tobin(&_config, _plugin_controller_section.post,
195       _plugin_controller_entries, ARRAYSIZE(_plugin_controller_entries));
196 }