mirror of
https://github.com/SuperBFG7/ympd
synced 2025-07-04 19:12:48 +00:00
Fix: no global state in web_server.c
This commit is contained in:
parent
4c086da611
commit
8634a52194
@ -27,6 +27,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
int randrange(int n) {
|
||||||
|
return rand() / (RAND_MAX / (n + 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
void sanitize_string(const char *data) {
|
void sanitize_string(const char *data) {
|
||||||
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
|
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
@ -99,6 +99,7 @@ typedef struct {
|
|||||||
t_config config;
|
t_config config;
|
||||||
|
|
||||||
//global functions
|
//global functions
|
||||||
|
int randrange(int n);
|
||||||
void sanitize_string(const char *data);
|
void sanitize_string(const char *data);
|
||||||
int copy_string(char * const dest, char const * const src, size_t const dst_len, size_t const src_len);
|
int copy_string(char * const dest, char const * const src, size_t const dst_len, size_t const src_len);
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,7 +81,7 @@ int list_shuffle(struct list *l) {
|
|||||||
if (l->length < 2)
|
if (l->length < 2)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
// srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
struct node *current = l->list;
|
struct node *current = l->list;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
|
31
src/main.c
31
src/main.c
@ -38,6 +38,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
#include "web_server.h"
|
#include "web_server.h"
|
||||||
|
#include "../dist/src/mongoose/mongoose.h"
|
||||||
|
|
||||||
static void signal_handler(int sig_num) {
|
static void signal_handler(int sig_num) {
|
||||||
signal(sig_num, signal_handler); // Reinstantiate signal handler
|
signal(sig_num, signal_handler); // Reinstantiate signal handler
|
||||||
@ -297,7 +298,7 @@ bool testdir(char *name, char *dirname) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *mpd_client_thread() {
|
void *mpd_client_loop() {
|
||||||
while (s_signal_received == 0) {
|
while (s_signal_received == 0) {
|
||||||
mpd_client_idle(100);
|
mpd_client_idle(100);
|
||||||
}
|
}
|
||||||
@ -310,7 +311,8 @@ int main(int argc, char **argv) {
|
|||||||
char testdirname[400];
|
char testdirname[400];
|
||||||
mpd_client_queue = tiny_queue_create();
|
mpd_client_queue = tiny_queue_create();
|
||||||
web_server_queue = tiny_queue_create();
|
web_server_queue = tiny_queue_create();
|
||||||
//mympd_queue = tiny_queue_create();
|
|
||||||
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
//defaults
|
//defaults
|
||||||
config.mpdhost = "127.0.0.1";
|
config.mpdhost = "127.0.0.1";
|
||||||
@ -380,36 +382,36 @@ int main(int argc, char **argv) {
|
|||||||
setvbuf(stderr, NULL, _IOLBF, 0);
|
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
//init webserver
|
//init webserver
|
||||||
if (!web_server_init()) {
|
struct mg_mgr mgr;
|
||||||
|
if (!web_server_init(&mgr)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//drop privileges
|
//drop privileges
|
||||||
if (config.user != NULL) {
|
if (config.user != NULL) {
|
||||||
LOG_INFO() printf("Droping privileges to %s\n", config.user);
|
LOG_INFO() printf("Droping privileges to %s\n", config.user);
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
if ((pw = getpwnam(config.user)) == NULL) {
|
if ((pw = getpwnam(config.user)) == NULL) {
|
||||||
printf("getpwnam() failed, unknown user\n");
|
printf("getpwnam() failed, unknown user\n");
|
||||||
web_server_free();
|
web_server_free(&mgr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setgroups(0, NULL) != 0) {
|
} else if (setgroups(0, NULL) != 0) {
|
||||||
printf("setgroups() failed\n");
|
printf("setgroups() failed\n");
|
||||||
web_server_free();
|
web_server_free(&mgr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setgid(pw->pw_gid) != 0) {
|
} else if (setgid(pw->pw_gid) != 0) {
|
||||||
printf("setgid() failed\n");
|
printf("setgid() failed\n");
|
||||||
web_server_free();
|
web_server_free(&mgr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setuid(pw->pw_uid) != 0) {
|
} else if (setuid(pw->pw_uid) != 0) {
|
||||||
printf("setuid() failed\n");
|
printf("setuid() failed\n");
|
||||||
web_server_free();
|
web_server_free(&mgr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() == 0) {
|
if (getuid() == 0) {
|
||||||
printf("myMPD should not be run with root privileges\n");
|
printf("myMPD should not be run with root privileges\n");
|
||||||
web_server_free();
|
web_server_free(&mgr);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,22 +458,21 @@ int main(int argc, char **argv) {
|
|||||||
LOG_INFO() printf("Reading last played songs: %d\n", read_last_played());
|
LOG_INFO() printf("Reading last played songs: %d\n", read_last_played());
|
||||||
|
|
||||||
//Create working threads
|
//Create working threads
|
||||||
pthread_t mpd_client, web_server;
|
pthread_t mpd_client_thread, web_server_thread;
|
||||||
//mpd connection
|
//mpd connection
|
||||||
pthread_create(&mpd_client, NULL, mpd_client_thread, NULL);
|
pthread_create(&mpd_client_thread, NULL, mpd_client_loop, NULL);
|
||||||
//webserver
|
//webserver
|
||||||
pthread_create(&web_server, NULL, web_server_thread, NULL);
|
pthread_create(&web_server_thread, NULL, web_server_loop, &mgr);
|
||||||
|
|
||||||
//Do nothing...
|
//Do nothing...
|
||||||
|
|
||||||
|
|
||||||
//clean up
|
//clean up
|
||||||
pthread_join(mpd_client, NULL);
|
pthread_join(mpd_client_thread, NULL);
|
||||||
pthread_join(web_server, NULL);
|
pthread_join(web_server_thread, NULL);
|
||||||
list_free(&mpd_tags);
|
list_free(&mpd_tags);
|
||||||
list_free(&mympd_tags);
|
list_free(&mympd_tags);
|
||||||
tiny_queue_free(web_server_queue);
|
tiny_queue_free(web_server_queue);
|
||||||
tiny_queue_free(mpd_client_queue);
|
tiny_queue_free(mpd_client_queue);
|
||||||
//tiny_queue_free(mympd_queue);
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1362,7 +1362,7 @@ bool mpd_client_jukebox() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
//srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
struct list add_list;
|
struct list add_list;
|
||||||
list_init(&add_list);
|
list_init(&add_list);
|
||||||
@ -1482,10 +1482,6 @@ bool mpd_client_jukebox() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int randrange(int n) {
|
|
||||||
return rand() / (RAND_MAX / (n + 1) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mpd_client_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) {
|
int mpd_client_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) {
|
||||||
struct mpd_status *status;
|
struct mpd_status *status;
|
||||||
const struct mpd_audio_format *audioformat;
|
const struct mpd_audio_format *audioformat;
|
||||||
|
@ -191,7 +191,6 @@ typedef struct {
|
|||||||
t_mympd_state mympd_state;
|
t_mympd_state mympd_state;
|
||||||
tiny_queue_t *mpd_client_queue;
|
tiny_queue_t *mpd_client_queue;
|
||||||
|
|
||||||
int randrange(int n);
|
|
||||||
void mpd_client_idle(int timeout);
|
void mpd_client_idle(int timeout);
|
||||||
void mpd_client_parse_idle(int idle_bitmask);
|
void mpd_client_parse_idle(int idle_bitmask);
|
||||||
void mpd_client_api(struct work_request_t *request);
|
void mpd_client_api(struct work_request_t *request);
|
||||||
|
@ -28,10 +28,6 @@
|
|||||||
#include "../dist/src/mongoose/mongoose.h"
|
#include "../dist/src/mongoose/mongoose.h"
|
||||||
|
|
||||||
//non-api definitions
|
//non-api definitions
|
||||||
static unsigned long s_next_id = 1;
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
static struct mg_serve_http_opts s_http_server_opts;
|
|
||||||
|
|
||||||
static int is_websocket(const struct mg_connection *nc);
|
static int is_websocket(const struct mg_connection *nc);
|
||||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data);
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data);
|
||||||
static void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data);
|
static void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data);
|
||||||
@ -39,19 +35,20 @@ static void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response);
|
|||||||
static void send_api_response(struct mg_mgr *mgr, struct work_result_t *response);
|
static void send_api_response(struct mg_mgr *mgr, struct work_result_t *response);
|
||||||
|
|
||||||
//api functions
|
//api functions
|
||||||
bool web_server_init() {
|
bool web_server_init(void *arg) {
|
||||||
|
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
||||||
struct mg_connection *nc;
|
struct mg_connection *nc;
|
||||||
struct mg_connection *nc_http;
|
struct mg_connection *nc_http;
|
||||||
struct mg_bind_opts bind_opts;
|
struct mg_bind_opts bind_opts;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
mg_mgr_init(&mgr, NULL);
|
mg_mgr_init(mgr, NULL);
|
||||||
|
|
||||||
if (config.ssl == true) {
|
if (config.ssl == true) {
|
||||||
nc_http = mg_bind(&mgr, config.webport, ev_handler_redirect);
|
nc_http = mg_bind(mgr, config.webport, ev_handler_redirect);
|
||||||
if (nc_http == NULL) {
|
if (nc_http == NULL) {
|
||||||
printf("Error listening on port %s\n", config.webport);
|
printf("Error listening on port %s\n", config.webport);
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(mgr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mg_set_protocol_http_websocket(nc_http);
|
mg_set_protocol_http_websocket(nc_http);
|
||||||
@ -61,51 +58,52 @@ bool web_server_init() {
|
|||||||
bind_opts.ssl_cert = config.sslcert;
|
bind_opts.ssl_cert = config.sslcert;
|
||||||
bind_opts.ssl_key = config.sslkey;
|
bind_opts.ssl_key = config.sslkey;
|
||||||
bind_opts.error_string = &err;
|
bind_opts.error_string = &err;
|
||||||
nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts);
|
nc = mg_bind_opt(mgr, config.sslport, ev_handler, bind_opts);
|
||||||
if (nc == NULL) {
|
if (nc == NULL) {
|
||||||
printf("Error listening on port %s: %s\n", config.sslport, err);
|
printf("Error listening on port %s: %s\n", config.sslport, err);
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(mgr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOG_INFO() printf("Listening on ssl port %s\n", config.sslport);
|
LOG_INFO() printf("Listening on ssl port %s\n", config.sslport);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nc = mg_bind(&mgr, config.webport, ev_handler);
|
nc = mg_bind(mgr, config.webport, ev_handler);
|
||||||
if (nc == NULL) {
|
if (nc == NULL) {
|
||||||
printf("Error listening on port %s\n", config.webport);
|
printf("Error listening on port %s\n", config.webport);
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(mgr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOG_INFO() printf("Listening on http port %s\n", config.webport);
|
LOG_INFO() printf("Listening on http port %s\n", config.webport);
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_set_protocol_http_websocket(nc);
|
mg_set_protocol_http_websocket(nc);
|
||||||
s_http_server_opts.document_root = DOC_ROOT;
|
|
||||||
s_http_server_opts.enable_directory_listing = "no";
|
return mgr;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void web_server_free() {
|
void web_server_free(void *arg) {
|
||||||
mg_mgr_free(&mgr);
|
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
||||||
|
mg_mgr_free(mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *web_server_thread() {
|
void *web_server_loop(void *arg) {
|
||||||
|
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
||||||
while (s_signal_received == 0) {
|
while (s_signal_received == 0) {
|
||||||
mg_mgr_poll(&mgr, 10);
|
mg_mgr_poll(mgr, 100);
|
||||||
unsigned web_server_queue_length = tiny_queue_length(web_server_queue);
|
unsigned web_server_queue_length = tiny_queue_length(web_server_queue);
|
||||||
if (web_server_queue_length > 0) {
|
if (web_server_queue_length > 0) {
|
||||||
struct work_result_t *response = tiny_queue_shift(web_server_queue);
|
struct work_result_t *response = tiny_queue_shift(web_server_queue);
|
||||||
if (response->conn_id == 0) {
|
if (response->conn_id == 0) {
|
||||||
//Websocket notify from mpd idle
|
//Websocket notify from mpd idle
|
||||||
send_ws_notify(&mgr, response);
|
send_ws_notify(mgr, response);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//api response
|
//api response
|
||||||
send_api_response(&mgr, response);
|
send_api_response(mgr, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(mgr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +146,11 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case MG_EV_ACCEPT: {
|
case MG_EV_ACCEPT: {
|
||||||
nc->user_data = (void *)++s_next_id;
|
struct timespec start;
|
||||||
LOG_DEBUG() fprintf(stderr, "DEBUG: New connection id %lu.\n", s_next_id);
|
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
|
||||||
|
long unsigned conn_id = (start.tv_sec * 1000 + start.tv_nsec / 1000) * 100 + randrange(100);
|
||||||
|
nc->user_data = (void *)conn_id;
|
||||||
|
LOG_DEBUG() fprintf(stderr, "DEBUG: New connection id %lu.\n", conn_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: {
|
case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: {
|
||||||
@ -178,6 +179,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
tiny_queue_push(mpd_client_queue, request);
|
tiny_queue_push(mpd_client_queue, request);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
static struct mg_serve_http_opts s_http_server_opts;
|
||||||
|
s_http_server_opts.document_root = DOC_ROOT;
|
||||||
|
s_http_server_opts.enable_directory_listing = "no";
|
||||||
mg_serve_http(nc, hm, s_http_server_opts);
|
mg_serve_http(nc, hm, s_http_server_opts);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -41,8 +41,8 @@ struct work_result_t {
|
|||||||
int length;
|
int length;
|
||||||
} work_result_t;
|
} work_result_t;
|
||||||
|
|
||||||
void *web_server_thread();
|
void *web_server_loop(void *arg);
|
||||||
bool web_server_init();
|
bool web_server_init(void *arg);
|
||||||
void web_server_free();
|
void web_server_free(void *arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user