59eac50748764bbeff5ae93b59d59d1aefb6e2a6
[oonf.git] / lib / httptelnet / src / httptelnet.c
1 /*
2  * httptelnet.c
3  *
4  *  Created on: Oct 7, 2011
5  *      Author: rogge
6  */
7
8 #include "common/common_types.h"
9 #include "common/autobuf.h"
10
11 #include "config/cfg_schema.h"
12 #include "olsr_cfg.h"
13 #include "olsr_http.h"
14 #include "olsr_logging.h"
15 #include "olsr_plugins.h"
16 #include "olsr_telnet.h"
17 #include "olsr.h"
18
19 /* constants */
20 #define _CFG_SECTION "httptelnet"
21
22 static const char *_HTTP_PATH = "/telnet";
23
24 /* prototypes */
25 static int _cb_plugin_load(void);
26 static int _cb_plugin_unload(void);
27 static int _cb_plugin_enable(void);
28 static int _cb_plugin_disable(void);
29
30 static enum olsr_http_result _cb_generate_site(
31     struct autobuf *out, struct olsr_http_session *);
32
33 static void _cb_config_changed(void);
34
35 /* html handler */
36 struct olsr_http_handler _http_site_handler = {
37   .content_handler = _cb_generate_site,
38 };
39
40 /* plugin declaration */
41 OLSR_PLUGIN7 {
42   .descr = "OLSRD http2telnet bridge plugin",
43   .author = "Henning Rogge",
44
45   .load = _cb_plugin_load,
46   .unload = _cb_plugin_unload,
47   .enable = _cb_plugin_enable,
48   .disable = _cb_plugin_disable,
49
50   .deactivate = true,
51 };
52
53 /* configuration */
54 static struct cfg_schema_section _httptelnet_section = {
55   .type = _CFG_SECTION,
56   .cb_delta_handler = _cb_config_changed,
57 };
58
59 static struct cfg_schema_entry _httptelnet_entries[] = {
60   CFG_MAP_STRING(olsr_http_handler, site, "site", "/telnet", "Path for http2telnet bridge"),
61   CFG_MAP_ACL(olsr_http_handler, acl, "acl", "default_accept", "acl for http2telnet bridge"),
62   CFG_MAP_STRINGLIST(olsr_http_handler, auth, "auth", "", "TODO"),
63 };
64
65 static const char *_last_site;
66
67 /**
68  * Constructor of plugin
69  * @return 0 if initialization was successful, -1 otherwise
70  */
71 static int
72 _cb_plugin_load(void) {
73   _http_site_handler.site = strdup(_HTTP_PATH);
74   if (_http_site_handler.site == NULL) {
75     return -1;
76   }
77
78   _last_site = _http_site_handler.site;
79
80   cfg_schema_add_section(olsr_cfg_get_schema(), &_httptelnet_section,
81       _httptelnet_entries, ARRAYSIZE(_httptelnet_entries));
82
83   olsr_acl_add(&_http_site_handler.acl);
84   strarray_init(&_http_site_handler.auth);
85
86   return 0;
87 }
88
89 /**
90  * Destructor of plugin
91  * @return always returns 0 (cannot fail)
92  */
93 static int
94 _cb_plugin_unload(void) {
95   strarray_free(&_http_site_handler.auth);
96   olsr_acl_remove(&_http_site_handler.acl);
97   free((char *)_http_site_handler.site);
98
99   cfg_schema_remove_section(olsr_cfg_get_schema(), &_httptelnet_section);
100   return 0;
101 }
102
103 /**
104  * Enable plugin
105  * @return always returns 0 (cannot fail)
106  */
107 static int
108 _cb_plugin_enable(void) {
109   olsr_http_add(&_http_site_handler);
110   return 0;
111 }
112
113 /**
114  * Disable plugin
115  * @return always returns 0 (cannot fail)
116  */
117 static int
118 _cb_plugin_disable(void) {
119   olsr_http_remove(&_http_site_handler);
120   return 0;
121 }
122
123 /**
124  * Callback for generating a http site from the output of the
125  * triggered telnet command
126  * @param out pointer to output buffer
127  * @param session pointer to http session
128  * @return http result code
129  */
130 static enum olsr_http_result
131 _cb_generate_site(struct autobuf *out, struct olsr_http_session *session) {
132   const char *command, *param;
133
134   command = olsr_http_lookup_param(session, "c");
135   param = olsr_http_lookup_param(session, "p");
136
137   if (command == NULL) {
138     return HTTP_404_NOT_FOUND;
139   }
140
141   switch (olsr_telnet_execute(command, param, out, session->remote)) {
142     case TELNET_RESULT_ACTIVE:
143     case TELNET_RESULT_QUIT:
144       session->content_type = HTTP_CONTENTTYPE_TEXT;
145       return HTTP_200_OK;
146
147     case TELNET_RESULT_UNKNOWN_COMMAND:
148       return HTTP_404_NOT_FOUND;
149
150     default:
151       return HTTP_400_BAD_REQ;
152   }
153 }
154
155 /**
156  * Update configuration of remotecontrol plugin
157  */
158 static void
159 _cb_config_changed(void) {
160   if (cfg_schema_tobin(&_http_site_handler, _httptelnet_section.post,
161       _httptelnet_entries, ARRAYSIZE(_httptelnet_entries))) {
162     OLSR_WARN(LOG_CONFIG, "Could not convert httptelnet config to bin");
163     return;
164   }
165
166   if (_http_site_handler.site != _last_site) {
167     _last_site = _http_site_handler.site;
168
169     _cb_plugin_disable();
170     _cb_plugin_enable();
171   }
172 }