2
Copyright (C) 2010-2011 wpitchoune@gmail.com
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2
* Copyright (C) 2010-2011 jeanfi@gmail.com
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of the
7
* License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
19
#include <locale.h>
20
20
#include <libintl.h>
21
21
#define _(str) gettext(str)
39
40
#include "sysinfo.h"
43
#include "server_lua.h"
46
44
#include "psensor_json.h"
48
#include "plib/plib_io.h"
49
47
#include "server.h"
51
49
static const char *program_name;
53
51
#define DEFAULT_PORT 3131
55
#define PAGE_NOT_FOUND \
56
"<html><body><p>Page not found - Go to <a href='/index.lua'>Main page</a>\
53
#define PAGE_NOT_FOUND (_("<html><body><p>"\
54
"Page not found - Go to <a href='/'>Main page</a></p></body>"))
59
56
static struct option long_options[] = {
60
57
{"version", no_argument, 0, 'v'},
61
58
{"help", no_argument, 0, 'h'},
62
59
{"port", required_argument, 0, 'p'},
63
60
{"wdir", required_argument, 0, 'w'},
61
{"debug", no_argument, 0, 'd'},
69
67
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
71
static int server_stop_requested;
71
73
void print_version()
73
75
printf("psensor-server %s\n", VERSION);
74
printf(_("Copyright (C) %s wpitchoune@gmail.com\n\
75
License GPLv2: GNU GPL version 2 or later \
76
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n\
77
This is free software: you are free to change and redistribute it.\n\
78
There is NO WARRANTY, to the extent permitted by law.\n"),
76
printf(_("Copyright (C) %s jeanfi@gmail.com\n"
77
"License GPLv2: GNU GPL version 2 or later "
78
"<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
79
"This is free software: you are free to change and redistribute it.\n"
80
"There is NO WARRANTY, to the extent permitted by law.\n"),
92
-h, --help display this help and exit\n\
93
-v, --version display version information and exit"));
93
puts(_(" -h, --help display this help and exit\n"
94
" -v, --version display version information and exit"));
98
-p,--port=PORT webserver port\n\
99
-w,--wdir=DIR directory containing webserver pages"));
98
puts(_(" -d,--debug run in debug mode\n"
99
" -p,--port=PORT webserver port\n"
100
" -w,--wdir=DIR directory containing webserver pages"));
142
static int cbk_http_request(void *cls,
143
struct MHD_Connection *connection,
147
const char *upload_data,
148
size_t *upload_data_size, void **ptr)
130
#if MHD_VERSION >= 0x00090200
132
file_reader(void *cls, uint64_t pos, char *buf, size_t max)
135
file_reader(void *cls, uint64_t pos, char *buf, int max)
140
fseek(file, pos, SEEK_SET);
141
return fread(buf, 1, max, file);
144
struct MHD_Response *
145
create_response_api(const char *nurl,
147
unsigned int *rp_code)
149
struct MHD_Response *resp;
153
if (!strcmp(nurl, URL_BASE_API_1_0_SENSORS)) {
154
page = sensors_to_json_string(server_data.sensors);
156
} else if (!strcmp(nurl, URL_API_1_0_SYSINFO)) {
157
page = sysinfo_to_json_string(&server_data.psysinfo);
158
} else if (!strcmp(nurl, URL_API_1_0_CPU_USAGE)) {
159
page = sensor_to_json_string(server_data.cpu_usage);
161
} else if (!strncmp(nurl, URL_BASE_API_1_0_SENSORS,
162
strlen(URL_BASE_API_1_0_SENSORS))
163
&& nurl[strlen(URL_BASE_API_1_0_SENSORS)] == '/') {
165
const char *sid = nurl + strlen(URL_BASE_API_1_0_SENSORS) + 1;
167
s = psensor_list_get_by_id(server_data.sensors, sid);
170
page = sensor_to_json_string(s);
172
} else if (debug && !strcmp(nurl, URL_API_1_0_SERVER_STOP)) {
174
server_stop_requested = 1;
175
page = strdup(_("<html><body><p>"
176
"Server stop requested</p></body></html>"));
180
*rp_code = MHD_HTTP_OK;
182
resp = MHD_create_response_from_data(strlen(page), page,
185
MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE,
194
struct MHD_Response *
195
create_response_file(const char *nurl,
197
unsigned int *rp_code,
204
ret = stat(fpath, &st);
206
if (!ret && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) {
207
file = fopen(fpath, "rb");
210
*rp_code = MHD_HTTP_OK;
214
return MHD_create_response_from_data
215
(0, NULL, MHD_NO, MHD_NO);
218
return MHD_create_response_from_callback
223
(MHD_ContentReaderFreeCallback)&fclose);
226
log_printf(LOG_ERR, "Failed to open: %s\n", fpath);
233
struct MHD_Response *
234
create_response(const char *nurl, const char *method, unsigned int *rp_code)
236
struct MHD_Response *resp = NULL;
238
if (!strncmp(nurl, URL_BASE_API_1_0, strlen(URL_BASE_API_1_0))) {
239
resp = create_response_api(nurl, method, rp_code);
241
char *fpath = get_path(nurl, server_data.www_dir);
243
resp = create_response_file(nurl, method, rp_code, fpath);
251
char *page = strdup(PAGE_NOT_FOUND);
252
*rp_code = MHD_HTTP_NOT_FOUND;
254
return MHD_create_response_from_data
255
(strlen(page), page, MHD_YES, MHD_NO);
260
cbk_http_request(void *cls,
261
struct MHD_Connection *connection,
265
const char *upload_data,
266
size_t *upload_data_size, void **ptr)
150
268
static int dummy;
151
269
struct MHD_Response *response;
154
272
unsigned int resp_code;
157
274
if (strcmp(method, "GET"))
158
return MHD_NO; /* unexpected method */
160
277
if (&dummy != *ptr) {
161
278
/* The first time only the headers are valid, do not
167
284
if (*upload_data_size)
168
return MHD_NO; /* upload data in a GET!? */
170
287
*ptr = NULL; /* clear context pointer */
290
printf(_("HTTP Request: %s\n"), url);
172
292
nurl = url_normalize(url);
174
294
pthread_mutex_lock(&mutex);
176
if (!strcmp(nurl, URL_BASE_API_1_0_SENSORS)) {
177
page = sensors_to_json_string(server_data.sensors);
179
} else if (!strncmp(nurl, URL_BASE_API_1_0_SENSORS,
180
strlen(URL_BASE_API_1_0_SENSORS))
181
&& nurl[strlen(URL_BASE_API_1_0_SENSORS)] == '/') {
183
char *sid = nurl + strlen(URL_BASE_API_1_0_SENSORS) + 1;
185
= psensor_list_get_by_id(server_data.sensors, sid);
188
page = sensor_to_json_string(s);
191
char *fpath = get_path(nurl, server_data.www_dir);
192
int n = strlen(nurl);
194
if (is_path_lua(fpath)) {
196
page = lua_to_html_page(&server_data, fpath);
198
page = strdup(_("ERROR: Lua support not enabled\n"));
201
page = file_get_content(fpath);
208
resp_code = MHD_HTTP_OK;
210
page = strdup(PAGE_NOT_FOUND);
211
resp_code = MHD_HTTP_NOT_FOUND;
295
response = create_response(nurl, method, &resp_code);
214
296
pthread_mutex_unlock(&mutex);
216
response = MHD_create_response_from_data(strlen(page),
217
(void *)page, MHD_YES, MHD_NO);
219
298
ret = MHD_queue_response(connection, resp_code, response);
220
299
MHD_destroy_response(response);
290
374
exit(EXIT_FAILURE);
293
printf(_("Web server started on port: %d\n"), port);
294
printf(_("WWW directory: %s\n"), server_data.www_dir);
295
printf(_("URL: http://localhost:%d\n"), port);
377
log_printf(LOG_INFO, _("Web server started on port: %d"), port);
378
log_printf(LOG_INFO, _("WWW directory: %s"), server_data.www_dir);
379
log_printf(LOG_INFO, _("URL: http://localhost:%d"), port);
381
while (!server_stop_requested) {
298
382
pthread_mutex_lock(&mutex);
301
sysinfo_update(&server_data.cpu_rate);
385
sysinfo_update(&server_data.psysinfo);
386
cpu_usage_sensor_update(server_data.cpu_usage);
303
388
psensor_list_update_measures(server_data.sensors);