1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-12-26 19:10:25 +00:00

Fix: move dynamic linked list management in separate src files

Fix: write state files on startup
This commit is contained in:
jcorporation 2018-10-07 22:21:00 +01:00
parent 5c134ee026
commit cac4e8bfd5
6 changed files with 121 additions and 87 deletions

View File

@ -31,6 +31,7 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_SSL)
set(SOURCES set(SOURCES
src/mympd.c src/mympd.c
src/mpd_client.c src/mpd_client.c
src/list.c
dist/src/mongoose/mongoose.c dist/src/mongoose/mongoose.c
dist/src/frozen/frozen.c dist/src/frozen/frozen.c
dist/src/inih/ini.c dist/src/inih/ini.c

37
src/list.c Normal file
View File

@ -0,0 +1,37 @@
#include <stdlib.h>
#include <string.h>
#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;
}

15
src/list.h Normal file
View File

@ -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);

View File

@ -33,6 +33,7 @@
#include <mpd/client.h> #include <mpd/client.h>
#include "mpd_client.h" #include "mpd_client.h"
#include "list.h"
#include "config.h" #include "config.h"
#include "../dist/src/frozen/frozen.h" #include "../dist/src/frozen/frozen.h"
@ -1033,36 +1034,33 @@ void mympd_jukebox() {
return; return;
srand((unsigned int)time(NULL)); srand((unsigned int)time(NULL));
struct aline *keepentries;
keepentries = malloc(addSongs * sizeof(*keepentries)); struct list add_list;
if (keepentries == NULL) { list_init(&add_list);
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;
}
if (mympd_state.jukeboxMode == 1) { if (mympd_state.jukeboxMode == 1) {
//add songs //add songs
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) { if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
if (!mpd_send_list_all(mpd.conn, "/")) { if (!mpd_send_list_all(mpd.conn, "/")) {
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
list_free(&add_list);
return; return;
} }
} }
else { else {
if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) { if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) {
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
list_free(&add_list);
return; return;
} }
} }
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
if (randrange(lineno) < addSongs) { if (randrange(lineno) < addSongs) {
if (nkeep < addSongs) { if (nkeep < addSongs) {
song = mpd_entity_get_song(entity); song = mpd_entity_get_song(entity);
save_entry(&keepentries[nkeep++], mpd_song_get_uri(song)); list_push(&add_list, mpd_song_get_uri(song), lineno);
nkeep++;
} }
else { else {
i = 0; i = 0;
@ -1070,21 +1068,17 @@ void mympd_jukebox() {
i = randrange(addSongs); i = randrange(addSongs);
if (addSongs == 1) { if (addSongs == 1) {
song = mpd_entity_get_song(entity); song = mpd_entity_get_song(entity);
save_entry(&keepentries[i], mpd_song_get_uri(song)); list_free(&add_list);
list_push(&add_list, mpd_song_get_uri(song), lineno);
} }
else { 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); song = mpd_entity_get_song(entity);
save_entry(&keepentries[nkeep - 1], mpd_song_get_uri(song)); list_push(&add_list, mpd_song_get_uri(song), lineno);
} }
} }
} }
lineno++; lineno++;
}
mpd_entity_free(entity); mpd_entity_free(entity);
} }
} }
@ -1092,32 +1086,30 @@ void mympd_jukebox() {
//add album //add album
if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) { if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) {
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
list_free(&add_list);
return; return;
} }
if (!mpd_search_commit(mpd.conn)) { if (!mpd_search_commit(mpd.conn)) {
LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); LOG_ERROR_AND_RECOVER("mpd_send_list_playlist");
list_free(&add_list);
return; return;
} }
while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) { while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL) {
if (randrange(lineno) < addSongs) { if (randrange(lineno) < addSongs) {
if (nkeep < addSongs) { if (nkeep < addSongs) {
save_entry(&keepentries[nkeep++], strdup(pair->value)); list_push(&add_list, strdup(pair->value), lineno);
nkeep++;
} }
else { else {
i = 0; i = 0;
if (addSongs > 1) if (addSongs > 1)
i = randrange(addSongs); i = randrange(addSongs);
if (addSongs == 1) { if (addSongs == 1) {
save_entry(&keepentries[i], strdup(pair->value)); list_free(&add_list);
list_push(&add_list, strdup(pair->value), lineno);
} }
else { else {
int nm = addSongs - i - 1; list_push(&add_list, strdup(pair->value), lineno);
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));
} }
} }
} }
@ -1126,26 +1118,30 @@ void mympd_jukebox() {
} }
} }
if (nkeep < addSongs) { if (nkeep < addSongs) {
fprintf(stderr, "Warning: input didn't contain %d lines\n", addSongs); fprintf(stderr, "Warning: input didn't contain %d entries\n", addSongs);
return;
} }
for (i = 0; i < nkeep; i++) {
struct node *current = add_list.list;
while (1) {
if (mympd_state.jukeboxMode == 1) { if (mympd_state.jukeboxMode == 1) {
printf("Jukebox adding song: %s\n", keepentries[i].ptr); printf("Jukebox adding song: %s\n", current->data);
if (!mpd_run_add(mpd.conn, keepentries[i].ptr)) { if (!mpd_run_add(mpd.conn, current->data)) {
LOG_ERROR_AND_RECOVER("mpd_run_add"); LOG_ERROR_AND_RECOVER("mpd_run_add");
} }
} }
else { else {
printf("Jukebox adding album: %s\n", keepentries[i].ptr); printf("Jukebox adding album: %s\n", current->data);
if (!mpd_send_command(mpd.conn, "searchadd", "Album", keepentries[i].ptr, NULL)) { if (!mpd_send_command(mpd.conn, "searchadd", "Album", current->data, NULL)) {
LOG_ERROR_AND_RECOVER("mpd_send_command"); LOG_ERROR_AND_RECOVER("mpd_send_command");
return; return;
} }
mpd_response_finish(mpd.conn); mpd_response_finish(mpd.conn);
} }
if (current->next == NULL)
break;
current = current->next;
} }
free(keepentries); list_free(&add_list);
mpd_run_play(mpd.conn); mpd_run_play(mpd.conn);
} }
@ -1153,24 +1149,6 @@ int randrange(int n) {
return rand() / (RAND_MAX / (n + 1)); 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) { 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; struct mpd_status *status;
const struct mpd_audio_format *audioformat; 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); snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name);
FILE *fp = fopen(cfgfile, "r"); FILE *fp = fopen(cfgfile, "r");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", cfgfile); printf("Error opening %s\n", cfgfile);
return false; return false;
} }
read = getline(&line, &n, fp); read = getline(&line, &n, fp);
@ -1267,7 +1245,7 @@ bool mympd_state_set(char *name, char *value) {
FILE *fp = fopen(tmpfile, "w"); FILE *fp = fopen(tmpfile, "w");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", tmpfile); printf("Error opening %s\n", tmpfile);
return false; return false;
} }
fprintf(fp, value); 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); snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
FILE *fp = fopen(tmpfile, "w"); FILE *fp = fopen(tmpfile, "w");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", tmpfile); printf("Error opening %s\n", tmpfile);
return 1; return 1;
} }
while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { 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; value_max = value_max / 2;
fp = fopen(tmpfile, "r"); fp = fopen(tmpfile, "r");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", tmpfile); printf("Error opening %s\n", tmpfile);
return 1; return 1;
} }
while ((read = getline(&uri, &len, fp)) != -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); snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir);
FILE *fp = fopen(tmpfile, "w"); FILE *fp = fopen(tmpfile, "w");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", tmpfile); printf("Error opening %s\n", tmpfile);
return 1; return 1;
} }
while ((song = mpd_recv_song(mpd.conn)) != NULL) { 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"); fp = fopen(tmpfile, "r");
if (fp == NULL) { if (fp == NULL) {
printf("Error opening %s", tmpfile); printf("Error opening %s\n", tmpfile);
return 1; return 1;
} }
while ((read = getline(&uri, &len, fp)) != -1) { while ((read = getline(&uri, &len, fp)) != -1) {

View File

@ -186,17 +186,11 @@ typedef struct {
t_mympd_state mympd_state; t_mympd_state mympd_state;
struct aline {
char *ptr;
int nalloc;
};
static int is_websocket(const struct mg_connection *nc) { static int is_websocket(const struct mg_connection *nc) {
return nc->flags & MG_F_IS_WEBSOCKET; return nc->flags & MG_F_IS_WEBSOCKET;
} }
int randrange(int n); int randrange(int n);
void save_entry(struct aline *alp, const char *entry);
void mympd_idle(struct mg_mgr *sm, int timeout); void mympd_idle(struct mg_mgr *sm, int timeout);
void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask); void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask);
void callback_mympd(struct mg_connection *nc, const struct mg_str msg); void callback_mympd(struct mg_connection *nc, const struct mg_str msg);

View File

@ -189,8 +189,10 @@ void read_statefiles() {
else else
mympd_state.notificationWeb = false; mympd_state.notificationWeb = false;
} }
else else {
mympd_state.notificationWeb = false; mympd_state.notificationWeb = false;
mympd_state_set("notificationWeb", "false");
}
if (mympd_state_get("notificationPage", value)) { if (mympd_state_get("notificationPage", value)) {
if (strcmp(value, "true") == 0) if (strcmp(value, "true") == 0)
@ -198,24 +200,31 @@ void read_statefiles() {
else else
mympd_state.notificationPage = false; mympd_state.notificationPage = false;
} }
else else {
mympd_state.notificationPage = true; mympd_state.notificationPage = true;
mympd_state_set("notificationPage", "true");
}
if (mympd_state_get("jukeboxMode", value)) if (mympd_state_get("jukeboxMode", value))
mympd_state.jukeboxMode = strtol(value, &crap, 10); mympd_state.jukeboxMode = strtol(value, &crap, 10);
else else {
mympd_state.jukeboxMode = 0; mympd_state.jukeboxMode = 0;
mympd_state_set("jukeboxMode", "0");
}
if (mympd_state_get("jukeboxPlaylist", value)) if (mympd_state_get("jukeboxPlaylist", value))
mympd_state.jukeboxPlaylist = strdup(value); mympd_state.jukeboxPlaylist = strdup(value);
else else {
mympd_state.jukeboxPlaylist = "Database"; mympd_state.jukeboxPlaylist = "Database";
mympd_state_set("jukeboxPlaylist", "Database");
}
if (mympd_state_get("jukeboxQueueLength", value)) if (mympd_state_get("jukeboxQueueLength", value))
mympd_state.jukeboxQueueLength = strtol(value, &crap, 10); mympd_state.jukeboxQueueLength = strtol(value, &crap, 10);
else else {
mympd_state.jukeboxQueueLength = 1; mympd_state.jukeboxQueueLength = 1;
mympd_state_set("jukeboxQueueLength", "1");
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -278,8 +287,6 @@ int main(int argc, char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
read_statefiles();
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0);
@ -342,6 +349,8 @@ int main(int argc, char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
read_statefiles();
if (config.ssl == true) if (config.ssl == true)
mg_set_protocol_http_websocket(nc_http); mg_set_protocol_http_websocket(nc_http);