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:
parent
5c134ee026
commit
cac4e8bfd5
@ -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
37
src/list.c
Normal 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
15
src/list.h
Normal 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);
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
25
src/mympd.c
25
src/mympd.c
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user