mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-30 21:33:00 +00:00 
			
		
		
		
	Fix: valgrind memory still reachable errors in read_statefiles
Fix: thread termination of mympd_api_thread
This commit is contained in:
		
							
								
								
									
										49
									
								
								src/global.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								src/global.c
									
									
									
									
									
								
							| @@ -33,55 +33,6 @@ | ||||
| #include "list.h" | ||||
| #include "global.h" | ||||
|  | ||||
| bool state_file_read(t_config *config, const char *name, char *value) { | ||||
|     char cfg_file[400]; | ||||
|     char *line = NULL; | ||||
|     size_t n = 0; | ||||
|     ssize_t read; | ||||
|      | ||||
|     if (!validate_string(name)) | ||||
|         return false; | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     FILE *fp = fopen(cfg_file, "r"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", cfg_file); | ||||
|         return false; | ||||
|     } | ||||
|     read = getline(&line, &n, fp); | ||||
|     snprintf(value, 400, "%s", line); | ||||
|     LOG_DEBUG() fprintf(stderr, "DEBUG: State %s: %s\n", name, value); | ||||
|     fclose(fp); | ||||
|     free(line); | ||||
|     if (read > 0) | ||||
|         return true; | ||||
|     else | ||||
|         return false; | ||||
| } | ||||
|  | ||||
| bool state_file_write(t_config *config, const char *name, const char *value) { | ||||
|     char tmp_file[400]; | ||||
|     char cfg_file[400]; | ||||
|      | ||||
|     if (!validate_string(name)) | ||||
|         return false; | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     snprintf(tmp_file, 400, "%s/tmp/%s", config->varlibdir, name); | ||||
|          | ||||
|     FILE *fp = fopen(tmp_file, "w"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", tmp_file); | ||||
|         return false; | ||||
|     } | ||||
|     fprintf(fp, "%s", value); | ||||
|     fclose(fp); | ||||
|     if (rename(tmp_file, cfg_file) == -1) { | ||||
|         printf("Error renaming file from %s to %s\n", tmp_file, cfg_file); | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|  | ||||
| bool testdir(const char *name, const char *dirname) { | ||||
|     DIR* dir = opendir(dirname); | ||||
|     if (dir) { | ||||
|   | ||||
| @@ -158,33 +158,33 @@ typedef struct t_work_result { | ||||
| //myMPD configuration | ||||
| typedef struct t_config { | ||||
|     long mpdport; | ||||
|     const char *mpdhost; | ||||
|     const char *mpdpass; | ||||
|     const char *webport; | ||||
|     char *mpdhost; | ||||
|     char *mpdpass; | ||||
|     char *webport; | ||||
|     bool ssl; | ||||
|     const char *sslport; | ||||
|     const char *sslcert; | ||||
|     const char *sslkey; | ||||
|     const char *user; | ||||
|     char *sslport; | ||||
|     char *sslcert; | ||||
|     char *sslkey; | ||||
|     char *user; | ||||
|     bool coverimage; | ||||
|     const char *coverimagename; | ||||
|     char *coverimagename; | ||||
|     long coverimagesize; | ||||
|     bool stickers; | ||||
|     bool mixramp; | ||||
|     const char *taglist; | ||||
|     const char *searchtaglist; | ||||
|     const char *browsetaglist; | ||||
|     char *taglist; | ||||
|     char *searchtaglist; | ||||
|     char *browsetaglist; | ||||
|     bool smartpls; | ||||
|     const char *varlibdir; | ||||
|     const char *etcdir; | ||||
|     char *varlibdir; | ||||
|     char *etcdir; | ||||
|     unsigned long max_elements_per_page; | ||||
|     bool syscmds; | ||||
|     bool localplayer; | ||||
|     long streamport; | ||||
|     const char *streamurl; | ||||
|     char *streamurl; | ||||
|     unsigned long last_played_count; | ||||
|     long loglevel; | ||||
|     const char *backgroundcolor; | ||||
|     char *backgroundcolor; | ||||
| } t_config; | ||||
|  | ||||
| //global functions | ||||
| @@ -194,6 +194,4 @@ bool validate_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 replacechar(char *str, const char orig, const char rep); | ||||
| enum mympd_cmd_ids get_cmd_id(const char *cmd); | ||||
| bool state_file_read(t_config *config, const char *name, char *value); | ||||
| bool state_file_write(t_config *config, const char *name, const char *value); | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										173
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -47,6 +47,8 @@ | ||||
| static void signal_handler(int sig_num) { | ||||
|     signal(sig_num, signal_handler);  // Reinstantiate signal handler | ||||
|     s_signal_received = sig_num; | ||||
|     //Wakeup mympd_api_loop | ||||
|     pthread_cond_signal(&mympd_api_queue->wakeup); | ||||
| } | ||||
|  | ||||
| static int inihandler(void *user, const char *section, const char *name, const char* value) { | ||||
| @@ -55,61 +57,78 @@ static int inihandler(void *user, const char *section, const char *name, const c | ||||
|  | ||||
|     #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 | ||||
|  | ||||
|     if (MATCH("mpd", "mpdhost")) | ||||
|     if (MATCH("mpd", "mpdhost")) { | ||||
|         free(p_config->mpdhost); | ||||
|         p_config->mpdhost = strdup(value); | ||||
|     else if (MATCH("mpd", "mpdport")) | ||||
|     } | ||||
|     else if (MATCH("mpd", "mpdport")) { | ||||
|         p_config->mpdport = strtol(value, &crap, 10); | ||||
|     else if (MATCH("mpd", "mpdpass")) | ||||
|     } | ||||
|     else if (MATCH("mpd", "mpdpass")) { | ||||
|         free(p_config->mpdpass); | ||||
|         p_config->mpdpass = strdup(value); | ||||
|     else if (MATCH("mpd", "streamport")) | ||||
|     } | ||||
|     else if (MATCH("mpd", "streamport")) { | ||||
|         p_config->streamport = strtol(value, &crap, 10); | ||||
|     else if (MATCH("webserver", "webport")) | ||||
|     } | ||||
|     else if (MATCH("webserver", "webport")) { | ||||
|         free(p_config->webport); | ||||
|         p_config->webport = strdup(value); | ||||
|     else if (MATCH("webserver", "ssl")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->ssl = true; | ||||
|         else | ||||
|             p_config->ssl = false; | ||||
|     else if (MATCH("webserver", "sslport")) | ||||
|     } | ||||
|     else if (MATCH("webserver", "ssl")) { | ||||
|         p_config->ssl = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("webserver", "sslport")) { | ||||
|         free(p_config->sslport); | ||||
|         p_config->sslport = strdup(value); | ||||
|     else if (MATCH("webserver", "sslcert")) | ||||
|     } | ||||
|     else if (MATCH("webserver", "sslcert")) { | ||||
|         free(p_config->sslcert); | ||||
|         p_config->sslcert = strdup(value); | ||||
|     else if (MATCH("webserver", "sslkey")) | ||||
|     } | ||||
|     else if (MATCH("webserver", "sslkey")) { | ||||
|         free(p_config->sslkey); | ||||
|         p_config->sslkey = strdup(value); | ||||
|     else if (MATCH("mympd", "user")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "user")) { | ||||
|         free(p_config->user); | ||||
|         p_config->user = strdup(value); | ||||
|     else if (MATCH("mympd", "coverimage")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->coverimage = true; | ||||
|         else | ||||
|             p_config->coverimage = false; | ||||
|     else if (MATCH("mympd", "coverimagename")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "coverimage")) { | ||||
|         p_config->coverimage = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "coverimagename")) { | ||||
|         free(p_config->coverimagename); | ||||
|         p_config->coverimagename = strdup(value); | ||||
|     else if (MATCH("mympd", "coverimagesize")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "coverimagesize")) { | ||||
|         p_config->coverimagesize = strtol(value, &crap, 10); | ||||
|     else if (MATCH("mympd", "varlibdir")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "varlibdir")) { | ||||
|         free(p_config->varlibdir); | ||||
|         p_config->varlibdir = strdup(value); | ||||
|     else if (MATCH("mympd", "stickers")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->stickers = true; | ||||
|         else | ||||
|             p_config->stickers = false; | ||||
|     else if (MATCH("mympd", "smartpls")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->smartpls = true; | ||||
|         else | ||||
|             p_config->smartpls = false; | ||||
|     else if (MATCH("mympd", "mixramp")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->mixramp = true; | ||||
|         else | ||||
|             p_config->mixramp = false; | ||||
|     else if (MATCH("mympd", "taglist")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "stickers")) { | ||||
|         p_config->stickers = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "smartpls")) { | ||||
|         p_config->smartpls =  strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "mixramp")) { | ||||
|         p_config->mixramp = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "taglist")) { | ||||
|         free(p_config->taglist); | ||||
|         p_config->taglist = strdup(value); | ||||
|     else if (MATCH("mympd", "searchtaglist")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "searchtaglist")) { | ||||
|         free(p_config->searchtaglist); | ||||
|         p_config->searchtaglist = strdup(value); | ||||
|     else if (MATCH("mympd", "browsetaglist")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "browsetaglist")) { | ||||
|         free(p_config->browsetaglist); | ||||
|         p_config->browsetaglist = strdup(value); | ||||
|     } | ||||
|     else if (MATCH("mympd", "max_elements_per_page")) { | ||||
|         p_config->max_elements_per_page = strtol(value, &crap, 10); | ||||
|         if (p_config->max_elements_per_page > MAX_ELEMENTS_PER_PAGE) { | ||||
| @@ -117,27 +136,29 @@ static int inihandler(void *user, const char *section, const char *name, const c | ||||
|             p_config->max_elements_per_page = MAX_ELEMENTS_PER_PAGE; | ||||
|         } | ||||
|     } | ||||
|     else if (MATCH("mympd", "syscmds")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->syscmds = true; | ||||
|         else | ||||
|             p_config->syscmds = false; | ||||
|     else if (MATCH("mympd", "localplayer")) | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             p_config->localplayer = true; | ||||
|         else | ||||
|             p_config->localplayer = false; | ||||
|     else if (MATCH("mympd", "streamurl")) | ||||
|     else if (MATCH("mympd", "syscmds")) { | ||||
|         p_config->syscmds = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "localplayer")) { | ||||
|         p_config->localplayer = strcmp(value, "true") == 0 ? true : false; | ||||
|     } | ||||
|     else if (MATCH("mympd", "streamurl")) { | ||||
|         free(p_config->streamurl); | ||||
|         p_config->streamurl = strdup(value); | ||||
|     else if (MATCH("mympd", "last_played_count")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "last_played_count")) { | ||||
|         p_config->last_played_count = strtol(value, &crap, 10); | ||||
|     else if (MATCH("mympd", "loglevel")) | ||||
|     } | ||||
|     else if (MATCH("mympd", "loglevel")) { | ||||
|         p_config->loglevel = strtol(value, &crap, 10); | ||||
|     else if (MATCH("theme", "backgroundcolor")) | ||||
|     } | ||||
|     else if (MATCH("theme", "backgroundcolor")) { | ||||
|         free(p_config->backgroundcolor); | ||||
|         p_config->backgroundcolor = strdup(value); | ||||
|     } | ||||
|     else { | ||||
|         printf("Unkown config option: %s - %s\n", section, name); | ||||
|         return 0;  /* unknown section/name, error */ | ||||
|         return 0;   | ||||
|     } | ||||
|  | ||||
|     return 1; | ||||
| @@ -154,26 +175,26 @@ int main(int argc, char **argv) { | ||||
|      | ||||
|     //mympd config defaults | ||||
|     t_config config; | ||||
|     config.mpdhost = "127.0.0.1"; | ||||
|     config.mpdhost = strdup("127.0.0.1"); | ||||
|     config.mpdport = 6600; | ||||
|     config.mpdpass = NULL; | ||||
|     config.webport = "80"; | ||||
|     config.webport = strdup("80"); | ||||
|     config.ssl = true; | ||||
|     config.sslport = "443"; | ||||
|     config.sslcert = "/etc/mympd/ssl/server.pem"; | ||||
|     config.sslkey = "/etc/mympd/ssl/server.key"; | ||||
|     config.user = "mympd"; | ||||
|     config.sslport = strdup("443"); | ||||
|     config.sslcert = strdup("/etc/mympd/ssl/server.pem"); | ||||
|     config.sslkey = strdup("/etc/mympd/ssl/server.key"); | ||||
|     config.user = strdup("mympd"); | ||||
|     config.streamport = 8000; | ||||
|     config.streamurl = ""; | ||||
|     config.streamurl = strdup(""); | ||||
|     config.coverimage = true; | ||||
|     config.coverimagename = "folder.jpg"; | ||||
|     config.coverimagename = strdup("folder.jpg"); | ||||
|     config.coverimagesize = 240; | ||||
|     config.varlibdir = "/var/lib/mympd"; | ||||
|     config.varlibdir = strdup("/var/lib/mympd"); | ||||
|     config.stickers = true; | ||||
|     config.mixramp = true; | ||||
|     config.taglist = "Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer"; | ||||
|     config.searchtaglist = "Artist,Album,AlbumArtist,Title,Genre,Composer,Performer"; | ||||
|     config.browsetaglist = "Artist,Album,AlbumArtist,Genre,Composer,Performer"; | ||||
|     config.taglist = strdup("Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer"); | ||||
|     config.searchtaglist = strdup("Artist,Album,AlbumArtist,Title,Genre,Composer,Performer"); | ||||
|     config.browsetaglist = strdup("Artist,Album,AlbumArtist,Genre,Composer,Performer"); | ||||
|     config.smartpls = true; | ||||
|     config.max_elements_per_page = 100; | ||||
|     config.last_played_count = 20; | ||||
| @@ -183,7 +204,7 @@ int main(int argc, char **argv) { | ||||
|     config.syscmds = false; | ||||
|     config.localplayer = true; | ||||
|     config.loglevel = 1; | ||||
|     config.backgroundcolor = "#888"; | ||||
|     config.backgroundcolor = strdup("#888"); | ||||
|      | ||||
|     if (argc == 2) { | ||||
|         printf("Starting myMPD %s\n", MYMPD_VERSION); | ||||
| @@ -292,9 +313,25 @@ int main(int argc, char **argv) { | ||||
|     //cleanup | ||||
|     pthread_join(mpd_client_thread, NULL); | ||||
|     pthread_join(web_server_thread, NULL); | ||||
|     pthread_join(mympd_api_thread, NULL); | ||||
|     tiny_queue_free(web_server_queue); | ||||
|     tiny_queue_free(mpd_client_queue); | ||||
|     tiny_queue_free(mympd_api_queue); | ||||
|     free(config.mpdhost); | ||||
|     free(config.mpdpass); | ||||
|     free(config.webport); | ||||
|     free(config.sslport); | ||||
|     free(config.sslcert); | ||||
|     free(config.sslkey); | ||||
|     free(config.user); | ||||
|     free(config.coverimagename); | ||||
|     free(config.taglist); | ||||
|     free(config.searchtaglist); | ||||
|     free(config.browsetaglist); | ||||
|     free(config.varlibdir); | ||||
|     free(config.etcdir); | ||||
|     free(config.streamurl); | ||||
|     free(config.backgroundcolor); | ||||
|  | ||||
|     return EXIT_SUCCESS; | ||||
| } | ||||
|   | ||||
| @@ -1122,6 +1122,7 @@ static void mpd_client_idle(t_config *config, t_mpd_state *mpd_state) { | ||||
|                 len = snprintf(buffer, MAX_SIZE, "{\"type\": \"disconnected\"}"); | ||||
|                 mpd_client_notify(buffer, len); | ||||
|                 mpd_state->conn_state = MPD_FAILURE; | ||||
|                 mpd_connection_free(mpd_state->conn); | ||||
|                 sleep(3); | ||||
|                 return; | ||||
|             } | ||||
| @@ -1160,8 +1161,9 @@ static void mpd_client_idle(t_config *config, t_mpd_state *mpd_state) { | ||||
|             // fall through | ||||
|         case MPD_DISCONNECT: | ||||
|         case MPD_RECONNECT: | ||||
|             if (mpd_state->conn != NULL) | ||||
|             if (mpd_state->conn != NULL) { | ||||
|                 mpd_connection_free(mpd_state->conn); | ||||
|             } | ||||
|             mpd_state->conn = NULL; | ||||
|             mpd_state->conn_state = MPD_DISCONNECTED; | ||||
|             break; | ||||
| @@ -2557,7 +2559,9 @@ static int mpd_client_put_stats(t_mpd_state *mpd_state, char *buffer) { | ||||
|  | ||||
| static void mpd_client_disconnect(t_config *config, t_mpd_state *mpd_state) { | ||||
|     mpd_state->conn_state = MPD_DISCONNECT; | ||||
| //    mpd_client_idle(config, mpd_state); | ||||
|     if (mpd_state->conn != NULL) { | ||||
|         mpd_connection_free(mpd_state->conn); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int mpd_client_smartpls_put(t_config *config, char *buffer, const char *playlist) { | ||||
|   | ||||
							
								
								
									
										199
									
								
								src/mympd_api.c
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								src/mympd_api.c
									
									
									
									
									
								
							| @@ -69,6 +69,10 @@ static void mympd_api(t_config *config, t_mympd_state *mympd_state, t_work_reque | ||||
| static bool mympd_api_read_syscmds(t_config *config, t_mympd_state *mympd_state); | ||||
| static int mympd_api_syscmd(t_config *config, t_mympd_state *mympd_state, char *buffer, const char *cmd); | ||||
| static void mympd_api_read_statefiles(t_config *config, t_mympd_state *mympd_state); | ||||
| static char *state_file_rw_string(t_config *config, const char *name, const char *def_value); | ||||
| static bool state_file_rw_bool(t_config *config, const char *name, const bool def_value); | ||||
| static long state_file_rw_long(t_config *config, const char *name, const long def_value); | ||||
| static bool state_file_write(t_config *config, const char *name, const char *value); | ||||
| static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state, char *buffer); | ||||
|  | ||||
|  | ||||
| @@ -327,112 +331,129 @@ static int mympd_api_syscmd(t_config *config, t_mympd_state *mympd_state, char * | ||||
| } | ||||
|  | ||||
| static void mympd_api_read_statefiles(t_config *config, t_mympd_state *mympd_state) { | ||||
|     char *crap; | ||||
|     char value[400]; | ||||
|  | ||||
|     LOG_INFO() printf("Reading states\n"); | ||||
|     if (state_file_read(config, "notificationWeb", value)) { | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             mympd_state->notificationWeb = true; | ||||
|         else | ||||
|             mympd_state->notificationWeb = false; | ||||
|     } | ||||
|     else { | ||||
|         mympd_state->notificationWeb = false; | ||||
|         state_file_write(config, "notificationWeb", "false"); | ||||
|     mympd_state->notificationWeb = state_file_rw_bool(config, "notificationWeb", false); | ||||
|     mympd_state->notificationPage = state_file_rw_bool(config, "notificationPage", true); | ||||
|     mympd_state->autoPlay = state_file_rw_bool(config, "autoPlay", false); | ||||
|     mympd_state->jukeboxMode = state_file_rw_long(config, "jukeboxMode", JUKEBOX_OFF); | ||||
|     mympd_state->jukeboxPlaylist = state_file_rw_string(config, "jukeboxPlaylist", "Database"); | ||||
|     mympd_state->jukeboxQueueLength = state_file_rw_long(config, "jukeboxQueueLength", 1); | ||||
|     mympd_state->colsQueueCurrent = state_file_rw_string(config, "colsQueueCurrent", "[\"Pos\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|     mympd_state->colsSearch = state_file_rw_string(config, "colsSearch", "[\"Title\",\"Artist\",\"Album\",\"Duration\"]");     | ||||
|     mympd_state->colsBrowseDatabase = state_file_rw_string(config, "colsBrowseDatabase", "[\"Track\",\"Title\",\"Duration\"]"); | ||||
|     mympd_state->colsBrowsePlaylistsDetail = state_file_rw_string(config, "colsBrowsePlaylistsDetail", "[\"Pos\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|     mympd_state->colsBrowseFilesystem = state_file_rw_string(config, "colsBrowseFilesystem", "[\"Type\",\"Title\",\"Artist\",\"Album\",\"Duration\"]");     | ||||
|     mympd_state->colsPlayback = state_file_rw_string(config, "colsPlayback", "[\"Artist\",\"Album\"]");     | ||||
|     mympd_state->colsQueueLastPlayed = state_file_rw_string(config, "colsQueueLastPlayed", "[\"Pos\",\"Title\",\"Artist\",\"Album\",\"LastPlayed\"]");     | ||||
| } | ||||
|  | ||||
|     if (state_file_read(config, "notificationPage", value)) { | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             mympd_state->notificationPage = true; | ||||
|         else | ||||
|             mympd_state->notificationPage = false; | ||||
| static char *state_file_rw_string(t_config *config, const char *name, const char *def_value) { | ||||
|     char cfg_file[400]; | ||||
|     char *line = NULL; | ||||
|     size_t n = 0; | ||||
|     ssize_t read; | ||||
|      | ||||
|     if (!validate_string(name)) { | ||||
|         return NULL; | ||||
|     } | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     FILE *fp = fopen(cfg_file, "r"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", cfg_file); | ||||
|         state_file_write(config, name, def_value); | ||||
|         return NULL; | ||||
|     } | ||||
|     read = getline(&line, &n, fp); | ||||
|     if (read > 0) { | ||||
|         LOG_DEBUG() fprintf(stderr, "DEBUG: State %s: %s\n", name, line); | ||||
|     } | ||||
|     fclose(fp); | ||||
|     if (read > 0) { | ||||
|         return line; | ||||
|     } | ||||
|     else { | ||||
|         mympd_state->notificationPage = true; | ||||
|         state_file_write(config, "notificationPage", "true"); | ||||
|         free(line); | ||||
|         return NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     if (state_file_read(config, "autoPlay", value)) { | ||||
|         if (strcmp(value, "true") == 0) | ||||
|             mympd_state->autoPlay = true; | ||||
|         else | ||||
|             mympd_state->autoPlay = false; | ||||
| static bool state_file_rw_bool(t_config *config, const char *name, const bool def_value) { | ||||
|     char cfg_file[400]; | ||||
|     char *line = NULL; | ||||
|     size_t n = 0; | ||||
|     ssize_t read; | ||||
|     bool value = def_value; | ||||
|      | ||||
|     if (!validate_string(name)) | ||||
|         return def_value; | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     FILE *fp = fopen(cfg_file, "r"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", cfg_file); | ||||
|         state_file_write(config, name, def_value == true ? "true" : "false"); | ||||
|         return def_value; | ||||
|     } | ||||
|     else { | ||||
|         mympd_state->autoPlay = false; | ||||
|         state_file_write(config, "autoPlay", "false"); | ||||
|     read = getline(&line, &n, fp); | ||||
|     if (read > 0) { | ||||
|         LOG_DEBUG() fprintf(stderr, "DEBUG: State %s: %s\n", name, line); | ||||
|         value = strcmp(line, "true") == 0 ? true : false; | ||||
|     } | ||||
|     fclose(fp); | ||||
|     free(line); | ||||
|     return value; | ||||
| } | ||||
|  | ||||
|     if (state_file_read(config, "jukeboxMode", value)) | ||||
|         mympd_state->jukeboxMode = strtol(value, &crap, 10); | ||||
|     else { | ||||
|         mympd_state->jukeboxMode = JUKEBOX_OFF; | ||||
|         state_file_write(config, "jukeboxMode", "0"); | ||||
| static long state_file_rw_long(t_config *config, const char *name, const long def_value) { | ||||
|     char cfg_file[400]; | ||||
|     char *line = NULL; | ||||
|     char *crap; | ||||
|     size_t n = 0; | ||||
|     ssize_t read; | ||||
|     long value = def_value; | ||||
|      | ||||
|     if (!validate_string(name)) | ||||
|         return def_value; | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     FILE *fp = fopen(cfg_file, "r"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", cfg_file); | ||||
|         char p_value[65]; | ||||
|         snprintf(p_value, 65, "%ld", def_value); | ||||
|         state_file_write(config, name, p_value); | ||||
|         return def_value; | ||||
|     } | ||||
|     read = getline(&line, &n, fp); | ||||
|     if (read > 0) { | ||||
|         LOG_DEBUG() fprintf(stderr, "DEBUG: State %s: %s\n", name, line); | ||||
|         value = strtol(line, &crap, 10); | ||||
|     } | ||||
|     fclose(fp); | ||||
|     free(line); | ||||
|     return value; | ||||
| } | ||||
|  | ||||
|     if (state_file_read(config, "jukeboxPlaylist", value)) | ||||
|         mympd_state->jukeboxPlaylist = strdup(value); | ||||
|     else { | ||||
|         mympd_state->jukeboxPlaylist = strdup("Database"); | ||||
|         state_file_write(config, "jukeboxPlaylist", "Database"); | ||||
|     } | ||||
|  | ||||
|     if (state_file_read(config, "jukeboxQueueLength", value)) | ||||
|         mympd_state->jukeboxQueueLength = strtol(value, &crap, 10); | ||||
|     else { | ||||
|         mympd_state->jukeboxQueueLength = 1; | ||||
|         state_file_write(config, "jukeboxQueueLength", "1"); | ||||
|     } | ||||
| static bool state_file_write(t_config *config, const char *name, const char *value) { | ||||
|     char tmp_file[400]; | ||||
|     char cfg_file[400]; | ||||
|      | ||||
|     if (state_file_read(config, "colsQueueCurrent", value)) | ||||
|         mympd_state->colsQueueCurrent = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsQueueCurrent = strdup("[\"Pos\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|         state_file_write(config, "colsQueueCurrent", mympd_state->colsQueueCurrent); | ||||
|     } | ||||
|     if (!validate_string(name)) | ||||
|         return false; | ||||
|     snprintf(cfg_file, 400, "%s/state/%s", config->varlibdir, name); | ||||
|     snprintf(tmp_file, 400, "%s/tmp/%s", config->varlibdir, name); | ||||
|          | ||||
|     if (state_file_read(config, "colsSearch", value)) | ||||
|         mympd_state->colsSearch = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsSearch = strdup("[\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|         state_file_write(config, "colsSearch", mympd_state->colsSearch); | ||||
|     FILE *fp = fopen(tmp_file, "w"); | ||||
|     if (fp == NULL) { | ||||
|         printf("Error opening %s\n", tmp_file); | ||||
|         return false; | ||||
|     } | ||||
|      | ||||
|     if (state_file_read(config, "colsBrowseDatabase", value)) | ||||
|         mympd_state->colsBrowseDatabase = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsBrowseDatabase = strdup("[\"Track\",\"Title\",\"Duration\"]"); | ||||
|         state_file_write(config, "colsBrowseDatabase", mympd_state->colsBrowseDatabase); | ||||
|     } | ||||
|      | ||||
|     if (state_file_read(config, "colsBrowsePlaylistsDetail", value)) | ||||
|         mympd_state->colsBrowsePlaylistsDetail = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsBrowsePlaylistsDetail = strdup("[\"Pos\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|         state_file_write(config, "colsBrowsePlaylistsDetail", mympd_state->colsBrowsePlaylistsDetail); | ||||
|     } | ||||
|      | ||||
|     if (state_file_read(config, "colsBrowseFilesystem", value)) | ||||
|         mympd_state->colsBrowseFilesystem = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsBrowseFilesystem = strdup("[\"Type\",\"Title\",\"Artist\",\"Album\",\"Duration\"]"); | ||||
|         state_file_write(config, "colsBrowseFilesystem", mympd_state->colsBrowseFilesystem); | ||||
|     } | ||||
|      | ||||
|     if (state_file_read(config, "colsPlayback", value)) | ||||
|         mympd_state->colsPlayback = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsPlayback = strdup("[\"Artist\",\"Album\",\"Genre\"]"); | ||||
|         state_file_write(config, "colsPlayback", mympd_state->colsPlayback); | ||||
|     } | ||||
|  | ||||
|     if (state_file_read(config, "colsQueueLastPlayed", value)) | ||||
|         mympd_state->colsQueueLastPlayed = strdup(value); | ||||
|     else { | ||||
|         mympd_state->colsQueueLastPlayed = strdup("[\"Pos\",\"Title\",\"Artist\",\"Album\",\"LastPlayed\"]"); | ||||
|         state_file_write(config, "colsQueueLastPlayed", mympd_state->colsQueueLastPlayed); | ||||
|     fprintf(fp, "%s", value); | ||||
|     fclose(fp); | ||||
|     if (rename(tmp_file, cfg_file) == -1) { | ||||
|         printf("Error renaming file from %s to %s\n", tmp_file, cfg_file); | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state, char *buffer) { | ||||
|   | ||||
| @@ -152,6 +152,7 @@ void *tiny_queue_shift(tiny_queue_t *queue, int timeout) { | ||||
|         } | ||||
|     } | ||||
|     //queue has entry | ||||
|     if (queue->head != NULL) { | ||||
|         struct tiny_msg_t* current_head = queue->head; | ||||
|         void *data = current_head->data; | ||||
|         if (queue->head == queue->tail) { | ||||
| @@ -168,3 +169,11 @@ void *tiny_queue_shift(tiny_queue_t *queue, int timeout) { | ||||
|         } | ||||
|         return data; | ||||
|     } | ||||
|     else { | ||||
|         rc = pthread_mutex_unlock(&queue->mutex); | ||||
|         if (rc != 0) { | ||||
|             printf("Error in pthread_mutex_unlock: %d\n", rc); | ||||
|         } | ||||
|         return NULL; | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation