From cac4e8bfd5a3cc1948cef4f112506339a9adf759 Mon Sep 17 00:00:00 2001 From: jcorporation Date: Sun, 7 Oct 2018 22:21:00 +0100 Subject: [PATCH] Fix: move dynamic linked list management in separate src files Fix: write state files on startup --- CMakeLists.txt | 1 + src/list.c | 37 ++++++++++++++ src/list.h | 15 ++++++ src/mpd_client.c | 124 +++++++++++++++++++---------------------------- src/mpd_client.h | 6 --- src/mympd.c | 25 +++++++--- 6 files changed, 121 insertions(+), 87 deletions(-) create mode 100644 src/list.c create mode 100644 src/list.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b52f79a..4d422b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_SSL) set(SOURCES src/mympd.c src/mpd_client.c + src/list.c dist/src/mongoose/mongoose.c dist/src/frozen/frozen.c dist/src/inih/ini.c diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..c39a8d1 --- /dev/null +++ b/src/list.c @@ -0,0 +1,37 @@ +#include +#include +#include "list.h" + +int list_init(struct list *list) { + list->length = 0; + list->list = NULL; + return 0; +} + +int list_push(struct list *l, char *data, int value) { + struct node *n = malloc(sizeof(struct node)); + n->value = value; + n->data = malloc(strlen(data)); + n->data = strdup(data); + n->next = NULL; + + struct node **next = &l->list; + while (*next != NULL) { + next = &(*next)->next; + } + *next = n; + l->length++; + return 0; +} + +int list_free(struct list *l) { + struct node * current = l->list, *tmp = NULL; + while (current != NULL) { + free(current->data); + tmp = current; + current = current->next; + free(tmp); + } + list_init(l); + return 0; +} diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..dc507b1 --- /dev/null +++ b/src/list.h @@ -0,0 +1,15 @@ +struct node { + char *data; + int value; + struct node *next; +}; + +struct list { + unsigned length; + struct node *list; +}; + + +int list_init(struct list *); +int list_push(struct list *l, char *data, int value); +int list_free(struct list *l); diff --git a/src/mpd_client.c b/src/mpd_client.c index 36afd96..e783a0f 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -33,6 +33,7 @@ #include #include "mpd_client.h" +#include "list.h" #include "config.h" #include "../dist/src/frozen/frozen.h" @@ -1033,58 +1034,51 @@ void mympd_jukebox() { return; srand((unsigned int)time(NULL)); - struct aline *keepentries; - keepentries = malloc(addSongs * sizeof(*keepentries)); - if (keepentries == NULL) { - printf("Can't allocate space for %d lines\n", addSongs); - exit(1); - } - for (i = 0; i < addSongs; i++) { - keepentries[i].nalloc = 0; - keepentries[i].ptr = NULL; - } + + struct list add_list; + list_init(&add_list); if (mympd_state.jukeboxMode == 1) { //add songs if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) { if (!mpd_send_list_all(mpd.conn, "/")) { LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); + list_free(&add_list); return; } } else { if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) { LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); + list_free(&add_list); return; } } while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { - if (randrange(lineno) < addSongs) { - if (nkeep < addSongs) { - song = mpd_entity_get_song(entity); - save_entry(&keepentries[nkeep++], mpd_song_get_uri(song)); - } - else { - i = 0; - if (addSongs > 1) - i = randrange(addSongs); - if (addSongs == 1) { - song = mpd_entity_get_song(entity); - save_entry(&keepentries[i], mpd_song_get_uri(song)); + if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { + if (randrange(lineno) < addSongs) { + if (nkeep < addSongs) { + song = mpd_entity_get_song(entity); + list_push(&add_list, mpd_song_get_uri(song), lineno); + nkeep++; } else { - int nm = addSongs - i - 1; - if (nm > 0) { - struct aline tmp = keepentries[i]; - memmove(&keepentries[i], &keepentries[i+1], nm * sizeof(*keepentries)); - keepentries[addSongs - 1] = tmp; - } - song = mpd_entity_get_song(entity); - save_entry(&keepentries[nkeep - 1], mpd_song_get_uri(song)); + i = 0; + if (addSongs > 1) + i = randrange(addSongs); + if (addSongs == 1) { + song = mpd_entity_get_song(entity); + list_free(&add_list); + list_push(&add_list, mpd_song_get_uri(song), lineno); + } + else { + song = mpd_entity_get_song(entity); + list_push(&add_list, mpd_song_get_uri(song), lineno); + } } } + lineno++; } - lineno++; mpd_entity_free(entity); } } @@ -1092,32 +1086,30 @@ void mympd_jukebox() { //add album if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) { LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); + list_free(&add_list); return; } if (!mpd_search_commit(mpd.conn)) { LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); + list_free(&add_list); return; } while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) { if (randrange(lineno) < addSongs) { if (nkeep < addSongs) { - save_entry(&keepentries[nkeep++], strdup(pair->value)); + list_push(&add_list, strdup(pair->value), lineno); + nkeep++; } else { i = 0; if (addSongs > 1) i = randrange(addSongs); if (addSongs == 1) { - save_entry(&keepentries[i], strdup(pair->value)); + list_free(&add_list); + list_push(&add_list, strdup(pair->value), lineno); } else { - int nm = addSongs - i - 1; - if (nm > 0) { - struct aline tmp = keepentries[i]; - memmove(&keepentries[i], &keepentries[i+1], nm * sizeof(*keepentries)); - keepentries[addSongs - 1] = tmp; - } - save_entry(&keepentries[nkeep - 1], strdup(pair->value)); + list_push(&add_list, strdup(pair->value), lineno); } } } @@ -1126,26 +1118,30 @@ void mympd_jukebox() { } } if (nkeep < addSongs) { - fprintf(stderr, "Warning: input didn't contain %d lines\n", addSongs); - return; + fprintf(stderr, "Warning: input didn't contain %d entries\n", addSongs); } - for (i = 0; i < nkeep; i++) { + + struct node *current = add_list.list; + while (1) { if (mympd_state.jukeboxMode == 1) { - printf("Jukebox adding song: %s\n", keepentries[i].ptr); - if (!mpd_run_add(mpd.conn, keepentries[i].ptr)) { + printf("Jukebox adding song: %s\n", current->data); + if (!mpd_run_add(mpd.conn, current->data)) { LOG_ERROR_AND_RECOVER("mpd_run_add"); } } else { - printf("Jukebox adding album: %s\n", keepentries[i].ptr); - if (!mpd_send_command(mpd.conn, "searchadd", "Album", keepentries[i].ptr, NULL)) { + printf("Jukebox adding album: %s\n", current->data); + if (!mpd_send_command(mpd.conn, "searchadd", "Album", current->data, NULL)) { LOG_ERROR_AND_RECOVER("mpd_send_command"); return; } mpd_response_finish(mpd.conn); } - } - free(keepentries); + if (current->next == NULL) + break; + current = current->next; + } + list_free(&add_list); mpd_run_play(mpd.conn); } @@ -1153,24 +1149,6 @@ int randrange(int n) { return rand() / (RAND_MAX / (n + 1)); } -void save_entry(struct aline *alp, const char *entry) { - int need = strlen(entry) + 1; - if (need > alp->nalloc) { - alp->nalloc = need; - if (alp->nalloc < 80) /* arbitrary threshold */ - alp->nalloc = 80; - if (alp->ptr == NULL) - alp->ptr = malloc(alp->nalloc); - else - alp->ptr = realloc(alp->ptr, alp->nalloc); - if (alp->ptr == NULL) { - fprintf(stderr, "Can't (re)allocate space for saved entry\n"); - exit(1); - } - } - strcpy(alp->ptr, entry); -} - int mympd_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; @@ -1244,7 +1222,7 @@ bool mympd_state_get(char *name, char *value) { snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name); FILE *fp = fopen(cfgfile, "r"); if (fp == NULL) { - printf("Error opening %s", cfgfile); + printf("Error opening %s\n", cfgfile); return false; } read = getline(&line, &n, fp); @@ -1267,7 +1245,7 @@ bool mympd_state_set(char *name, char *value) { FILE *fp = fopen(tmpfile, "w"); if (fp == NULL) { - printf("Error opening %s", tmpfile); + printf("Error opening %s\n", tmpfile); return false; } fprintf(fp, value); @@ -2291,7 +2269,7 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) { snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir); FILE *fp = fopen(tmpfile, "w"); if (fp == NULL) { - printf("Error opening %s", tmpfile); + printf("Error opening %s\n", tmpfile); return 1; } while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { @@ -2318,7 +2296,7 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) { value_max = value_max / 2; fp = fopen(tmpfile, "r"); if (fp == NULL) { - printf("Error opening %s", tmpfile); + printf("Error opening %s\n", tmpfile); return 1; } while ((read = getline(&uri, &len, fp)) != -1) { @@ -2365,7 +2343,7 @@ int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries) snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir); FILE *fp = fopen(tmpfile, "w"); if (fp == NULL) { - printf("Error opening %s", tmpfile); + printf("Error opening %s\n", tmpfile); return 1; } while ((song = mpd_recv_song(mpd.conn)) != NULL) { @@ -2384,7 +2362,7 @@ int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries) fp = fopen(tmpfile, "r"); if (fp == NULL) { - printf("Error opening %s", tmpfile); + printf("Error opening %s\n", tmpfile); return 1; } while ((read = getline(&uri, &len, fp)) != -1) { diff --git a/src/mpd_client.h b/src/mpd_client.h index c1ee153..6bba011 100644 --- a/src/mpd_client.h +++ b/src/mpd_client.h @@ -186,17 +186,11 @@ typedef struct { t_mympd_state mympd_state; -struct aline { - char *ptr; - int nalloc; -}; - static int is_websocket(const struct mg_connection *nc) { return nc->flags & MG_F_IS_WEBSOCKET; } int randrange(int n); -void save_entry(struct aline *alp, const char *entry); void mympd_idle(struct mg_mgr *sm, int timeout); void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask); void callback_mympd(struct mg_connection *nc, const struct mg_str msg); diff --git a/src/mympd.c b/src/mympd.c index 6048d90..998cbae 100644 --- a/src/mympd.c +++ b/src/mympd.c @@ -189,8 +189,10 @@ void read_statefiles() { else mympd_state.notificationWeb = false; } - else + else { mympd_state.notificationWeb = false; + mympd_state_set("notificationWeb", "false"); + } if (mympd_state_get("notificationPage", value)) { if (strcmp(value, "true") == 0) @@ -198,24 +200,31 @@ void read_statefiles() { else mympd_state.notificationPage = false; } - else + else { mympd_state.notificationPage = true; - + mympd_state_set("notificationPage", "true"); + } if (mympd_state_get("jukeboxMode", value)) mympd_state.jukeboxMode = strtol(value, &crap, 10); - else + else { mympd_state.jukeboxMode = 0; + mympd_state_set("jukeboxMode", "0"); + } if (mympd_state_get("jukeboxPlaylist", value)) mympd_state.jukeboxPlaylist = strdup(value); - else + else { mympd_state.jukeboxPlaylist = "Database"; + mympd_state_set("jukeboxPlaylist", "Database"); + } if (mympd_state_get("jukeboxQueueLength", value)) mympd_state.jukeboxQueueLength = strtol(value, &crap, 10); - else + else { mympd_state.jukeboxQueueLength = 1; + mympd_state_set("jukeboxQueueLength", "1"); + } } int main(int argc, char **argv) { @@ -278,8 +287,6 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - read_statefiles(); - signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); setvbuf(stdout, NULL, _IOLBF, 0); @@ -341,6 +348,8 @@ int main(int argc, char **argv) { mg_mgr_free(&mgr); return EXIT_FAILURE; } + + read_statefiles(); if (config.ssl == true) mg_set_protocol_http_websocket(nc_http);