diff --git a/src/global.c b/src/global.c index 943402b..a8e3eef 100644 --- a/src/global.c +++ b/src/global.c @@ -27,6 +27,10 @@ #include #include "global.h" +int randrange(int n) { + return rand() / (RAND_MAX / (n + 1) + 1); +} + void sanitize_string(const char *data) { static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/src/global.h.in b/src/global.h.in index 23e9d3c..6fb0267 100644 --- a/src/global.h.in +++ b/src/global.h.in @@ -99,6 +99,7 @@ typedef struct { t_config config; //global functions +int randrange(int n); 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); #endif diff --git a/src/list.c b/src/list.c index ce94a64..9929630 100644 --- a/src/list.c +++ b/src/list.c @@ -81,7 +81,7 @@ int list_shuffle(struct list *l) { if (l->length < 2) return 1; - srand((unsigned int)time(NULL)); +// srand((unsigned int)time(NULL)); struct node *current = l->list; while (current != NULL) { diff --git a/src/main.c b/src/main.c index 32df3a6..24fc055 100644 --- a/src/main.c +++ b/src/main.c @@ -38,6 +38,7 @@ #include "global.h" #include "mpd_client.h" #include "web_server.h" +#include "../dist/src/mongoose/mongoose.h" static void signal_handler(int sig_num) { 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) { mpd_client_idle(100); } @@ -310,7 +311,8 @@ int main(int argc, char **argv) { char testdirname[400]; mpd_client_queue = tiny_queue_create(); web_server_queue = tiny_queue_create(); - //mympd_queue = tiny_queue_create(); + + srand((unsigned int)time(NULL)); //defaults config.mpdhost = "127.0.0.1"; @@ -380,36 +382,36 @@ int main(int argc, char **argv) { setvbuf(stderr, NULL, _IOLBF, 0); //init webserver - if (!web_server_init()) { + struct mg_mgr mgr; + if (!web_server_init(&mgr)) { return EXIT_FAILURE; } - //drop privileges if (config.user != NULL) { LOG_INFO() printf("Droping privileges to %s\n", config.user); struct passwd *pw; if ((pw = getpwnam(config.user)) == NULL) { printf("getpwnam() failed, unknown user\n"); - web_server_free(); + web_server_free(&mgr); return EXIT_FAILURE; } else if (setgroups(0, NULL) != 0) { printf("setgroups() failed\n"); - web_server_free(); + web_server_free(&mgr); return EXIT_FAILURE; } else if (setgid(pw->pw_gid) != 0) { printf("setgid() failed\n"); - web_server_free(); + web_server_free(&mgr); return EXIT_FAILURE; } else if (setuid(pw->pw_uid) != 0) { printf("setuid() failed\n"); - web_server_free(); + web_server_free(&mgr); return EXIT_FAILURE; } } if (getuid() == 0) { printf("myMPD should not be run with root privileges\n"); - web_server_free(); + web_server_free(&mgr); 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()); //Create working threads - pthread_t mpd_client, web_server; + pthread_t mpd_client_thread, web_server_thread; //mpd connection - pthread_create(&mpd_client, NULL, mpd_client_thread, NULL); + pthread_create(&mpd_client_thread, NULL, mpd_client_loop, NULL); //webserver - pthread_create(&web_server, NULL, web_server_thread, NULL); + pthread_create(&web_server_thread, NULL, web_server_loop, &mgr); //Do nothing... //clean up - pthread_join(mpd_client, NULL); - pthread_join(web_server, NULL); + pthread_join(mpd_client_thread, NULL); + pthread_join(web_server_thread, NULL); list_free(&mpd_tags); list_free(&mympd_tags); tiny_queue_free(web_server_queue); tiny_queue_free(mpd_client_queue); - //tiny_queue_free(mympd_queue); return EXIT_SUCCESS; } diff --git a/src/mpd_client.c b/src/mpd_client.c index 6d46f5a..d0a5d76 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -1362,7 +1362,7 @@ bool mpd_client_jukebox() { return true; } - srand((unsigned int)time(NULL)); + //srand((unsigned int)time(NULL)); struct list add_list; list_init(&add_list); @@ -1482,10 +1482,6 @@ bool mpd_client_jukebox() { 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) { struct mpd_status *status; const struct mpd_audio_format *audioformat; diff --git a/src/mpd_client.h b/src/mpd_client.h index ab2b12e..881f585 100644 --- a/src/mpd_client.h +++ b/src/mpd_client.h @@ -191,7 +191,6 @@ typedef struct { t_mympd_state mympd_state; tiny_queue_t *mpd_client_queue; -int randrange(int n); void mpd_client_idle(int timeout); void mpd_client_parse_idle(int idle_bitmask); void mpd_client_api(struct work_request_t *request); diff --git a/src/web_server.c b/src/web_server.c index 919fae0..a4a62c1 100644 --- a/src/web_server.c +++ b/src/web_server.c @@ -28,10 +28,6 @@ #include "../dist/src/mongoose/mongoose.h" //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 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); @@ -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); //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_http; struct mg_bind_opts bind_opts; const char *err; - mg_mgr_init(&mgr, NULL); + mg_mgr_init(mgr, NULL); 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) { printf("Error listening on port %s\n", config.webport); - mg_mgr_free(&mgr); + mg_mgr_free(mgr); return false; } mg_set_protocol_http_websocket(nc_http); @@ -61,51 +58,52 @@ bool web_server_init() { bind_opts.ssl_cert = config.sslcert; bind_opts.ssl_key = config.sslkey; 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) { printf("Error listening on port %s: %s\n", config.sslport, err); - mg_mgr_free(&mgr); + mg_mgr_free(mgr); return false; } LOG_INFO() printf("Listening on ssl port %s\n", config.sslport); } else { - nc = mg_bind(&mgr, config.webport, ev_handler); + nc = mg_bind(mgr, config.webport, ev_handler); if (nc == NULL) { printf("Error listening on port %s\n", config.webport); - mg_mgr_free(&mgr); + mg_mgr_free(mgr); return false; } LOG_INFO() printf("Listening on http port %s\n", config.webport); } mg_set_protocol_http_websocket(nc); - s_http_server_opts.document_root = DOC_ROOT; - s_http_server_opts.enable_directory_listing = "no"; - return true; + + return mgr; } -void web_server_free() { - mg_mgr_free(&mgr); +void web_server_free(void *arg) { + 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) { - mg_mgr_poll(&mgr, 10); + mg_mgr_poll(mgr, 100); unsigned web_server_queue_length = tiny_queue_length(web_server_queue); if (web_server_queue_length > 0) { struct work_result_t *response = tiny_queue_shift(web_server_queue); if (response->conn_id == 0) { //Websocket notify from mpd idle - send_ws_notify(&mgr, response); + send_ws_notify(mgr, response); } else { //api response - send_api_response(&mgr, response); + send_api_response(mgr, response); } } } - mg_mgr_free(&mgr); + mg_mgr_free(mgr); return NULL; } @@ -148,8 +146,11 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { switch(ev) { case MG_EV_ACCEPT: { - nc->user_data = (void *)++s_next_id; - LOG_DEBUG() fprintf(stderr, "DEBUG: New connection id %lu.\n", s_next_id); + struct timespec start; + 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; } 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); } 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); } break; diff --git a/src/web_server.h b/src/web_server.h index 6e859ba..789eea1 100644 --- a/src/web_server.h +++ b/src/web_server.h @@ -41,8 +41,8 @@ struct work_result_t { int length; } work_result_t; -void *web_server_thread(); -bool web_server_init(); -void web_server_free(); +void *web_server_loop(void *arg); +bool web_server_init(void *arg); +void web_server_free(void *arg); #endif