mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 13:53:00 +00:00 
			
		
		
		
	Fix: no global state in web_server.c
This commit is contained in:
		| @@ -27,6 +27,10 @@ | ||||
| #include <stdio.h> | ||||
| #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" | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation